Skip to content

Commit

Permalink
Rollup merge of rust-lang#128701 - veera-sivarajan:fix-128604, r=este…
Browse files Browse the repository at this point in the history
…bank

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.
  • Loading branch information
matthiaskrgr authored Sep 2, 2024
2 parents b409db4 + f003e92 commit 31e63ea
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 14 deletions.
40 changes: 26 additions & 14 deletions compiler/rustc_passes/src/loops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,25 @@ use crate::errors::{
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)]
Expand Down Expand Up @@ -90,11 +98,11 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
}

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(
Expand Down Expand Up @@ -128,7 +136,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
&& matches!(
ck_loop.cx_stack.last(),
Some(&Normal)
| Some(&Constant)
| Some(&AnonConst)
| Some(&UnlabeledBlock(_))
| Some(&UnlabeledIfBlock(_))
)
Expand Down Expand Up @@ -175,14 +183,18 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, '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));
}
Expand Down Expand Up @@ -353,7 +365,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
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(),
Expand All @@ -365,7 +377,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
}

fn require_label_in_labeled_block(
&mut self,
&self,
span: Span,
label: &Destination,
cf_type: &str,
Expand All @@ -380,7 +392,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
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(),
Expand Down
25 changes: 25 additions & 0 deletions tests/ui/inline-const/break-inside-inline-const-issue-128604.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
}
Original file line number Diff line number Diff line change
@@ -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 changes: 34 additions & 0 deletions tests/ui/unsafe/break-inside-unsafe-block-issue-128604.rs
Original file line number Diff line number Diff line change
@@ -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;
}
}
}

}
42 changes: 42 additions & 0 deletions tests/ui/unsafe/break-inside-unsafe-block-issue-128604.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 31e63ea

Please sign in to comment.