mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-24 07:44:10 +00:00
Rollup merge of #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 #82329. It closes #84434 as well, due to having the same root cause.
This commit is contained in:
commit
a0dcbdf7fd
@ -1095,8 +1095,8 @@ impl<'a> State<'a> {
|
||||
|
||||
fn print_else(&mut self, els: Option<&hir::Expr<'_>>) {
|
||||
match els {
|
||||
Some(_else) => {
|
||||
match _else.kind {
|
||||
Some(else_) => {
|
||||
match else_.kind {
|
||||
// "another else-if"
|
||||
hir::ExprKind::If(ref i, ref then, ref e) => {
|
||||
self.cbox(INDENT_UNIT - 1);
|
||||
@ -1114,6 +1114,26 @@ impl<'a> State<'a> {
|
||||
self.s.word(" else ");
|
||||
self.print_block(&b)
|
||||
}
|
||||
hir::ExprKind::Match(ref expr, arms, _) => {
|
||||
// else if let desugared to match
|
||||
assert!(arms.len() == 2, "if let desugars to match with two arms");
|
||||
|
||||
self.s.word(" else ");
|
||||
self.s.word("{");
|
||||
|
||||
self.cbox(INDENT_UNIT);
|
||||
self.ibox(INDENT_UNIT);
|
||||
self.word_nbsp("match");
|
||||
self.print_expr_as_cond(&expr);
|
||||
self.s.space();
|
||||
self.bopen();
|
||||
for arm in arms {
|
||||
self.print_arm(arm);
|
||||
}
|
||||
self.bclose(expr.span);
|
||||
|
||||
self.s.word("}");
|
||||
}
|
||||
// BLEAH, constraints would be great here
|
||||
_ => {
|
||||
panic!("print_if saw if with weird alternative");
|
||||
|
9
src/test/ui/match/issue-82392.rs
Normal file
9
src/test/ui/match/issue-82392.rs
Normal file
@ -0,0 +1,9 @@
|
||||
// https://github.com/rust-lang/rust/issues/82329
|
||||
// compile-flags: -Zunpretty=hir,typed
|
||||
// check-pass
|
||||
|
||||
pub fn main() {
|
||||
if true {
|
||||
} else if let Some(a) = Some(3) {
|
||||
}
|
||||
}
|
20
src/test/ui/match/issue-82392.stdout
Normal file
20
src/test/ui/match/issue-82392.stdout
Normal file
@ -0,0 +1,20 @@
|
||||
#[prelude_import]
|
||||
use ::std::prelude::rust_2015::*;
|
||||
#[macro_use]
|
||||
extern crate std;
|
||||
// https://github.com/rust-lang/rust/issues/82329
|
||||
// compile-flags: -Zunpretty=hir,typed
|
||||
// check-pass
|
||||
|
||||
pub fn main() ({
|
||||
(if (true as bool)
|
||||
({ } as
|
||||
()) else {match ((Some as
|
||||
fn(i32) -> Option<i32> {Option::<i32>::Some})((3
|
||||
as
|
||||
i32))
|
||||
as Option<i32>) {
|
||||
Some(a) => { }
|
||||
_ => { }
|
||||
}} as ())
|
||||
} as ())
|
18
src/test/ui/match/issue-84434.rs
Normal file
18
src/test/ui/match/issue-84434.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// https://github.com/rust-lang/rust/issues/84434
|
||||
// check-pass
|
||||
|
||||
use std::path::Path;
|
||||
struct A {
|
||||
pub func: fn(check: bool, a: &Path, b: Option<&Path>),
|
||||
}
|
||||
const MY_A: A = A {
|
||||
func: |check, a, b| {
|
||||
if check {
|
||||
let _ = ();
|
||||
} else if let Some(parent) = b.and_then(|p| p.parent()) {
|
||||
let _ = ();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user