Rollup merge of #128701 - veera-sivarajan:fix-128604, r=estebank
Don't Suggest Labeling `const` and `unsafe` Blocks Fixes #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.
This commit is contained in:
commit
51c686f32b
@ -19,17 +19,25 @@
|
||||
OutsideLoopSuggestion, UnlabeledCfInWhileCondition, UnlabeledInLabeledBlock,
|
||||
};
|
||||
|
||||
/// The context in which a block is encountered.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
enum Context {
|
||||
Normal,
|
||||
Fn,
|
||||
Loop(hir::LoopSource),
|
||||
Closure(Span),
|
||||
Coroutine { coroutine_span: Span, kind: hir::CoroutineDesugaring, source: hir::CoroutineSource },
|
||||
Coroutine {
|
||||
coroutine_span: Span,
|
||||
kind: hir::CoroutineDesugaring,
|
||||
source: hir::CoroutineSource,
|
||||
},
|
||||
UnlabeledBlock(Span),
|
||||
UnlabeledIfBlock(Span),
|
||||
LabeledBlock,
|
||||
Constant,
|
||||
/// E.g. The labeled block inside `['_'; 'block: { break 'block 1 + 2; }]`.
|
||||
AnonConst,
|
||||
/// E.g. `const { ... }`.
|
||||
ConstBlock,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -90,11 +98,11 @@ fn nested_visit_map(&mut self) -> Self::Map {
|
||||
}
|
||||
|
||||
fn visit_anon_const(&mut self, c: &'hir hir::AnonConst) {
|
||||
self.with_context(Constant, |v| intravisit::walk_anon_const(v, c));
|
||||
self.with_context(AnonConst, |v| intravisit::walk_anon_const(v, c));
|
||||
}
|
||||
|
||||
fn visit_inline_const(&mut self, c: &'hir hir::ConstBlock) {
|
||||
self.with_context(Constant, |v| intravisit::walk_inline_const(v, c));
|
||||
self.with_context(ConstBlock, |v| intravisit::walk_inline_const(v, c));
|
||||
}
|
||||
|
||||
fn visit_fn(
|
||||
@ -128,7 +136,7 @@ fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) {
|
||||
&& matches!(
|
||||
ck_loop.cx_stack.last(),
|
||||
Some(&Normal)
|
||||
| Some(&Constant)
|
||||
| Some(&AnonConst)
|
||||
| Some(&UnlabeledBlock(_))
|
||||
| Some(&UnlabeledIfBlock(_))
|
||||
)
|
||||
@ -175,14 +183,18 @@ fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) {
|
||||
hir::ExprKind::Block(ref b, Some(_label)) => {
|
||||
self.with_context(LabeledBlock, |v| v.visit_block(b));
|
||||
}
|
||||
hir::ExprKind::Block(ref b, None) if matches!(self.cx_stack.last(), Some(&Fn)) => {
|
||||
hir::ExprKind::Block(ref b, None)
|
||||
if matches!(self.cx_stack.last(), Some(&Fn) | Some(&ConstBlock)) =>
|
||||
{
|
||||
self.with_context(Normal, |v| v.visit_block(b));
|
||||
}
|
||||
hir::ExprKind::Block(ref b, None)
|
||||
if matches!(
|
||||
self.cx_stack.last(),
|
||||
Some(&Normal) | Some(&Constant) | Some(&UnlabeledBlock(_))
|
||||
) =>
|
||||
hir::ExprKind::Block(
|
||||
ref b @ hir::Block { rules: hir::BlockCheckMode::DefaultBlock, .. },
|
||||
None,
|
||||
) if matches!(
|
||||
self.cx_stack.last(),
|
||||
Some(&Normal) | Some(&AnonConst) | Some(&UnlabeledBlock(_))
|
||||
) =>
|
||||
{
|
||||
self.with_context(UnlabeledBlock(b.span.shrink_to_lo()), |v| v.visit_block(b));
|
||||
}
|
||||
@ -353,7 +365,7 @@ fn require_break_cx(
|
||||
UnlabeledIfBlock(_) if br_cx_kind == BreakContextKind::Break => {
|
||||
self.require_break_cx(br_cx_kind, span, break_span, cx_pos - 1);
|
||||
}
|
||||
Normal | Constant | Fn | UnlabeledBlock(_) | UnlabeledIfBlock(_) => {
|
||||
Normal | AnonConst | Fn | UnlabeledBlock(_) | UnlabeledIfBlock(_) | ConstBlock => {
|
||||
self.sess.dcx().emit_err(OutsideLoop {
|
||||
spans: vec![span],
|
||||
name: &br_cx_kind.to_string(),
|
||||
@ -365,7 +377,7 @@ fn require_break_cx(
|
||||
}
|
||||
|
||||
fn require_label_in_labeled_block(
|
||||
&mut self,
|
||||
&self,
|
||||
span: Span,
|
||||
label: &Destination,
|
||||
cf_type: &str,
|
||||
@ -380,7 +392,7 @@ fn require_label_in_labeled_block(
|
||||
false
|
||||
}
|
||||
|
||||
fn report_outside_loop_error(&mut self) {
|
||||
fn report_outside_loop_error(&self) {
|
||||
for (s, block) in &self.block_breaks {
|
||||
self.sess.dcx().emit_err(OutsideLoop {
|
||||
spans: block.spans.clone(),
|
||||
|
@ -0,0 +1,25 @@
|
||||
fn main() {
|
||||
let _ = ['a'; { break 2; 1 }];
|
||||
//~^ ERROR `break` outside of a loop or labeled block
|
||||
//~| HELP consider labeling this block to be able to break within it
|
||||
|
||||
const {
|
||||
{
|
||||
//~^ HELP consider labeling this block to be able to break within it
|
||||
break;
|
||||
//~^ ERROR `break` outside of a loop or labeled block
|
||||
}
|
||||
};
|
||||
|
||||
const {
|
||||
break;
|
||||
//~^ ERROR `break` outside of a loop or labeled block
|
||||
};
|
||||
|
||||
{
|
||||
const {
|
||||
break;
|
||||
//~^ ERROR `break` outside of a loop or labeled block
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/break-inside-inline-const-issue-128604.rs:15:9
|
||||
|
|
||||
LL | break;
|
||||
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/break-inside-inline-const-issue-128604.rs:21:13
|
||||
|
|
||||
LL | break;
|
||||
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/break-inside-inline-const-issue-128604.rs:2:21
|
||||
|
|
||||
LL | let _ = ['a'; { break 2; 1 }];
|
||||
| ^^^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
|
||||
help: consider labeling this block to be able to break within it
|
||||
|
|
||||
LL | let _ = ['a'; 'block: { break 'block 2; 1 }];
|
||||
| +++++++ ++++++
|
||||
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/break-inside-inline-const-issue-128604.rs:9:13
|
||||
|
|
||||
LL | break;
|
||||
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
|
||||
help: consider labeling this block to be able to break within it
|
||||
|
|
||||
LL ~ 'block: {
|
||||
LL |
|
||||
LL ~ break 'block;
|
||||
|
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0268`.
|
34
tests/ui/unsafe/break-inside-unsafe-block-issue-128604.rs
Normal file
34
tests/ui/unsafe/break-inside-unsafe-block-issue-128604.rs
Normal file
@ -0,0 +1,34 @@
|
||||
fn main() {
|
||||
let a = ["_"; unsafe { break; 1 + 2 }];
|
||||
//~^ ERROR `break` outside of a loop or labeled block
|
||||
|
||||
unsafe {
|
||||
{
|
||||
//~^ HELP consider labeling this block to be able to break within it
|
||||
break;
|
||||
//~^ ERROR `break` outside of a loop or labeled block
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
break;
|
||||
//~^ ERROR `break` outside of a loop or labeled block
|
||||
}
|
||||
|
||||
{
|
||||
//~^ HELP consider labeling this block to be able to break within it
|
||||
unsafe {
|
||||
break;
|
||||
//~^ ERROR `break` outside of a loop or labeled block
|
||||
}
|
||||
}
|
||||
|
||||
while 2 > 1 {
|
||||
unsafe {
|
||||
if true || false {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/break-inside-unsafe-block-issue-128604.rs:2:28
|
||||
|
|
||||
LL | let a = ["_"; unsafe { break; 1 + 2 }];
|
||||
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/break-inside-unsafe-block-issue-128604.rs:14:9
|
||||
|
|
||||
LL | break;
|
||||
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/break-inside-unsafe-block-issue-128604.rs:8:13
|
||||
|
|
||||
LL | break;
|
||||
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
|
||||
help: consider labeling this block to be able to break within it
|
||||
|
|
||||
LL ~ 'block: {
|
||||
LL |
|
||||
LL ~ break 'block;
|
||||
|
|
||||
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/break-inside-unsafe-block-issue-128604.rs:21:13
|
||||
|
|
||||
LL | break;
|
||||
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
|
||||
help: consider labeling this block to be able to break within it
|
||||
|
|
||||
LL ~ 'block: {
|
||||
LL |
|
||||
LL | unsafe {
|
||||
LL ~ break 'block;
|
||||
|
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0268`.
|
Loading…
Reference in New Issue
Block a user