Skip to content

Commit 51c686f

Browse files
authored
Rollup merge of rust-lang#128701 - veera-sivarajan:fix-128604, r=estebank
Don't Suggest Labeling `const` and `unsafe` Blocks Fixes rust-lang#128604 Previously, both anonymous constant blocks (E.g. The labeled block inside `['_'; 'block: { break 'block 1 + 2; }]`) and inline const blocks (E.g. `const { ... }`) were considered to be the same kind of blocks. This caused the compiler to incorrectly suggest labeling both the blocks when only anonymous constant blocks can be labeled. This PR adds an other enum variant to `Context` so that both the blocks can be handled appropriately. Also, adds some doc comments and removes unnecessary `&mut` in a couple of places.
2 parents f75a195 + f003e92 commit 51c686f

5 files changed

+166
-14
lines changed

compiler/rustc_passes/src/loops.rs

+26-14
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,25 @@ use crate::errors::{
1919
OutsideLoopSuggestion, UnlabeledCfInWhileCondition, UnlabeledInLabeledBlock,
2020
};
2121

22+
/// The context in which a block is encountered.
2223
#[derive(Clone, Copy, Debug, PartialEq)]
2324
enum Context {
2425
Normal,
2526
Fn,
2627
Loop(hir::LoopSource),
2728
Closure(Span),
28-
Coroutine { coroutine_span: Span, kind: hir::CoroutineDesugaring, source: hir::CoroutineSource },
29+
Coroutine {
30+
coroutine_span: Span,
31+
kind: hir::CoroutineDesugaring,
32+
source: hir::CoroutineSource,
33+
},
2934
UnlabeledBlock(Span),
3035
UnlabeledIfBlock(Span),
3136
LabeledBlock,
32-
Constant,
37+
/// E.g. The labeled block inside `['_'; 'block: { break 'block 1 + 2; }]`.
38+
AnonConst,
39+
/// E.g. `const { ... }`.
40+
ConstBlock,
3341
}
3442

3543
#[derive(Clone)]
@@ -90,11 +98,11 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
9098
}
9199

92100
fn visit_anon_const(&mut self, c: &'hir hir::AnonConst) {
93-
self.with_context(Constant, |v| intravisit::walk_anon_const(v, c));
101+
self.with_context(AnonConst, |v| intravisit::walk_anon_const(v, c));
94102
}
95103

96104
fn visit_inline_const(&mut self, c: &'hir hir::ConstBlock) {
97-
self.with_context(Constant, |v| intravisit::walk_inline_const(v, c));
105+
self.with_context(ConstBlock, |v| intravisit::walk_inline_const(v, c));
98106
}
99107

100108
fn visit_fn(
@@ -128,7 +136,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
128136
&& matches!(
129137
ck_loop.cx_stack.last(),
130138
Some(&Normal)
131-
| Some(&Constant)
139+
| Some(&AnonConst)
132140
| Some(&UnlabeledBlock(_))
133141
| Some(&UnlabeledIfBlock(_))
134142
)
@@ -175,14 +183,18 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
175183
hir::ExprKind::Block(ref b, Some(_label)) => {
176184
self.with_context(LabeledBlock, |v| v.visit_block(b));
177185
}
178-
hir::ExprKind::Block(ref b, None) if matches!(self.cx_stack.last(), Some(&Fn)) => {
186+
hir::ExprKind::Block(ref b, None)
187+
if matches!(self.cx_stack.last(), Some(&Fn) | Some(&ConstBlock)) =>
188+
{
179189
self.with_context(Normal, |v| v.visit_block(b));
180190
}
181-
hir::ExprKind::Block(ref b, None)
182-
if matches!(
183-
self.cx_stack.last(),
184-
Some(&Normal) | Some(&Constant) | Some(&UnlabeledBlock(_))
185-
) =>
191+
hir::ExprKind::Block(
192+
ref b @ hir::Block { rules: hir::BlockCheckMode::DefaultBlock, .. },
193+
None,
194+
) if matches!(
195+
self.cx_stack.last(),
196+
Some(&Normal) | Some(&AnonConst) | Some(&UnlabeledBlock(_))
197+
) =>
186198
{
187199
self.with_context(UnlabeledBlock(b.span.shrink_to_lo()), |v| v.visit_block(b));
188200
}
@@ -353,7 +365,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
353365
UnlabeledIfBlock(_) if br_cx_kind == BreakContextKind::Break => {
354366
self.require_break_cx(br_cx_kind, span, break_span, cx_pos - 1);
355367
}
356-
Normal | Constant | Fn | UnlabeledBlock(_) | UnlabeledIfBlock(_) => {
368+
Normal | AnonConst | Fn | UnlabeledBlock(_) | UnlabeledIfBlock(_) | ConstBlock => {
357369
self.sess.dcx().emit_err(OutsideLoop {
358370
spans: vec![span],
359371
name: &br_cx_kind.to_string(),
@@ -365,7 +377,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
365377
}
366378

367379
fn require_label_in_labeled_block(
368-
&mut self,
380+
&self,
369381
span: Span,
370382
label: &Destination,
371383
cf_type: &str,
@@ -380,7 +392,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
380392
false
381393
}
382394

383-
fn report_outside_loop_error(&mut self) {
395+
fn report_outside_loop_error(&self) {
384396
for (s, block) in &self.block_breaks {
385397
self.sess.dcx().emit_err(OutsideLoop {
386398
spans: block.spans.clone(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
fn main() {
2+
let _ = ['a'; { break 2; 1 }];
3+
//~^ ERROR `break` outside of a loop or labeled block
4+
//~| HELP consider labeling this block to be able to break within it
5+
6+
const {
7+
{
8+
//~^ HELP consider labeling this block to be able to break within it
9+
break;
10+
//~^ ERROR `break` outside of a loop or labeled block
11+
}
12+
};
13+
14+
const {
15+
break;
16+
//~^ ERROR `break` outside of a loop or labeled block
17+
};
18+
19+
{
20+
const {
21+
break;
22+
//~^ ERROR `break` outside of a loop or labeled block
23+
}
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
error[E0268]: `break` outside of a loop or labeled block
2+
--> $DIR/break-inside-inline-const-issue-128604.rs:15:9
3+
|
4+
LL | break;
5+
| ^^^^^ cannot `break` outside of a loop or labeled block
6+
7+
error[E0268]: `break` outside of a loop or labeled block
8+
--> $DIR/break-inside-inline-const-issue-128604.rs:21:13
9+
|
10+
LL | break;
11+
| ^^^^^ cannot `break` outside of a loop or labeled block
12+
13+
error[E0268]: `break` outside of a loop or labeled block
14+
--> $DIR/break-inside-inline-const-issue-128604.rs:2:21
15+
|
16+
LL | let _ = ['a'; { break 2; 1 }];
17+
| ^^^^^^^ cannot `break` outside of a loop or labeled block
18+
|
19+
help: consider labeling this block to be able to break within it
20+
|
21+
LL | let _ = ['a'; 'block: { break 'block 2; 1 }];
22+
| +++++++ ++++++
23+
24+
error[E0268]: `break` outside of a loop or labeled block
25+
--> $DIR/break-inside-inline-const-issue-128604.rs:9:13
26+
|
27+
LL | break;
28+
| ^^^^^ cannot `break` outside of a loop or labeled block
29+
|
30+
help: consider labeling this block to be able to break within it
31+
|
32+
LL ~ 'block: {
33+
LL |
34+
LL ~ break 'block;
35+
|
36+
37+
error: aborting due to 4 previous errors
38+
39+
For more information about this error, try `rustc --explain E0268`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
fn main() {
2+
let a = ["_"; unsafe { break; 1 + 2 }];
3+
//~^ ERROR `break` outside of a loop or labeled block
4+
5+
unsafe {
6+
{
7+
//~^ HELP consider labeling this block to be able to break within it
8+
break;
9+
//~^ ERROR `break` outside of a loop or labeled block
10+
}
11+
}
12+
13+
unsafe {
14+
break;
15+
//~^ ERROR `break` outside of a loop or labeled block
16+
}
17+
18+
{
19+
//~^ HELP consider labeling this block to be able to break within it
20+
unsafe {
21+
break;
22+
//~^ ERROR `break` outside of a loop or labeled block
23+
}
24+
}
25+
26+
while 2 > 1 {
27+
unsafe {
28+
if true || false {
29+
break;
30+
}
31+
}
32+
}
33+
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
error[E0268]: `break` outside of a loop or labeled block
2+
--> $DIR/break-inside-unsafe-block-issue-128604.rs:2:28
3+
|
4+
LL | let a = ["_"; unsafe { break; 1 + 2 }];
5+
| ^^^^^ cannot `break` outside of a loop or labeled block
6+
7+
error[E0268]: `break` outside of a loop or labeled block
8+
--> $DIR/break-inside-unsafe-block-issue-128604.rs:14:9
9+
|
10+
LL | break;
11+
| ^^^^^ cannot `break` outside of a loop or labeled block
12+
13+
error[E0268]: `break` outside of a loop or labeled block
14+
--> $DIR/break-inside-unsafe-block-issue-128604.rs:8:13
15+
|
16+
LL | break;
17+
| ^^^^^ cannot `break` outside of a loop or labeled block
18+
|
19+
help: consider labeling this block to be able to break within it
20+
|
21+
LL ~ 'block: {
22+
LL |
23+
LL ~ break 'block;
24+
|
25+
26+
error[E0268]: `break` outside of a loop or labeled block
27+
--> $DIR/break-inside-unsafe-block-issue-128604.rs:21:13
28+
|
29+
LL | break;
30+
| ^^^^^ cannot `break` outside of a loop or labeled block
31+
|
32+
help: consider labeling this block to be able to break within it
33+
|
34+
LL ~ 'block: {
35+
LL |
36+
LL | unsafe {
37+
LL ~ break 'block;
38+
|
39+
40+
error: aborting due to 4 previous errors
41+
42+
For more information about this error, try `rustc --explain E0268`.

0 commit comments

Comments
 (0)