about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2021-04-25 23:15:12 +0200
committerGitHub <noreply@github.com>2021-04-25 23:15:12 +0200
commita0dcbdf7fd826bac839fc7c8097f807812cc02a0 (patch)
tree1187ea3811adf2f61839db58b5247af3e886502c /src
parent379a55c64ef72df1c8272ac33ba730244d1395d4 (diff)
parentfc97ce6daed320027a47c1a0ddb86c9242ebde0c (diff)
downloadrust-a0dcbdf7fd826bac839fc7c8097f807812cc02a0.tar.gz
rust-a0dcbdf7fd826bac839fc7c8097f807812cc02a0.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/match/issue-82392.rs9
-rw-r--r--src/test/ui/match/issue-82392.stdout20
-rw-r--r--src/test/ui/match/issue-84434.rs18
3 files changed, 47 insertions, 0 deletions
diff --git a/src/test/ui/match/issue-82392.rs b/src/test/ui/match/issue-82392.rs
new file mode 100644
index 00000000000..d26d883040b
--- /dev/null
+++ b/src/test/ui/match/issue-82392.rs
@@ -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) {
+    }
+}
diff --git a/src/test/ui/match/issue-82392.stdout b/src/test/ui/match/issue-82392.stdout
new file mode 100644
index 00000000000..8ff76c64fc7
--- /dev/null
+++ b/src/test/ui/match/issue-82392.stdout
@@ -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 ())
diff --git a/src/test/ui/match/issue-84434.rs b/src/test/ui/match/issue-84434.rs
new file mode 100644
index 00000000000..423481fd5f0
--- /dev/null
+++ b/src/test/ui/match/issue-84434.rs
@@ -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() {}