Skip to content

Commit 822c24c

Browse files
authored
Rollup merge of rust-lang#84486 - Smittyvb:else-if-let-hir-pretty-print, r=petrochenkov
Handle pretty printing of `else if let` clauses without ICEing When pretty printing the HIR of `if ... {} else if let ... {}` clauses, this displays it the `else if let` part as `match` it gets desugared to, the same way normal `if let` statements are currently displayed, instead of ICEing. ```rust pub fn main() { if true { // 1 } else if let a = 1 { // 2 } else { // 3 } } ``` now gets desugared (via `rustc -Zunpretty=hir,typed src/x.rs`) to: ```rust #[prelude_import] use ::std::prelude::rust_2015::*; #[macro_use] extern crate std; pub fn main() ({ (if (true as bool) ({ // 1 } as ()) else {match (1 as i32) { a => { // 2 } _ => { // 3 } }} as ()) } as ()) ``` For comparison, this code gets HIR prettyprinted the same way before and after this change: ```rust pub fn main() { if let a = 1 { // 2 } else { // 3 } } ``` turns into ```rust #[prelude_import] use ::std::prelude::rust_2015::*; #[macro_use] extern crate std; pub fn main() ({ (match (1 as i32) { a => { // 2 } _ => { // 3 } } as ()) } as ()) ``` This closes rust-lang#82329. It closes rust-lang#84434 as well, due to having the same root cause.
2 parents 8509ccb + fc97ce6 commit 822c24c

File tree

4 files changed

+69
-2
lines changed

4 files changed

+69
-2
lines changed

compiler/rustc_hir_pretty/src/lib.rs

+22-2
Original file line numberDiff line numberDiff line change
@@ -1095,8 +1095,8 @@ impl<'a> State<'a> {
10951095

10961096
fn print_else(&mut self, els: Option<&hir::Expr<'_>>) {
10971097
match els {
1098-
Some(_else) => {
1099-
match _else.kind {
1098+
Some(else_) => {
1099+
match else_.kind {
11001100
// "another else-if"
11011101
hir::ExprKind::If(ref i, ref then, ref e) => {
11021102
self.cbox(INDENT_UNIT - 1);
@@ -1114,6 +1114,26 @@ impl<'a> State<'a> {
11141114
self.s.word(" else ");
11151115
self.print_block(&b)
11161116
}
1117+
hir::ExprKind::Match(ref expr, arms, _) => {
1118+
// else if let desugared to match
1119+
assert!(arms.len() == 2, "if let desugars to match with two arms");
1120+
1121+
self.s.word(" else ");
1122+
self.s.word("{");
1123+
1124+
self.cbox(INDENT_UNIT);
1125+
self.ibox(INDENT_UNIT);
1126+
self.word_nbsp("match");
1127+
self.print_expr_as_cond(&expr);
1128+
self.s.space();
1129+
self.bopen();
1130+
for arm in arms {
1131+
self.print_arm(arm);
1132+
}
1133+
self.bclose(expr.span);
1134+
1135+
self.s.word("}");
1136+
}
11171137
// BLEAH, constraints would be great here
11181138
_ => {
11191139
panic!("print_if saw if with weird alternative");

src/test/ui/match/issue-82392.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// https://github.com/rust-lang/rust/issues/82329
2+
// compile-flags: -Zunpretty=hir,typed
3+
// check-pass
4+
5+
pub fn main() {
6+
if true {
7+
} else if let Some(a) = Some(3) {
8+
}
9+
}

src/test/ui/match/issue-82392.stdout

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#[prelude_import]
2+
use ::std::prelude::rust_2015::*;
3+
#[macro_use]
4+
extern crate std;
5+
// https://github.com/rust-lang/rust/issues/82329
6+
// compile-flags: -Zunpretty=hir,typed
7+
// check-pass
8+
9+
pub fn main() ({
10+
(if (true as bool)
11+
({ } as
12+
()) else {match ((Some as
13+
fn(i32) -> Option<i32> {Option::<i32>::Some})((3
14+
as
15+
i32))
16+
as Option<i32>) {
17+
Some(a) => { }
18+
_ => { }
19+
}} as ())
20+
} as ())

src/test/ui/match/issue-84434.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// https://github.com/rust-lang/rust/issues/84434
2+
// check-pass
3+
4+
use std::path::Path;
5+
struct A {
6+
pub func: fn(check: bool, a: &Path, b: Option<&Path>),
7+
}
8+
const MY_A: A = A {
9+
func: |check, a, b| {
10+
if check {
11+
let _ = ();
12+
} else if let Some(parent) = b.and_then(|p| p.parent()) {
13+
let _ = ();
14+
}
15+
},
16+
};
17+
18+
fn main() {}

0 commit comments

Comments
 (0)