1
Fork 0

Don't Suggest Labeling const and unsafe Blocks

This commit is contained in:
Veera 2024-08-06 14:10:00 -04:00
parent 764675e01a
commit f003e92a5b
5 changed files with 75 additions and 37 deletions

View file

@ -19,17 +19,25 @@ use crate::errors::{
OutsideLoopSuggestion, UnlabeledCfInWhileCondition, UnlabeledInLabeledBlock, OutsideLoopSuggestion, UnlabeledCfInWhileCondition, UnlabeledInLabeledBlock,
}; };
/// The context in which a block is encountered.
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
enum Context { enum Context {
Normal, Normal,
Fn, Fn,
Loop(hir::LoopSource), Loop(hir::LoopSource),
Closure(Span), Closure(Span),
Coroutine { coroutine_span: Span, kind: hir::CoroutineDesugaring, source: hir::CoroutineSource }, Coroutine {
coroutine_span: Span,
kind: hir::CoroutineDesugaring,
source: hir::CoroutineSource,
},
UnlabeledBlock(Span), UnlabeledBlock(Span),
UnlabeledIfBlock(Span), UnlabeledIfBlock(Span),
LabeledBlock, LabeledBlock,
Constant, /// E.g. The labeled block inside `['_'; 'block: { break 'block 1 + 2; }]`.
AnonConst,
/// E.g. `const { ... }`.
ConstBlock,
} }
#[derive(Clone)] #[derive(Clone)]
@ -90,11 +98,11 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
} }
fn visit_anon_const(&mut self, c: &'hir hir::AnonConst) { 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) { 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( fn visit_fn(
@ -128,7 +136,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
&& matches!( && matches!(
ck_loop.cx_stack.last(), ck_loop.cx_stack.last(),
Some(&Normal) Some(&Normal)
| Some(&Constant) | Some(&AnonConst)
| Some(&UnlabeledBlock(_)) | Some(&UnlabeledBlock(_))
| Some(&UnlabeledIfBlock(_)) | Some(&UnlabeledIfBlock(_))
) )
@ -175,13 +183,17 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
hir::ExprKind::Block(ref b, Some(_label)) => { hir::ExprKind::Block(ref b, Some(_label)) => {
self.with_context(LabeledBlock, |v| v.visit_block(b)); 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)); self.with_context(Normal, |v| v.visit_block(b));
} }
hir::ExprKind::Block(ref b, None) hir::ExprKind::Block(
if matches!( ref b @ hir::Block { rules: hir::BlockCheckMode::DefaultBlock, .. },
None,
) if matches!(
self.cx_stack.last(), self.cx_stack.last(),
Some(&Normal) | Some(&Constant) | Some(&UnlabeledBlock(_)) Some(&Normal) | Some(&AnonConst) | Some(&UnlabeledBlock(_))
) => ) =>
{ {
self.with_context(UnlabeledBlock(b.span.shrink_to_lo()), |v| v.visit_block(b)); self.with_context(UnlabeledBlock(b.span.shrink_to_lo()), |v| v.visit_block(b));
@ -353,7 +365,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
UnlabeledIfBlock(_) if br_cx_kind == BreakContextKind::Break => { UnlabeledIfBlock(_) if br_cx_kind == BreakContextKind::Break => {
self.require_break_cx(br_cx_kind, span, break_span, cx_pos - 1); 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 { self.sess.dcx().emit_err(OutsideLoop {
spans: vec![span], spans: vec![span],
name: &br_cx_kind.to_string(), name: &br_cx_kind.to_string(),
@ -365,7 +377,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
} }
fn require_label_in_labeled_block( fn require_label_in_labeled_block(
&mut self, &self,
span: Span, span: Span,
label: &Destination, label: &Destination,
cf_type: &str, cf_type: &str,
@ -380,7 +392,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
false false
} }
fn report_outside_loop_error(&mut self) { fn report_outside_loop_error(&self) {
for (s, block) in &self.block_breaks { for (s, block) in &self.block_breaks {
self.sess.dcx().emit_err(OutsideLoop { self.sess.dcx().emit_err(OutsideLoop {
spans: block.spans.clone(), spans: block.spans.clone(),

View file

@ -15,4 +15,11 @@ fn main() {
break; break;
//~^ ERROR `break` outside of a loop or labeled block //~^ ERROR `break` outside of a loop or labeled block
}; };
{
const {
break;
//~^ ERROR `break` outside of a loop or labeled block
}
}
} }

View file

@ -1,3 +1,15 @@
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 error[E0268]: `break` outside of a loop or labeled block
--> $DIR/break-inside-inline-const-issue-128604.rs:2:21 --> $DIR/break-inside-inline-const-issue-128604.rs:2:21
| |
@ -22,18 +34,6 @@ LL |
LL ~ break 'block; LL ~ break 'block;
| |
error[E0268]: `break` outside of a loop or labeled block error: aborting due to 4 previous errors
--> $DIR/break-inside-inline-const-issue-128604.rs:15:9
|
LL | break;
| ^^^^^ cannot `break` outside of a loop or labeled block
|
help: consider labeling this block to be able to break within it
|
LL ~ const 'block: {
LL ~ break 'block;
|
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0268`. For more information about this error, try `rustc --explain E0268`.

View file

@ -15,4 +15,20 @@ fn main() {
//~^ ERROR `break` outside of a loop or labeled block //~^ 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;
}
}
}
} }

View file

@ -3,11 +3,12 @@ error[E0268]: `break` outside of a loop or labeled block
| |
LL | let a = ["_"; unsafe { break; 1 + 2 }]; LL | let a = ["_"; unsafe { break; 1 + 2 }];
| ^^^^^ cannot `break` outside of a loop or labeled block | ^^^^^ 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
| |
help: consider labeling this block to be able to break within it LL | break;
| | ^^^^^ cannot `break` outside of a loop or labeled block
LL | let a = ["_"; 'block: unsafe { break 'block; 1 + 2 }];
| +++++++ ++++++
error[E0268]: `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 --> $DIR/break-inside-unsafe-block-issue-128604.rs:8:13
@ -23,17 +24,19 @@ LL ~ break 'block;
| |
error[E0268]: `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 --> $DIR/break-inside-unsafe-block-issue-128604.rs:21:13
| |
LL | break; LL | break;
| ^^^^^ cannot `break` outside of a loop or labeled block | ^^^^^ cannot `break` outside of a loop or labeled block
| |
help: consider labeling this block to be able to break within it help: consider labeling this block to be able to break within it
| |
LL ~ 'block: unsafe { LL ~ 'block: {
LL |
LL | unsafe {
LL ~ break 'block; LL ~ break 'block;
| |
error: aborting due to 3 previous errors error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0268`. For more information about this error, try `rustc --explain E0268`.