From 764675e01aa4f32fd5a84e5f3b6a6e1ca8a1d31e Mon Sep 17 00:00:00 2001 From: Veera Date: Tue, 6 Aug 2024 14:06:29 -0400 Subject: [PATCH 1/2] Add Tests --- .../break-inside-inline-const-issue-128604.rs | 18 +++++++++ ...ak-inside-inline-const-issue-128604.stderr | 39 +++++++++++++++++++ .../break-inside-unsafe-block-issue-128604.rs | 18 +++++++++ ...ak-inside-unsafe-block-issue-128604.stderr | 39 +++++++++++++++++++ 4 files changed, 114 insertions(+) create mode 100644 tests/ui/inline-const/break-inside-inline-const-issue-128604.rs create mode 100644 tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr create mode 100644 tests/ui/unsafe/break-inside-unsafe-block-issue-128604.rs create mode 100644 tests/ui/unsafe/break-inside-unsafe-block-issue-128604.stderr diff --git a/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs b/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs new file mode 100644 index 0000000000000..648c9582510e3 --- /dev/null +++ b/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs @@ -0,0 +1,18 @@ +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 + }; +} diff --git a/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr b/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr new file mode 100644 index 0000000000000..c240fab111338 --- /dev/null +++ b/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr @@ -0,0 +1,39 @@ +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[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 + | +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`. diff --git a/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.rs b/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.rs new file mode 100644 index 0000000000000..cbe7a03d38900 --- /dev/null +++ b/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.rs @@ -0,0 +1,18 @@ +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 + } + +} diff --git a/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.stderr b/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.stderr new file mode 100644 index 0000000000000..7acfaf403fb08 --- /dev/null +++ b/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.stderr @@ -0,0 +1,39 @@ +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 + | +help: consider labeling this block to be able to break within it + | +LL | let a = ["_"; 'block: unsafe { break 'block; 1 + 2 }]; + | +++++++ ++++++ + +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:14: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 ~ 'block: unsafe { +LL ~ break 'block; + | + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0268`. From f003e92a5ba73c673f0faeaac01b6eac6ba3f76a Mon Sep 17 00:00:00 2001 From: Veera Date: Tue, 6 Aug 2024 14:10:00 -0400 Subject: [PATCH 2/2] Don't Suggest Labeling `const` and `unsafe` Blocks --- compiler/rustc_passes/src/loops.rs | 40 ++++++++++++------- .../break-inside-inline-const-issue-128604.rs | 7 ++++ ...ak-inside-inline-const-issue-128604.stderr | 26 ++++++------ .../break-inside-unsafe-block-issue-128604.rs | 16 ++++++++ ...ak-inside-unsafe-block-issue-128604.stderr | 23 ++++++----- 5 files changed, 75 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index 25115c5cafd89..c11562ae39e3c 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -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)] @@ -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( @@ -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(_)) ) @@ -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)); } @@ -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(), @@ -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, @@ -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(), diff --git a/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs b/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs index 648c9582510e3..a9795d1569c86 100644 --- a/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs +++ b/tests/ui/inline-const/break-inside-inline-const-issue-128604.rs @@ -15,4 +15,11 @@ fn main() { break; //~^ ERROR `break` outside of a loop or labeled block }; + + { + const { + break; + //~^ ERROR `break` outside of a loop or labeled block + } + } } diff --git a/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr b/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr index c240fab111338..300cd45ad6912 100644 --- a/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr +++ b/tests/ui/inline-const/break-inside-inline-const-issue-128604.stderr @@ -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 --> $DIR/break-inside-inline-const-issue-128604.rs:2:21 | @@ -22,18 +34,6 @@ LL | LL ~ break 'block; | -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 - | -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 +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0268`. diff --git a/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.rs b/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.rs index cbe7a03d38900..a83141f0e4eda 100644 --- a/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.rs +++ b/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.rs @@ -15,4 +15,20 @@ fn main() { //~^ 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; + } + } + } + } diff --git a/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.stderr b/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.stderr index 7acfaf403fb08..b7cbe1a5cf461 100644 --- a/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.stderr +++ b/tests/ui/unsafe/break-inside-unsafe-block-issue-128604.stderr @@ -3,11 +3,12 @@ error[E0268]: `break` outside of a loop or labeled block | 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 | -help: consider labeling this block to be able to break within it - | -LL | let a = ["_"; 'block: unsafe { break 'block; 1 + 2 }]; - | +++++++ ++++++ +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 @@ -23,17 +24,19 @@ LL ~ break '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; - | ^^^^^ cannot `break` outside of a loop or labeled block +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: unsafe { -LL ~ break 'block; +LL ~ 'block: { +LL | +LL | unsafe { +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`.