Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't Suggest Labeling const and unsafe Blocks #128701

Merged
merged 2 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
veera-sivarajan marked this conversation as resolved.
Show resolved Hide resolved

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`.
Loading