about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/feature-gates/feature-gate-loop-match.rs30
-rw-r--r--tests/ui/feature-gates/feature-gate-loop-match.stderr33
-rw-r--r--tests/ui/loop-match/break-to-block.rs23
-rw-r--r--tests/ui/loop-match/const-continue-to-block.rs26
-rw-r--r--tests/ui/loop-match/const-continue-to-block.stderr8
-rw-r--r--tests/ui/loop-match/const-continue-to-loop.rs27
-rw-r--r--tests/ui/loop-match/const-continue-to-loop.stderr8
-rw-r--r--tests/ui/loop-match/const-continue-to-polymorphic-const.rs29
-rw-r--r--tests/ui/loop-match/const-continue-to-polymorphic-const.stderr8
-rw-r--r--tests/ui/loop-match/drop-in-match-arm.rs47
-rw-r--r--tests/ui/loop-match/invalid-attribute.rs43
-rw-r--r--tests/ui/loop-match/invalid-attribute.stderr131
-rw-r--r--tests/ui/loop-match/invalid.rs161
-rw-r--r--tests/ui/loop-match/invalid.stderr91
-rw-r--r--tests/ui/loop-match/loop-match.rs45
-rw-r--r--tests/ui/loop-match/macro.rs48
-rw-r--r--tests/ui/loop-match/nested.rs83
-rw-r--r--tests/ui/loop-match/or-patterns.rs54
-rw-r--r--tests/ui/loop-match/unsupported-type.rs27
-rw-r--r--tests/ui/loop-match/unsupported-type.stderr10
-rw-r--r--tests/ui/loop-match/unwind.rs53
-rw-r--r--tests/ui/loop-match/valid-patterns.rs117
-rw-r--r--tests/ui/thir-print/thir-tree-loop-match.rs22
-rw-r--r--tests/ui/thir-print/thir-tree-loop-match.stdout301
24 files changed, 1425 insertions, 0 deletions
diff --git a/tests/ui/feature-gates/feature-gate-loop-match.rs b/tests/ui/feature-gates/feature-gate-loop-match.rs
new file mode 100644
index 00000000000..399b20234f3
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-loop-match.rs
@@ -0,0 +1,30 @@
+// Test that `#[loop_match]` and `#[const_continue]` cannot be used without
+// `#![feature(loop_match)]`.
+
+enum State {
+    A,
+    B,
+    C,
+}
+
+fn main() {
+    let mut state = State::A;
+    #[loop_match] //~ ERROR the `#[loop_match]` attribute is an experimental feature
+    'a: loop {
+        state = 'blk: {
+            match state {
+                State::A => {
+                    #[const_continue]
+                    //~^ ERROR the `#[const_continue]` attribute is an experimental feature
+                    break 'blk State::B;
+                }
+                State::B => {
+                    #[const_continue]
+                    //~^ ERROR the `#[const_continue]` attribute is an experimental feature
+                    break 'blk State::C;
+                }
+                State::C => break 'a,
+            }
+        };
+    }
+}
diff --git a/tests/ui/feature-gates/feature-gate-loop-match.stderr b/tests/ui/feature-gates/feature-gate-loop-match.stderr
new file mode 100644
index 00000000000..9b12047cf4d
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-loop-match.stderr
@@ -0,0 +1,33 @@
+error[E0658]: the `#[loop_match]` attribute is an experimental feature
+  --> $DIR/feature-gate-loop-match.rs:12:5
+   |
+LL |     #[loop_match]
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #132306 <https://github.com/rust-lang/rust/issues/132306> for more information
+   = help: add `#![feature(loop_match)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: the `#[const_continue]` attribute is an experimental feature
+  --> $DIR/feature-gate-loop-match.rs:17:21
+   |
+LL |                     #[const_continue]
+   |                     ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #132306 <https://github.com/rust-lang/rust/issues/132306> for more information
+   = help: add `#![feature(loop_match)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: the `#[const_continue]` attribute is an experimental feature
+  --> $DIR/feature-gate-loop-match.rs:22:21
+   |
+LL |                     #[const_continue]
+   |                     ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #132306 <https://github.com/rust-lang/rust/issues/132306> for more information
+   = help: add `#![feature(loop_match)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/loop-match/break-to-block.rs b/tests/ui/loop-match/break-to-block.rs
new file mode 100644
index 00000000000..e7451a944c3
--- /dev/null
+++ b/tests/ui/loop-match/break-to-block.rs
@@ -0,0 +1,23 @@
+// Test that a `break` without `#[const_continue]` still works as expected.
+
+//@ run-pass
+
+#![allow(incomplete_features)]
+#![feature(loop_match)]
+
+fn main() {
+    assert_eq!(helper(), 1);
+}
+
+fn helper() -> u8 {
+    let mut state = 0u8;
+    #[loop_match]
+    'a: loop {
+        state = 'blk: {
+            match state {
+                0 => break 'blk 1,
+                _ => break 'a state,
+            }
+        }
+    }
+}
diff --git a/tests/ui/loop-match/const-continue-to-block.rs b/tests/ui/loop-match/const-continue-to-block.rs
new file mode 100644
index 00000000000..fd7ebeefeb6
--- /dev/null
+++ b/tests/ui/loop-match/const-continue-to-block.rs
@@ -0,0 +1,26 @@
+// Test that a `#[const_continue]` that breaks to a normal labeled block (that
+// is not part of a `#[loop_match]`) produces an error.
+
+#![allow(incomplete_features)]
+#![feature(loop_match)]
+#![crate_type = "lib"]
+
+fn const_continue_to_block() -> u8 {
+    let state = 0;
+    #[loop_match]
+    loop {
+        state = 'blk: {
+            match state {
+                0 => {
+                    #[const_continue]
+                    break 'blk 1;
+                }
+                _ => 'b: {
+                    #[const_continue]
+                    break 'b 2;
+                    //~^ ERROR `#[const_continue]` must break to a labeled block that participates in a `#[loop_match]`
+                }
+            }
+        }
+    }
+}
diff --git a/tests/ui/loop-match/const-continue-to-block.stderr b/tests/ui/loop-match/const-continue-to-block.stderr
new file mode 100644
index 00000000000..3a5339a0394
--- /dev/null
+++ b/tests/ui/loop-match/const-continue-to-block.stderr
@@ -0,0 +1,8 @@
+error: `#[const_continue]` must break to a labeled block that participates in a `#[loop_match]`
+  --> $DIR/const-continue-to-block.rs:20:27
+   |
+LL |                     break 'b 2;
+   |                           ^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/loop-match/const-continue-to-loop.rs b/tests/ui/loop-match/const-continue-to-loop.rs
new file mode 100644
index 00000000000..c363e617cfb
--- /dev/null
+++ b/tests/ui/loop-match/const-continue-to-loop.rs
@@ -0,0 +1,27 @@
+// Test that a `#[const_continue]` that breaks to the label of the loop itself
+// rather than to the label of the block within the `#[loop_match]` produces an
+// error.
+
+#![allow(incomplete_features)]
+#![feature(loop_match)]
+#![crate_type = "lib"]
+
+fn const_continue_to_loop() -> u8 {
+    let mut state = 0;
+    #[loop_match]
+    'a: loop {
+        state = 'blk: {
+            match state {
+                0 => {
+                    #[const_continue]
+                    break 'blk 1;
+                }
+                _ => {
+                    #[const_continue]
+                    break 'a 2;
+                    //~^ ERROR `#[const_continue]` must break to a labeled block that participates in a `#[loop_match]`
+                }
+            }
+        }
+    }
+}
diff --git a/tests/ui/loop-match/const-continue-to-loop.stderr b/tests/ui/loop-match/const-continue-to-loop.stderr
new file mode 100644
index 00000000000..a217b3ac72c
--- /dev/null
+++ b/tests/ui/loop-match/const-continue-to-loop.stderr
@@ -0,0 +1,8 @@
+error: `#[const_continue]` must break to a labeled block that participates in a `#[loop_match]`
+  --> $DIR/const-continue-to-loop.rs:21:27
+   |
+LL |                     break 'a 2;
+   |                           ^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/loop-match/const-continue-to-polymorphic-const.rs b/tests/ui/loop-match/const-continue-to-polymorphic-const.rs
new file mode 100644
index 00000000000..9a91c977911
--- /dev/null
+++ b/tests/ui/loop-match/const-continue-to-polymorphic-const.rs
@@ -0,0 +1,29 @@
+// Test that a `#[const_continue]` that breaks on a polymorphic constant produces an error.
+// A polymorphic constant does not have a concrete value at MIR building time, and therefore the
+// `#[loop_match]~ desugaring can't handle such values.
+#![allow(incomplete_features)]
+#![feature(loop_match)]
+#![crate_type = "lib"]
+
+trait Foo {
+    const TARGET: u8;
+
+    fn test_u8(mut state: u8) -> &'static str {
+        #[loop_match]
+        loop {
+            state = 'blk: {
+                match state {
+                    0 => {
+                        #[const_continue]
+                        break 'blk Self::TARGET;
+                        //~^ ERROR could not determine the target branch for this `#[const_continue]`
+                    }
+
+                    1 => return "bar",
+                    2 => return "baz",
+                    _ => unreachable!(),
+                }
+            }
+        }
+    }
+}
diff --git a/tests/ui/loop-match/const-continue-to-polymorphic-const.stderr b/tests/ui/loop-match/const-continue-to-polymorphic-const.stderr
new file mode 100644
index 00000000000..4d183a2fbeb
--- /dev/null
+++ b/tests/ui/loop-match/const-continue-to-polymorphic-const.stderr
@@ -0,0 +1,8 @@
+error: could not determine the target branch for this `#[const_continue]`
+  --> $DIR/const-continue-to-polymorphic-const.rs:18:36
+   |
+LL |                         break 'blk Self::TARGET;
+   |                                    ^^^^^^^^^^^^ this value is too generic
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/loop-match/drop-in-match-arm.rs b/tests/ui/loop-match/drop-in-match-arm.rs
new file mode 100644
index 00000000000..731af659012
--- /dev/null
+++ b/tests/ui/loop-match/drop-in-match-arm.rs
@@ -0,0 +1,47 @@
+// Test that dropping values works in match arms, which is nontrivial
+// because each match arm needs its own scope.
+
+//@ run-pass
+
+#![allow(incomplete_features)]
+#![feature(loop_match)]
+
+use std::sync::atomic::{AtomicBool, Ordering};
+
+fn main() {
+    assert_eq!(helper(), 1);
+    assert!(DROPPED.load(Ordering::Relaxed));
+}
+
+static DROPPED: AtomicBool = AtomicBool::new(false);
+
+struct X;
+
+impl Drop for X {
+    fn drop(&mut self) {
+        DROPPED.store(true, Ordering::Relaxed);
+    }
+}
+
+#[no_mangle]
+#[inline(never)]
+fn helper() -> i32 {
+    let mut state = 0;
+    #[loop_match]
+    'a: loop {
+        state = 'blk: {
+            match state {
+                0 => match X {
+                    _ => {
+                        assert!(!DROPPED.load(Ordering::Relaxed));
+                        break 'blk 1;
+                    }
+                },
+                _ => {
+                    assert!(DROPPED.load(Ordering::Relaxed));
+                    break 'a state;
+                }
+            }
+        };
+    }
+}
diff --git a/tests/ui/loop-match/invalid-attribute.rs b/tests/ui/loop-match/invalid-attribute.rs
new file mode 100644
index 00000000000..d8d2f605eb4
--- /dev/null
+++ b/tests/ui/loop-match/invalid-attribute.rs
@@ -0,0 +1,43 @@
+// Test that the `#[loop_match]` and `#[const_continue]` attributes can only be
+// placed on expressions.
+
+#![allow(incomplete_features)]
+#![feature(loop_match)]
+#![loop_match] //~ ERROR should be applied to a loop
+#![const_continue] //~ ERROR should be applied to a break expression
+
+extern "C" {
+    #[loop_match] //~ ERROR should be applied to a loop
+    #[const_continue] //~ ERROR should be applied to a break expression
+    fn f();
+}
+
+#[loop_match] //~ ERROR should be applied to a loop
+#[const_continue] //~ ERROR should be applied to a break expression
+#[repr(C)]
+struct S {
+    a: u32,
+    b: u32,
+}
+
+trait Invoke {
+    #[loop_match] //~ ERROR should be applied to a loop
+    #[const_continue] //~ ERROR should be applied to a break expression
+    extern "C" fn invoke(&self);
+}
+
+#[loop_match] //~ ERROR should be applied to a loop
+#[const_continue] //~ ERROR should be applied to a break expression
+extern "C" fn ok() {}
+
+fn main() {
+    #[loop_match] //~ ERROR should be applied to a loop
+    #[const_continue] //~ ERROR should be applied to a break expression
+    || {};
+
+    {
+        #[loop_match] //~ ERROR should be applied to a loop
+        #[const_continue] //~ ERROR should be applied to a break expression
+        5
+    };
+}
diff --git a/tests/ui/loop-match/invalid-attribute.stderr b/tests/ui/loop-match/invalid-attribute.stderr
new file mode 100644
index 00000000000..07015311f9c
--- /dev/null
+++ b/tests/ui/loop-match/invalid-attribute.stderr
@@ -0,0 +1,131 @@
+error: `#[const_continue]` should be applied to a break expression
+  --> $DIR/invalid-attribute.rs:16:1
+   |
+LL | #[const_continue]
+   | ^^^^^^^^^^^^^^^^^
+LL | #[repr(C)]
+LL | struct S {
+   | -------- not a break expression
+
+error: `#[loop_match]` should be applied to a loop
+  --> $DIR/invalid-attribute.rs:15:1
+   |
+LL | #[loop_match]
+   | ^^^^^^^^^^^^^
+...
+LL | struct S {
+   | -------- not a loop
+
+error: `#[const_continue]` should be applied to a break expression
+  --> $DIR/invalid-attribute.rs:30:1
+   |
+LL | #[const_continue]
+   | ^^^^^^^^^^^^^^^^^
+LL | extern "C" fn ok() {}
+   | ------------------ not a break expression
+
+error: `#[loop_match]` should be applied to a loop
+  --> $DIR/invalid-attribute.rs:29:1
+   |
+LL | #[loop_match]
+   | ^^^^^^^^^^^^^
+LL | #[const_continue]
+LL | extern "C" fn ok() {}
+   | ------------------ not a loop
+
+error: `#[const_continue]` should be applied to a break expression
+  --> $DIR/invalid-attribute.rs:35:5
+   |
+LL |     #[const_continue]
+   |     ^^^^^^^^^^^^^^^^^
+LL |     || {};
+   |     -- not a break expression
+
+error: `#[loop_match]` should be applied to a loop
+  --> $DIR/invalid-attribute.rs:34:5
+   |
+LL |     #[loop_match]
+   |     ^^^^^^^^^^^^^
+LL |     #[const_continue]
+LL |     || {};
+   |     -- not a loop
+
+error: `#[const_continue]` should be applied to a break expression
+  --> $DIR/invalid-attribute.rs:40:9
+   |
+LL |         #[const_continue]
+   |         ^^^^^^^^^^^^^^^^^
+LL |         5
+   |         - not a break expression
+
+error: `#[loop_match]` should be applied to a loop
+  --> $DIR/invalid-attribute.rs:39:9
+   |
+LL |         #[loop_match]
+   |         ^^^^^^^^^^^^^
+LL |         #[const_continue]
+LL |         5
+   |         - not a loop
+
+error: `#[const_continue]` should be applied to a break expression
+  --> $DIR/invalid-attribute.rs:25:5
+   |
+LL |     #[const_continue]
+   |     ^^^^^^^^^^^^^^^^^
+LL |     extern "C" fn invoke(&self);
+   |     ---------------------------- not a break expression
+
+error: `#[loop_match]` should be applied to a loop
+  --> $DIR/invalid-attribute.rs:24:5
+   |
+LL |     #[loop_match]
+   |     ^^^^^^^^^^^^^
+LL |     #[const_continue]
+LL |     extern "C" fn invoke(&self);
+   |     ---------------------------- not a loop
+
+error: `#[const_continue]` should be applied to a break expression
+  --> $DIR/invalid-attribute.rs:11:5
+   |
+LL |     #[const_continue]
+   |     ^^^^^^^^^^^^^^^^^
+LL |     fn f();
+   |     ------- not a break expression
+
+error: `#[loop_match]` should be applied to a loop
+  --> $DIR/invalid-attribute.rs:10:5
+   |
+LL |     #[loop_match]
+   |     ^^^^^^^^^^^^^
+LL |     #[const_continue]
+LL |     fn f();
+   |     ------- not a loop
+
+error: `#[const_continue]` should be applied to a break expression
+  --> $DIR/invalid-attribute.rs:7:1
+   |
+LL | / #![allow(incomplete_features)]
+LL | | #![feature(loop_match)]
+LL | | #![loop_match]
+LL | | #![const_continue]
+   | | ^^^^^^^^^^^^^^^^^^
+...  |
+LL | |     };
+LL | | }
+   | |_- not a break expression
+
+error: `#[loop_match]` should be applied to a loop
+  --> $DIR/invalid-attribute.rs:6:1
+   |
+LL | / #![allow(incomplete_features)]
+LL | | #![feature(loop_match)]
+LL | | #![loop_match]
+   | | ^^^^^^^^^^^^^^
+LL | | #![const_continue]
+...  |
+LL | |     };
+LL | | }
+   | |_- not a loop
+
+error: aborting due to 14 previous errors
+
diff --git a/tests/ui/loop-match/invalid.rs b/tests/ui/loop-match/invalid.rs
new file mode 100644
index 00000000000..2ddc19f4fc6
--- /dev/null
+++ b/tests/ui/loop-match/invalid.rs
@@ -0,0 +1,161 @@
+// Test that the correct error is emitted when `#[loop_match]` is applied to
+// syntax it does not support.
+#![allow(incomplete_features)]
+#![feature(loop_match)]
+#![crate_type = "lib"]
+
+enum State {
+    A,
+    B,
+    C,
+}
+
+fn invalid_update() {
+    let mut fake = State::A;
+    let state = State::A;
+    #[loop_match]
+    loop {
+        fake = 'blk: {
+            //~^ ERROR invalid update of the `#[loop_match]` state
+            match state {
+                _ => State::B,
+            }
+        }
+    }
+}
+
+fn invalid_scrutinee() {
+    let mut state = State::A;
+    #[loop_match]
+    loop {
+        state = 'blk: {
+            match State::A {
+                //~^ ERROR invalid match on `#[loop_match]` state
+                _ => State::B,
+            }
+        }
+    }
+}
+
+fn bad_statements_1() {
+    let mut state = State::A;
+    #[loop_match]
+    loop {
+        1;
+        //~^ ERROR statements are not allowed in this position within a `#[loop_match]`
+        state = 'blk: {
+            match State::A {
+                _ => State::B,
+            }
+        }
+    }
+}
+
+fn bad_statements_2() {
+    let mut state = State::A;
+    #[loop_match]
+    loop {
+        state = 'blk: {
+            1;
+            //~^ ERROR statements are not allowed in this position within a `#[loop_match]`
+            match State::A {
+                _ => State::B,
+            }
+        }
+    }
+}
+
+fn bad_rhs_1() {
+    let mut state = State::A;
+    #[loop_match]
+    loop {
+        state = State::B
+        //~^ ERROR this expression must be a single `match` wrapped in a labeled block
+    }
+}
+
+fn bad_rhs_2() {
+    let mut state = State::A;
+    #[loop_match]
+    loop {
+        state = 'blk: {
+            State::B
+            //~^ ERROR this expression must be a single `match` wrapped in a labeled block
+        }
+    }
+}
+
+fn bad_rhs_3() {
+    let mut state = ();
+    #[loop_match]
+    loop {
+        state = 'blk: {
+            //~^ ERROR this expression must be a single `match` wrapped in a labeled block
+        }
+    }
+}
+
+fn missing_assignment() {
+    #[loop_match]
+    loop {
+        () //~ ERROR  expected a single assignment expression
+    }
+}
+
+fn empty_loop_body() {
+    #[loop_match]
+    loop {
+        //~^ ERROR  expected a single assignment expression
+    }
+}
+
+fn break_without_value() {
+    let mut state = State::A;
+    #[loop_match]
+    'a: loop {
+        state = 'blk: {
+            match state {
+                State::A => {
+                    #[const_continue]
+                    break 'blk;
+                    //~^ ERROR mismatched types
+                }
+                _ => break 'a,
+            }
+        }
+    }
+}
+
+fn break_without_value_unit() {
+    let mut state = ();
+    #[loop_match]
+    'a: loop {
+        state = 'blk: {
+            match state {
+                () => {
+                    #[const_continue]
+                    break 'blk;
+                    //~^ ERROR a `#[const_continue]` must break to a label with a value
+                }
+            }
+        }
+    }
+}
+
+fn arm_has_guard(cond: bool) {
+    let mut state = State::A;
+    #[loop_match]
+    'a: loop {
+        state = 'blk: {
+            match state {
+                State::A => {
+                    #[const_continue]
+                    break 'blk State::B;
+                }
+                State::B if cond => break 'a,
+                //~^ ERROR match arms that are part of a `#[loop_match]` cannot have guards
+                _ => break 'a,
+            }
+        }
+    }
+}
diff --git a/tests/ui/loop-match/invalid.stderr b/tests/ui/loop-match/invalid.stderr
new file mode 100644
index 00000000000..51fdd024c6f
--- /dev/null
+++ b/tests/ui/loop-match/invalid.stderr
@@ -0,0 +1,91 @@
+error[E0308]: mismatched types
+  --> $DIR/invalid.rs:120:21
+   |
+LL |                     break 'blk;
+   |                     ^^^^^^^^^^ expected `State`, found `()`
+   |
+help: give the `break` a value of the expected type
+   |
+LL |                     break 'blk /* value */;
+   |                                +++++++++++
+
+error: invalid update of the `#[loop_match]` state
+  --> $DIR/invalid.rs:18:9
+   |
+LL |         fake = 'blk: {
+   |         ^^^^
+LL |
+LL |             match state {
+   |                   ----- the assignment must update this variable
+
+error: invalid match on `#[loop_match]` state
+  --> $DIR/invalid.rs:32:19
+   |
+LL |             match State::A {
+   |                   ^^^^^^^^
+   |
+   = note: a local variable must be the scrutinee within a `#[loop_match]`
+
+error: statements are not allowed in this position within a `#[loop_match]`
+  --> $DIR/invalid.rs:44:9
+   |
+LL |         1;
+   |         ^^
+
+error: statements are not allowed in this position within a `#[loop_match]`
+  --> $DIR/invalid.rs:59:13
+   |
+LL |             1;
+   |             ^^
+
+error: this expression must be a single `match` wrapped in a labeled block
+  --> $DIR/invalid.rs:72:17
+   |
+LL |         state = State::B
+   |                 ^^^^^^^^
+
+error: this expression must be a single `match` wrapped in a labeled block
+  --> $DIR/invalid.rs:82:13
+   |
+LL |             State::B
+   |             ^^^^^^^^
+
+error: this expression must be a single `match` wrapped in a labeled block
+  --> $DIR/invalid.rs:92:17
+   |
+LL |           state = 'blk: {
+   |  _________________^
+LL | |
+LL | |         }
+   | |_________^
+
+error: expected a single assignment expression
+  --> $DIR/invalid.rs:101:9
+   |
+LL |         ()
+   |         ^^
+
+error: expected a single assignment expression
+  --> $DIR/invalid.rs:107:10
+   |
+LL |       loop {
+   |  __________^
+LL | |
+LL | |     }
+   | |_____^
+
+error: a `#[const_continue]` must break to a label with a value
+  --> $DIR/invalid.rs:137:21
+   |
+LL |                     break 'blk;
+   |                     ^^^^^^^^^^
+
+error: match arms that are part of a `#[loop_match]` cannot have guards
+  --> $DIR/invalid.rs:155:29
+   |
+LL |                 State::B if cond => break 'a,
+   |                             ^^^^
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/loop-match/loop-match.rs b/tests/ui/loop-match/loop-match.rs
new file mode 100644
index 00000000000..f38bc01f333
--- /dev/null
+++ b/tests/ui/loop-match/loop-match.rs
@@ -0,0 +1,45 @@
+// Test that a basic correct example of `#[loop_match]` with `#[const_continue]`
+// works correctly.
+
+//@ run-pass
+
+#![allow(incomplete_features)]
+#![feature(loop_match)]
+
+enum State {
+    A,
+    B,
+    C,
+}
+
+fn main() {
+    let mut state = State::A;
+    #[loop_match]
+    'a: loop {
+        state = 'blk: {
+            match state {
+                State::A => {
+                    #[const_continue]
+                    break 'blk State::B;
+                }
+                State::B => {
+                    // Without special logic, the compiler believes this is a
+                    // reassignment to an immutable variable because of the
+                    // `loop`. So this tests that local variables work.
+                    let _a = 0;
+
+                    if true {
+                        #[const_continue]
+                        break 'blk State::C;
+                    } else {
+                        #[const_continue]
+                        break 'blk State::A;
+                    }
+                }
+                State::C => break 'a,
+            }
+        };
+    }
+
+    assert!(matches!(state, State::C))
+}
diff --git a/tests/ui/loop-match/macro.rs b/tests/ui/loop-match/macro.rs
new file mode 100644
index 00000000000..98c98b9b627
--- /dev/null
+++ b/tests/ui/loop-match/macro.rs
@@ -0,0 +1,48 @@
+// Test that macros can be defined in the labeled block. This should not trigger an error about
+// statements not being allowed in that position, and should of course work as expected.
+
+//@ run-pass
+
+#![allow(incomplete_features)]
+#![feature(loop_match)]
+
+enum State {
+    A,
+    B,
+    C,
+}
+
+fn main() {
+    let mut state = State::A;
+    #[loop_match]
+    'a: loop {
+        state = 'blk: {
+            macro_rules! const_continue {
+                ($e:expr) => {
+                    #[const_continue]
+                    break 'blk $e;
+                };
+            }
+            match state {
+                State::A => {
+                    const_continue!(State::B);
+                }
+                State::B => {
+                    // Without special logic, the compiler believes this is a
+                    // reassignment to an immutable variable because of the
+                    // `loop`. So this tests that local variables work.
+                    let _a = 0;
+
+                    if true {
+                        const_continue!(State::C);
+                    } else {
+                        const_continue!(State::A);
+                    }
+                }
+                State::C => break 'a,
+            }
+        };
+    }
+
+    assert!(matches!(state, State::C))
+}
diff --git a/tests/ui/loop-match/nested.rs b/tests/ui/loop-match/nested.rs
new file mode 100644
index 00000000000..aaddfae11de
--- /dev/null
+++ b/tests/ui/loop-match/nested.rs
@@ -0,0 +1,83 @@
+// Test that a nested `#[loop_match]` works as expected, and that e.g. a
+// `#[const_continue]` of the inner `#[loop_match]` does not interact with the
+// outer `#[loop_match]`.
+
+//@ run-pass
+
+#![allow(incomplete_features)]
+#![feature(loop_match)]
+
+enum State1 {
+    A,
+    B,
+    C,
+}
+
+enum State2 {
+    X,
+    Y,
+    Z,
+}
+
+fn main() {
+    assert_eq!(run(), concat!("ab", "xyz", "xyz", "c"))
+}
+
+fn run() -> String {
+    let mut accum = String::new();
+
+    let mut state1 = State1::A;
+    let mut state2 = State2::X;
+
+    let mut first = true;
+
+    #[loop_match]
+    'a: loop {
+        state1 = 'blk1: {
+            match state1 {
+                State1::A => {
+                    accum.push('a');
+                    #[const_continue]
+                    break 'blk1 State1::B;
+                }
+                State1::B => {
+                    accum.push('b');
+                    #[loop_match]
+                    loop {
+                        state2 = 'blk2: {
+                            match state2 {
+                                State2::X => {
+                                    accum.push('x');
+                                    #[const_continue]
+                                    break 'blk2 State2::Y;
+                                }
+                                State2::Y => {
+                                    accum.push('y');
+                                    #[const_continue]
+                                    break 'blk2 State2::Z;
+                                }
+                                State2::Z => {
+                                    accum.push('z');
+                                    if first {
+                                        first = false;
+                                        #[const_continue]
+                                        break 'blk2 State2::X;
+                                    } else {
+                                        #[const_continue]
+                                        break 'blk1 State1::C;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                State1::C => {
+                    accum.push('c');
+                    break 'a;
+                }
+            }
+        }
+    }
+
+    accum
+}
diff --git a/tests/ui/loop-match/or-patterns.rs b/tests/ui/loop-match/or-patterns.rs
new file mode 100644
index 00000000000..775243b9c62
--- /dev/null
+++ b/tests/ui/loop-match/or-patterns.rs
@@ -0,0 +1,54 @@
+// Test that `#[loop_match]` supports or-patterns.
+
+//@ run-pass
+
+#![allow(incomplete_features)]
+#![feature(loop_match)]
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+enum State {
+    A,
+    B,
+    C,
+    D,
+}
+
+fn main() {
+    let mut states = vec![];
+    let mut first = true;
+    let mut state = State::A;
+    #[loop_match]
+    'a: loop {
+        state = 'blk: {
+            match state {
+                State::A => {
+                    states.push(state);
+                    if first {
+                        #[const_continue]
+                        break 'blk State::B;
+                    } else {
+                        #[const_continue]
+                        break 'blk State::D;
+                    }
+                }
+                State::B | State::D => {
+                    states.push(state);
+                    if first {
+                        first = false;
+                        #[const_continue]
+                        break 'blk State::A;
+                    } else {
+                        #[const_continue]
+                        break 'blk State::C;
+                    }
+                }
+                State::C => {
+                    states.push(state);
+                    break 'a;
+                }
+            }
+        }
+    }
+
+    assert_eq!(states, [State::A, State::B, State::A, State::D, State::C]);
+}
diff --git a/tests/ui/loop-match/unsupported-type.rs b/tests/ui/loop-match/unsupported-type.rs
new file mode 100644
index 00000000000..9100a1103ab
--- /dev/null
+++ b/tests/ui/loop-match/unsupported-type.rs
@@ -0,0 +1,27 @@
+// Test that the right error is emitted when the `#[loop_match]` state is an
+// unsupported type.
+
+#![allow(incomplete_features)]
+#![feature(loop_match)]
+#![crate_type = "lib"]
+
+fn unsupported_type() {
+    let mut state = Some(false);
+    #[loop_match]
+    'a: loop {
+        state = 'blk: {
+            //~^ ERROR this `#[loop_match]` state value has type `Option<bool>`, which is not supported
+            match state {
+                Some(false) => {
+                    #[const_continue]
+                    break 'blk Some(true);
+                }
+                Some(true) => {
+                    #[const_continue]
+                    break 'blk None;
+                }
+                None => break 'a,
+            }
+        }
+    }
+}
diff --git a/tests/ui/loop-match/unsupported-type.stderr b/tests/ui/loop-match/unsupported-type.stderr
new file mode 100644
index 00000000000..ede3d86796f
--- /dev/null
+++ b/tests/ui/loop-match/unsupported-type.stderr
@@ -0,0 +1,10 @@
+error: this `#[loop_match]` state value has type `Option<bool>`, which is not supported
+  --> $DIR/unsupported-type.rs:12:9
+   |
+LL |         state = 'blk: {
+   |         ^^^^^
+   |
+   = note: only integers, floats, bool, char, and enums without fields are supported
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/loop-match/unwind.rs b/tests/ui/loop-match/unwind.rs
new file mode 100644
index 00000000000..39e2e4537b1
--- /dev/null
+++ b/tests/ui/loop-match/unwind.rs
@@ -0,0 +1,53 @@
+// Test that `#[const_continue]` correctly emits cleanup paths for drops.
+//
+// Here, we first drop `DropBomb`, causing an unwind. Then `ExitOnDrop` should
+// be dropped, causing us to exit with `0` rather than with some non-zero value
+// due to the panic, which is what causes the test to pass.
+
+//@ run-pass
+//@ needs-unwind
+
+#![allow(incomplete_features)]
+#![feature(loop_match)]
+
+enum State {
+    A,
+    B,
+}
+
+struct ExitOnDrop;
+
+impl Drop for ExitOnDrop {
+    fn drop(&mut self) {
+        std::process::exit(0);
+    }
+}
+
+struct DropBomb;
+
+impl Drop for DropBomb {
+    fn drop(&mut self) {
+        panic!("this must unwind");
+    }
+}
+
+fn main() {
+    let mut state = State::A;
+    #[loop_match]
+    'a: loop {
+        state = 'blk: {
+            match state {
+                State::A => {
+                    let _exit = ExitOnDrop;
+                    let _bomb = DropBomb;
+
+                    #[const_continue]
+                    break 'blk State::B;
+                }
+                State::B => break 'a,
+            }
+        };
+    }
+
+    unreachable!();
+}
diff --git a/tests/ui/loop-match/valid-patterns.rs b/tests/ui/loop-match/valid-patterns.rs
new file mode 100644
index 00000000000..4e0e4798a0b
--- /dev/null
+++ b/tests/ui/loop-match/valid-patterns.rs
@@ -0,0 +1,117 @@
+// Test that signed and unsigned integer patterns work with `#[loop_match]`.
+
+//@ run-pass
+
+#![allow(incomplete_features)]
+#![feature(loop_match)]
+
+fn main() {
+    assert_eq!(integer(0), 2);
+    assert_eq!(integer(-1), 2);
+    assert_eq!(integer(2), 2);
+
+    assert_eq!(boolean(true), false);
+    assert_eq!(boolean(false), false);
+
+    assert_eq!(character('a'), 'b');
+    assert_eq!(character('b'), 'b');
+    assert_eq!(character('c'), 'd');
+    assert_eq!(character('d'), 'd');
+
+    assert_eq!(test_f32(1.0), core::f32::consts::PI);
+    assert_eq!(test_f32(2.5), core::f32::consts::PI);
+    assert_eq!(test_f32(4.0), 4.0);
+
+    assert_eq!(test_f64(1.0), core::f64::consts::PI);
+    assert_eq!(test_f64(2.5), core::f64::consts::PI);
+    assert_eq!(test_f64(4.0), 4.0);
+}
+
+fn integer(mut state: i32) -> i32 {
+    #[loop_match]
+    'a: loop {
+        state = 'blk: {
+            match state {
+                -1 => {
+                    #[const_continue]
+                    break 'blk 2;
+                }
+                0 => {
+                    #[const_continue]
+                    break 'blk -1;
+                }
+                2 => break 'a,
+                _ => unreachable!("weird value {:?}", state),
+            }
+        }
+    }
+
+    state
+}
+
+fn boolean(mut state: bool) -> bool {
+    #[loop_match]
+    loop {
+        state = 'blk: {
+            match state {
+                true => {
+                    #[const_continue]
+                    break 'blk false;
+                }
+                false => return state,
+            }
+        }
+    }
+}
+
+fn character(mut state: char) -> char {
+    #[loop_match]
+    loop {
+        state = 'blk: {
+            match state {
+                'a' => {
+                    #[const_continue]
+                    break 'blk 'b';
+                }
+                'b' => return state,
+                'c' => {
+                    #[const_continue]
+                    break 'blk 'd';
+                }
+                _ => return state,
+            }
+        }
+    }
+}
+
+fn test_f32(mut state: f32) -> f32 {
+    #[loop_match]
+    loop {
+        state = 'blk: {
+            match state {
+                1.0 => {
+                    #[const_continue]
+                    break 'blk 2.5;
+                }
+                2.0..3.0 => return core::f32::consts::PI,
+                _ => return state,
+            }
+        }
+    }
+}
+
+fn test_f64(mut state: f64) -> f64 {
+    #[loop_match]
+    loop {
+        state = 'blk: {
+            match state {
+                1.0 => {
+                    #[const_continue]
+                    break 'blk 2.5;
+                }
+                2.0..3.0 => return core::f64::consts::PI,
+                _ => return state,
+            }
+        }
+    }
+}
diff --git a/tests/ui/thir-print/thir-tree-loop-match.rs b/tests/ui/thir-print/thir-tree-loop-match.rs
new file mode 100644
index 00000000000..8c5f2244d54
--- /dev/null
+++ b/tests/ui/thir-print/thir-tree-loop-match.rs
@@ -0,0 +1,22 @@
+//@ check-pass
+//@ compile-flags: -Zunpretty=thir-tree
+
+#![allow(incomplete_features)]
+#![feature(loop_match)]
+
+fn boolean(mut state: bool) -> bool {
+    #[loop_match]
+    loop {
+        state = 'blk: {
+            match state {
+                true => {
+                    #[const_continue]
+                    break 'blk false;
+                }
+                false => return state,
+            }
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/thir-print/thir-tree-loop-match.stdout b/tests/ui/thir-print/thir-tree-loop-match.stdout
new file mode 100644
index 00000000000..828b93da6be
--- /dev/null
+++ b/tests/ui/thir-print/thir-tree-loop-match.stdout
@@ -0,0 +1,301 @@
+DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean):
+params: [
+    Param {
+        ty: bool
+        ty_span: Some($DIR/thir-tree-loop-match.rs:7:23: 7:27 (#0))
+        self_kind: None
+        hir_id: Some(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).1))
+        param: Some( 
+            Pat: {
+                ty: bool
+                span: $DIR/thir-tree-loop-match.rs:7:12: 7:21 (#0)
+                kind: PatKind {
+                    Binding {
+                        name: "state"
+                        mode: BindingMode(No, Mut)
+                        var: LocalVarId(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).2))
+                        ty: bool
+                        is_primary: true
+                        subpattern: None
+                    }
+                }
+            }
+        )
+    }
+]
+body:
+    Expr {
+        ty: bool
+        temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None }
+        span: $DIR/thir-tree-loop-match.rs:7:37: 20:2 (#0)
+        kind: 
+            Scope {
+                region_scope: Node(28)
+                lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).28))
+                value:
+                    Expr {
+                        ty: bool
+                        temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None }
+                        span: $DIR/thir-tree-loop-match.rs:7:37: 20:2 (#0)
+                        kind: 
+                            Block {
+                                targeted_by_break: false
+                                span: $DIR/thir-tree-loop-match.rs:7:37: 20:2 (#0)
+                                region_scope: Node(3)
+                                safety_mode: Safe
+                                stmts: []
+                                expr:
+                                    Expr {
+                                        ty: bool
+                                        temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None }
+                                        span: $DIR/thir-tree-loop-match.rs:9:5: 19:6 (#0)
+                                        kind: 
+                                            Scope {
+                                                region_scope: Node(4)
+                                                lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).4))
+                                                value:
+                                                    Expr {
+                                                        ty: bool
+                                                        temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None }
+                                                        span: $DIR/thir-tree-loop-match.rs:9:5: 19:6 (#0)
+                                                        kind: 
+                                                            NeverToAny {
+                                                                source:
+                                                                    Expr {
+                                                                        ty: !
+                                                                        temp_lifetime: TempLifetime { temp_lifetime: Some(Node(28)), backwards_incompatible: None }
+                                                                        span: $DIR/thir-tree-loop-match.rs:9:5: 19:6 (#0)
+                                                                        kind: 
+                                                                            LoopMatch {
+                                                                                state:
+                                                                                    Expr {
+                                                                                        ty: bool
+                                                                                        temp_lifetime: TempLifetime { temp_lifetime: Some(Node(5)), backwards_incompatible: None }
+                                                                                        span: $DIR/thir-tree-loop-match.rs:10:9: 10:14 (#0)
+                                                                                        kind: 
+                                                                                            Scope {
+                                                                                                region_scope: Node(7)
+                                                                                                lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).7))
+                                                                                                value:
+                                                                                                    Expr {
+                                                                                                        ty: bool
+                                                                                                        temp_lifetime: TempLifetime { temp_lifetime: Some(Node(5)), backwards_incompatible: None }
+                                                                                                        span: $DIR/thir-tree-loop-match.rs:10:9: 10:14 (#0)
+                                                                                                        kind: 
+                                                                                                            VarRef {
+                                                                                                                id: LocalVarId(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).2))
+                                                                                                            }
+                                                                                                    }
+                                                                                            }
+                                                                                    }
+                                                                                region_scope: Node(10)
+                                                                                match_span: $DIR/thir-tree-loop-match.rs:11:13: 17:14 (#0)
+                                                                                arms: [
+                                                                                    Arm {
+                                                                                        pattern: 
+                                                                                            Pat: {
+                                                                                                ty: bool
+                                                                                                span: $DIR/thir-tree-loop-match.rs:12:17: 12:21 (#0)
+                                                                                                kind: PatKind {
+                                                                                                    Constant {
+                                                                                                        value: Ty(bool, true)
+                                                                                                    }
+                                                                                                }
+                                                                                            }
+                                                                                        guard: None
+                                                                                        body: 
+                                                                                            Expr {
+                                                                                                ty: bool
+                                                                                                temp_lifetime: TempLifetime { temp_lifetime: Some(Node(16)), backwards_incompatible: None }
+                                                                                                span: $DIR/thir-tree-loop-match.rs:12:25: 15:18 (#0)
+                                                                                                kind: 
+                                                                                                    Scope {
+                                                                                                        region_scope: Node(17)
+                                                                                                        lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).17))
+                                                                                                        value:
+                                                                                                            Expr {
+                                                                                                                ty: bool
+                                                                                                                temp_lifetime: TempLifetime { temp_lifetime: Some(Node(16)), backwards_incompatible: None }
+                                                                                                                span: $DIR/thir-tree-loop-match.rs:12:25: 15:18 (#0)
+                                                                                                                kind: 
+                                                                                                                    NeverToAny {
+                                                                                                                        source:
+                                                                                                                            Expr {
+                                                                                                                                ty: !
+                                                                                                                                temp_lifetime: TempLifetime { temp_lifetime: Some(Node(16)), backwards_incompatible: None }
+                                                                                                                                span: $DIR/thir-tree-loop-match.rs:12:25: 15:18 (#0)
+                                                                                                                                kind: 
+                                                                                                                                    Block {
+                                                                                                                                        targeted_by_break: false
+                                                                                                                                        span: $DIR/thir-tree-loop-match.rs:12:25: 15:18 (#0)
+                                                                                                                                        region_scope: Node(18)
+                                                                                                                                        safety_mode: Safe
+                                                                                                                                        stmts: [
+                                                                                                                                            Stmt {
+                                                                                                                                                kind: Expr {
+                                                                                                                                                    scope: Node(21)
+                                                                                                                                                    expr:
+                                                                                                                                                        Expr {
+                                                                                                                                                            ty: !
+                                                                                                                                                            temp_lifetime: TempLifetime { temp_lifetime: Some(Node(21)), backwards_incompatible: None }
+                                                                                                                                                            span: $DIR/thir-tree-loop-match.rs:14:21: 14:37 (#0)
+                                                                                                                                                            kind: 
+                                                                                                                                                                Scope {
+                                                                                                                                                                    region_scope: Node(19)
+                                                                                                                                                                    lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).19))
+                                                                                                                                                                    value:
+                                                                                                                                                                        Expr {
+                                                                                                                                                                            ty: !
+                                                                                                                                                                            temp_lifetime: TempLifetime { temp_lifetime: Some(Node(21)), backwards_incompatible: None }
+                                                                                                                                                                            span: $DIR/thir-tree-loop-match.rs:14:21: 14:37 (#0)
+                                                                                                                                                                            kind: 
+                                                                                                                                                                                ConstContinue (
+                                                                                                                                                                                    label: Node(10)
+                                                                                                                                                                                    value:
+                                                                                                                                                                                        Expr {
+                                                                                                                                                                                            ty: bool
+                                                                                                                                                                                            temp_lifetime: TempLifetime { temp_lifetime: Some(Node(21)), backwards_incompatible: None }
+                                                                                                                                                                                            span: $DIR/thir-tree-loop-match.rs:14:32: 14:37 (#0)
+                                                                                                                                                                                            kind: 
+                                                                                                                                                                                                Scope {
+                                                                                                                                                                                                    region_scope: Node(20)
+                                                                                                                                                                                                    lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).20))
+                                                                                                                                                                                                    value:
+                                                                                                                                                                                                        Expr {
+                                                                                                                                                                                                            ty: bool
+                                                                                                                                                                                                            temp_lifetime: TempLifetime { temp_lifetime: Some(Node(21)), backwards_incompatible: None }
+                                                                                                                                                                                                            span: $DIR/thir-tree-loop-match.rs:14:32: 14:37 (#0)
+                                                                                                                                                                                                            kind: 
+                                                                                                                                                                                                                Literal( lit: Spanned { node: Bool(false), span: $DIR/thir-tree-loop-match.rs:14:32: 14:37 (#0) }, neg: false)
+
+                                                                                                                                                                                                        }
+                                                                                                                                                                                                }
+                                                                                                                                                                                        }
+                                                                                                                                                                                )
+                                                                                                                                                                        }
+                                                                                                                                                                }
+                                                                                                                                                        }
+                                                                                                                                                }
+                                                                                                                                            }
+                                                                                                                                        ]
+                                                                                                                                        expr: []
+                                                                                                                                    }
+                                                                                                                            }
+                                                                                                                    }
+                                                                                                            }
+                                                                                                    }
+                                                                                            }
+                                                                                        lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).16))
+                                                                                        scope: Node(16)
+                                                                                        span: $DIR/thir-tree-loop-match.rs:12:17: 15:18 (#0)
+                                                                                    }
+                                                                                    Arm {
+                                                                                        pattern: 
+                                                                                            Pat: {
+                                                                                                ty: bool
+                                                                                                span: $DIR/thir-tree-loop-match.rs:16:17: 16:22 (#0)
+                                                                                                kind: PatKind {
+                                                                                                    Constant {
+                                                                                                        value: Ty(bool, false)
+                                                                                                    }
+                                                                                                }
+                                                                                            }
+                                                                                        guard: None
+                                                                                        body: 
+                                                                                            Expr {
+                                                                                                ty: bool
+                                                                                                temp_lifetime: TempLifetime { temp_lifetime: Some(Node(24)), backwards_incompatible: None }
+                                                                                                span: $DIR/thir-tree-loop-match.rs:16:26: 16:38 (#0)
+                                                                                                kind: 
+                                                                                                    Scope {
+                                                                                                        region_scope: Node(25)
+                                                                                                        lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).25))
+                                                                                                        value:
+                                                                                                            Expr {
+                                                                                                                ty: bool
+                                                                                                                temp_lifetime: TempLifetime { temp_lifetime: Some(Node(24)), backwards_incompatible: None }
+                                                                                                                span: $DIR/thir-tree-loop-match.rs:16:26: 16:38 (#0)
+                                                                                                                kind: 
+                                                                                                                    NeverToAny {
+                                                                                                                        source:
+                                                                                                                            Expr {
+                                                                                                                                ty: !
+                                                                                                                                temp_lifetime: TempLifetime { temp_lifetime: Some(Node(24)), backwards_incompatible: None }
+                                                                                                                                span: $DIR/thir-tree-loop-match.rs:16:26: 16:38 (#0)
+                                                                                                                                kind: 
+                                                                                                                                    Return {
+                                                                                                                                        value:
+                                                                                                                                            Expr {
+                                                                                                                                                ty: bool
+                                                                                                                                                temp_lifetime: TempLifetime { temp_lifetime: Some(Node(24)), backwards_incompatible: None }
+                                                                                                                                                span: $DIR/thir-tree-loop-match.rs:16:33: 16:38 (#0)
+                                                                                                                                                kind: 
+                                                                                                                                                    Scope {
+                                                                                                                                                        region_scope: Node(26)
+                                                                                                                                                        lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).26))
+                                                                                                                                                        value:
+                                                                                                                                                            Expr {
+                                                                                                                                                                ty: bool
+                                                                                                                                                                temp_lifetime: TempLifetime { temp_lifetime: Some(Node(24)), backwards_incompatible: None }
+                                                                                                                                                                span: $DIR/thir-tree-loop-match.rs:16:33: 16:38 (#0)
+                                                                                                                                                                kind: 
+                                                                                                                                                                    VarRef {
+                                                                                                                                                                        id: LocalVarId(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).2))
+                                                                                                                                                                    }
+                                                                                                                                                            }
+                                                                                                                                                    }
+                                                                                                                                            }
+                                                                                                                                    }
+                                                                                                                            }
+                                                                                                                    }
+                                                                                                            }
+                                                                                                    }
+                                                                                            }
+                                                                                        lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).24))
+                                                                                        scope: Node(24)
+                                                                                        span: $DIR/thir-tree-loop-match.rs:16:17: 16:38 (#0)
+                                                                                    }
+                                                                                ]
+                                                                            }
+                                                                    }
+                                                            }
+                                                    }
+                                            }
+                                    }
+                            }
+                    }
+            }
+    }
+
+
+DefId(0:4 ~ thir_tree_loop_match[3c53]::main):
+params: [
+]
+body:
+    Expr {
+        ty: ()
+        temp_lifetime: TempLifetime { temp_lifetime: Some(Node(2)), backwards_incompatible: None }
+        span: $DIR/thir-tree-loop-match.rs:22:11: 22:13 (#0)
+        kind: 
+            Scope {
+                region_scope: Node(2)
+                lint_level: Explicit(HirId(DefId(0:4 ~ thir_tree_loop_match[3c53]::main).2))
+                value:
+                    Expr {
+                        ty: ()
+                        temp_lifetime: TempLifetime { temp_lifetime: Some(Node(2)), backwards_incompatible: None }
+                        span: $DIR/thir-tree-loop-match.rs:22:11: 22:13 (#0)
+                        kind: 
+                            Block {
+                                targeted_by_break: false
+                                span: $DIR/thir-tree-loop-match.rs:22:11: 22:13 (#0)
+                                region_scope: Node(1)
+                                safety_mode: Safe
+                                stmts: []
+                                expr: []
+                            }
+                    }
+            }
+    }
+
+