File tree Expand file tree Collapse file tree 3 files changed +57
-4
lines changed
rustc_mir_build/src/thir/cx Expand file tree Collapse file tree 3 files changed +57
-4
lines changed Original file line number Diff line number Diff line change @@ -895,9 +895,12 @@ impl<'tcx> ThirBuildCx<'tcx> {
895
895
dcx. emit_fatal ( LoopMatchBadRhs { span : rhs_expr. span } )
896
896
} ;
897
897
898
- if let Some ( first) = block_body. stmts . first ( ) {
899
- let span = first. span . to ( block_body. stmts . last ( ) . unwrap ( ) . span ) ;
900
- dcx. emit_fatal ( LoopMatchBadStatements { span } )
898
+ // The labeled block should contain one match expression, but defining items is
899
+ // allowed.
900
+ for stmt in block_body. stmts {
901
+ if !matches ! ( stmt. kind, rustc_hir:: StmtKind :: Item ( _) ) {
902
+ dcx. emit_fatal ( LoopMatchBadStatements { span : stmt. span } )
903
+ }
901
904
}
902
905
903
906
let Some ( block_body_expr) = block_body. expr else {
Original file line number Diff line number Diff line change @@ -233,7 +233,9 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
233
233
if attrs. iter ( ) . any ( |attr| attr. has_name ( sym:: const_continue) ) {
234
234
if let Some ( break_label) = break_label. label {
235
235
let is_target_label = |cx : & Context | match cx {
236
- Context :: LoopMatch { labeled_block } => break_label == * labeled_block,
236
+ Context :: LoopMatch { labeled_block } => {
237
+ break_label. ident . name == labeled_block. ident . name
238
+ }
237
239
_ => false ,
238
240
} ;
239
241
Original file line number Diff line number Diff line change
1
+ // Test that macros can be defined in the labeled block. This should not trigger an error about
2
+ // statements not being allowed in that position, and should of course work as expected.
3
+
4
+ //@ run-pass
5
+
6
+ #![ allow( incomplete_features) ]
7
+ #![ feature( loop_match) ]
8
+
9
+ enum State {
10
+ A ,
11
+ B ,
12
+ C ,
13
+ }
14
+
15
+ fn main ( ) {
16
+ let mut state = State :: A ;
17
+ #[ loop_match]
18
+ ' a: loop {
19
+ state = ' blk: {
20
+ macro_rules! const_continue {
21
+ ( $e: expr) => {
22
+ #[ const_continue]
23
+ break ' blk $e;
24
+ } ;
25
+ }
26
+ match state {
27
+ State :: A => {
28
+ const_continue ! ( State :: B ) ;
29
+ }
30
+ State :: B => {
31
+ // Without special logic, the compiler believes this is a
32
+ // reassignment to an immutable variable because of the
33
+ // `loop`. So this tests that local variables work.
34
+ let _a = 0 ;
35
+
36
+ if true {
37
+ const_continue ! ( State :: C ) ;
38
+ } else {
39
+ const_continue ! ( State :: A ) ;
40
+ }
41
+ }
42
+ State :: C => break ' a,
43
+ }
44
+ } ;
45
+ }
46
+
47
+ assert ! ( matches!( state, State :: C ) )
48
+ }
You can’t perform that action at this time.
0 commit comments