From daac0114591777f29e2f6396e8c2bd5d2c506788 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Tue, 3 Oct 2023 00:20:59 +0000 Subject: Suggest labeling block if `break` is in bare block Fix #103982. --- compiler/rustc_passes/messages.ftl | 2 + compiler/rustc_passes/src/errors.rs | 10 +++++ compiler/rustc_passes/src/loops.rs | 55 +++++++++++++++++++++---- tests/ui/parser/break-in-unlabeled-block.fixed | 12 ++++++ tests/ui/parser/break-in-unlabeled-block.rs | 11 +++++ tests/ui/parser/break-in-unlabeled-block.stderr | 27 ++++++++++++ 6 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 tests/ui/parser/break-in-unlabeled-block.fixed create mode 100644 tests/ui/parser/break-in-unlabeled-block.rs create mode 100644 tests/ui/parser/break-in-unlabeled-block.stderr diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 214c6d70960..25ef5245cf1 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -580,6 +580,8 @@ passes_outside_loop = *[false] {""} } +passes_outside_loop_suggestion = consider labeling this block to be able to break within it + passes_params_not_allowed = referencing function parameters is not allowed in naked functions .help = follow the calling convention in asm block to use parameters diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index bcf5abbfe7d..4b27b6d8c36 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1099,6 +1099,16 @@ pub struct OutsideLoop<'a> { pub span: Span, pub name: &'a str, pub is_break: bool, + #[subdiagnostic] + pub suggestion: Option, +} +#[derive(Subdiagnostic)] +#[multipart_suggestion(passes_outside_loop_suggestion, applicability = "maybe-incorrect")] +pub struct OutsideLoopSuggestion { + #[suggestion_part(code = "'block: ")] + pub block_span: Span, + #[suggestion_part(code = " 'block")] + pub break_span: Span, } #[derive(Diagnostic)] diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index 0aaf85086e4..10763556c7c 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -1,7 +1,7 @@ use Context::*; use rustc_hir as hir; -use rustc_hir::def_id::LocalModDefId; +use rustc_hir::def_id::{LocalDefId, LocalModDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Destination, Movability, Node}; use rustc_middle::hir::map::Map; @@ -10,19 +10,21 @@ use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::hygiene::DesugaringKind; -use rustc_span::Span; +use rustc_span::{BytePos, Span}; use crate::errors::{ BreakInsideAsyncBlock, BreakInsideClosure, BreakNonLoop, ContinueLabeledBlock, OutsideLoop, - UnlabeledCfInWhileCondition, UnlabeledInLabeledBlock, + OutsideLoopSuggestion, UnlabeledCfInWhileCondition, UnlabeledInLabeledBlock, }; #[derive(Clone, Copy, Debug, PartialEq)] enum Context { Normal, + Fn, Loop(hir::LoopSource), Closure(Span), AsyncClosure(Span), + UnlabeledBlock(Span), LabeledBlock, Constant, } @@ -60,6 +62,25 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { self.with_context(Constant, |v| intravisit::walk_inline_const(v, c)); } + fn visit_fn( + &mut self, + fk: hir::intravisit::FnKind<'hir>, + fd: &'hir hir::FnDecl<'hir>, + b: hir::BodyId, + _: Span, + id: LocalDefId, + ) { + self.with_context(Fn, |v| intravisit::walk_fn(v, fk, fd, b, id)); + } + + fn visit_trait_item(&mut self, trait_item: &'hir hir::TraitItem<'hir>) { + self.with_context(Fn, |v| intravisit::walk_trait_item(v, trait_item)); + } + + fn visit_impl_item(&mut self, impl_item: &'hir hir::ImplItem<'hir>) { + self.with_context(Fn, |v| intravisit::walk_impl_item(v, impl_item)); + } + fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) { match e.kind { hir::ExprKind::Loop(ref b, _, source, _) => { @@ -83,6 +104,14 @@ 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, Fn) => { + self.with_context(Normal, |v| v.visit_block(&b)); + } + hir::ExprKind::Block(ref b, None) + if matches!(self.cx, Normal | Constant | UnlabeledBlock(_)) => + { + self.with_context(UnlabeledBlock(b.span.shrink_to_lo()), |v| v.visit_block(&b)); + } hir::ExprKind::Break(break_label, ref opt_expr) => { if let Some(e) = opt_expr { self.visit_expr(e); @@ -147,7 +176,12 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { } } - self.require_break_cx("break", e.span); + let sp_lo = e.span.with_lo(e.span.lo() + BytePos("break".len() as u32)); + let label_sp = match break_label.label { + Some(label) => sp_lo.with_hi(label.ident.span.hi()), + None => sp_lo.shrink_to_lo(), + }; + self.require_break_cx("break", e.span, label_sp); } hir::ExprKind::Continue(destination) => { self.require_label_in_labeled_block(e.span, &destination, "continue"); @@ -169,7 +203,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { } Err(_) => {} } - self.require_break_cx("continue", e.span) + self.require_break_cx("continue", e.span, e.span) } _ => intravisit::walk_expr(self, e), } @@ -187,7 +221,8 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> { self.cx = old_cx; } - fn require_break_cx(&self, name: &str, span: Span) { + fn require_break_cx(&self, name: &str, span: Span, break_span: Span) { + let is_break = name == "break"; match self.cx { LabeledBlock | Loop(_) => {} Closure(closure_span) => { @@ -196,8 +231,12 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> { AsyncClosure(closure_span) => { self.sess.emit_err(BreakInsideAsyncBlock { span, closure_span, name }); } - Normal | Constant => { - self.sess.emit_err(OutsideLoop { span, name, is_break: name == "break" }); + UnlabeledBlock(block_span) if is_break => { + let suggestion = Some(OutsideLoopSuggestion { block_span, break_span }); + self.sess.emit_err(OutsideLoop { span, name, is_break, suggestion }); + } + Normal | Constant | Fn | UnlabeledBlock(_) => { + self.sess.emit_err(OutsideLoop { span, name, is_break, suggestion: None }); } } } diff --git a/tests/ui/parser/break-in-unlabeled-block.fixed b/tests/ui/parser/break-in-unlabeled-block.fixed new file mode 100644 index 00000000000..0e496430ae6 --- /dev/null +++ b/tests/ui/parser/break-in-unlabeled-block.fixed @@ -0,0 +1,12 @@ +// run-rustfix +fn main() { + 'block: { + break 'block (); //~ ERROR `break` outside of a loop or labeled block + } + { + 'block: { + break 'block (); //~ ERROR `break` outside of a loop or labeled block + } + } +} + diff --git a/tests/ui/parser/break-in-unlabeled-block.rs b/tests/ui/parser/break-in-unlabeled-block.rs new file mode 100644 index 00000000000..3e5587e9f9c --- /dev/null +++ b/tests/ui/parser/break-in-unlabeled-block.rs @@ -0,0 +1,11 @@ +// run-rustfix +fn main() { + { + break (); //~ ERROR `break` outside of a loop or labeled block + } + { + { + break (); //~ ERROR `break` outside of a loop or labeled block + } + } +} diff --git a/tests/ui/parser/break-in-unlabeled-block.stderr b/tests/ui/parser/break-in-unlabeled-block.stderr new file mode 100644 index 00000000000..632cca80d8c --- /dev/null +++ b/tests/ui/parser/break-in-unlabeled-block.stderr @@ -0,0 +1,27 @@ +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-in-unlabeled-block.rs:4: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: { +LL ~ break 'block (); + | + +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-in-unlabeled-block.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 ~ break 'block (); + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0268`. -- cgit 1.4.1-3-g733a5 From 5c17b8be61b69be6c38619f829ba81c64212110d Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Tue, 3 Oct 2023 21:34:52 +0000 Subject: Move some tests around --- tests/ui/parser/attr-bad-meta-2.rs | 2 - tests/ui/parser/attr-bad-meta-2.stderr | 8 - tests/ui/parser/attr-bad-meta-3.rs | 2 - tests/ui/parser/attr-bad-meta-3.stderr | 8 - tests/ui/parser/attr-bad-meta.rs | 2 - tests/ui/parser/attr-bad-meta.stderr | 8 - tests/ui/parser/attr-before-eof.rs | 3 - tests/ui/parser/attr-before-eof.stderr | 8 - tests/ui/parser/attr-dangling-in-fn.rs | 8 - tests/ui/parser/attr-dangling-in-fn.stderr | 8 - tests/ui/parser/attr-dangling-in-mod.rs | 6 - tests/ui/parser/attr-dangling-in-mod.stderr | 8 - tests/ui/parser/attr-stmt-expr-attr-bad.rs | 108 ----- tests/ui/parser/attr-stmt-expr-attr-bad.stderr | 446 --------------------- tests/ui/parser/attr-with-a-semicolon.rs | 4 - tests/ui/parser/attr-with-a-semicolon.stderr | 14 - tests/ui/parser/attr.rs | 6 - tests/ui/parser/attr.stderr | 17 - ...attribute-with-no-generics-in-parameter-list.rs | 3 - ...ibute-with-no-generics-in-parameter-list.stderr | 8 - tests/ui/parser/attribute/attr-bad-meta-2.rs | 2 + tests/ui/parser/attribute/attr-bad-meta-2.stderr | 8 + tests/ui/parser/attribute/attr-bad-meta-3.rs | 2 + tests/ui/parser/attribute/attr-bad-meta-3.stderr | 8 + tests/ui/parser/attribute/attr-bad-meta.rs | 2 + tests/ui/parser/attribute/attr-bad-meta.stderr | 8 + tests/ui/parser/attribute/attr-before-eof.rs | 3 + tests/ui/parser/attribute/attr-before-eof.stderr | 8 + tests/ui/parser/attribute/attr-dangling-in-fn.rs | 8 + .../ui/parser/attribute/attr-dangling-in-fn.stderr | 8 + tests/ui/parser/attribute/attr-dangling-in-mod.rs | 6 + .../parser/attribute/attr-dangling-in-mod.stderr | 8 + .../ui/parser/attribute/attr-stmt-expr-attr-bad.rs | 108 +++++ .../attribute/attr-stmt-expr-attr-bad.stderr | 446 +++++++++++++++++++++ tests/ui/parser/attribute/attr-with-a-semicolon.rs | 4 + .../parser/attribute/attr-with-a-semicolon.stderr | 14 + tests/ui/parser/attribute/attr.rs | 6 + tests/ui/parser/attribute/attr.stderr | 17 + ...attribute-with-no-generics-in-parameter-list.rs | 3 + ...ibute-with-no-generics-in-parameter-list.stderr | 8 + .../ui/parser/attribute/attrs-after-extern-mod.rs | 7 + .../parser/attribute/attrs-after-extern-mod.stderr | 12 + tests/ui/parser/attrs-after-extern-mod.rs | 7 - tests/ui/parser/attrs-after-extern-mod.stderr | 12 - 44 files changed, 696 insertions(+), 696 deletions(-) delete mode 100644 tests/ui/parser/attr-bad-meta-2.rs delete mode 100644 tests/ui/parser/attr-bad-meta-2.stderr delete mode 100644 tests/ui/parser/attr-bad-meta-3.rs delete mode 100644 tests/ui/parser/attr-bad-meta-3.stderr delete mode 100644 tests/ui/parser/attr-bad-meta.rs delete mode 100644 tests/ui/parser/attr-bad-meta.stderr delete mode 100644 tests/ui/parser/attr-before-eof.rs delete mode 100644 tests/ui/parser/attr-before-eof.stderr delete mode 100644 tests/ui/parser/attr-dangling-in-fn.rs delete mode 100644 tests/ui/parser/attr-dangling-in-fn.stderr delete mode 100644 tests/ui/parser/attr-dangling-in-mod.rs delete mode 100644 tests/ui/parser/attr-dangling-in-mod.stderr delete mode 100644 tests/ui/parser/attr-stmt-expr-attr-bad.rs delete mode 100644 tests/ui/parser/attr-stmt-expr-attr-bad.stderr delete mode 100644 tests/ui/parser/attr-with-a-semicolon.rs delete mode 100644 tests/ui/parser/attr-with-a-semicolon.stderr delete mode 100644 tests/ui/parser/attr.rs delete mode 100644 tests/ui/parser/attr.stderr delete mode 100644 tests/ui/parser/attribute-with-no-generics-in-parameter-list.rs delete mode 100644 tests/ui/parser/attribute-with-no-generics-in-parameter-list.stderr create mode 100644 tests/ui/parser/attribute/attr-bad-meta-2.rs create mode 100644 tests/ui/parser/attribute/attr-bad-meta-2.stderr create mode 100644 tests/ui/parser/attribute/attr-bad-meta-3.rs create mode 100644 tests/ui/parser/attribute/attr-bad-meta-3.stderr create mode 100644 tests/ui/parser/attribute/attr-bad-meta.rs create mode 100644 tests/ui/parser/attribute/attr-bad-meta.stderr create mode 100644 tests/ui/parser/attribute/attr-before-eof.rs create mode 100644 tests/ui/parser/attribute/attr-before-eof.stderr create mode 100644 tests/ui/parser/attribute/attr-dangling-in-fn.rs create mode 100644 tests/ui/parser/attribute/attr-dangling-in-fn.stderr create mode 100644 tests/ui/parser/attribute/attr-dangling-in-mod.rs create mode 100644 tests/ui/parser/attribute/attr-dangling-in-mod.stderr create mode 100644 tests/ui/parser/attribute/attr-stmt-expr-attr-bad.rs create mode 100644 tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr create mode 100644 tests/ui/parser/attribute/attr-with-a-semicolon.rs create mode 100644 tests/ui/parser/attribute/attr-with-a-semicolon.stderr create mode 100644 tests/ui/parser/attribute/attr.rs create mode 100644 tests/ui/parser/attribute/attr.stderr create mode 100644 tests/ui/parser/attribute/attribute-with-no-generics-in-parameter-list.rs create mode 100644 tests/ui/parser/attribute/attribute-with-no-generics-in-parameter-list.stderr create mode 100644 tests/ui/parser/attribute/attrs-after-extern-mod.rs create mode 100644 tests/ui/parser/attribute/attrs-after-extern-mod.stderr delete mode 100644 tests/ui/parser/attrs-after-extern-mod.rs delete mode 100644 tests/ui/parser/attrs-after-extern-mod.stderr diff --git a/tests/ui/parser/attr-bad-meta-2.rs b/tests/ui/parser/attr-bad-meta-2.rs deleted file mode 100644 index db612ed883d..00000000000 --- a/tests/ui/parser/attr-bad-meta-2.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[path =] //~ ERROR expected expression, found `]` -mod m {} diff --git a/tests/ui/parser/attr-bad-meta-2.stderr b/tests/ui/parser/attr-bad-meta-2.stderr deleted file mode 100644 index 6fc6fb665a8..00000000000 --- a/tests/ui/parser/attr-bad-meta-2.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: expected expression, found `]` - --> $DIR/attr-bad-meta-2.rs:1:9 - | -LL | #[path =] - | ^ expected expression - -error: aborting due to previous error - diff --git a/tests/ui/parser/attr-bad-meta-3.rs b/tests/ui/parser/attr-bad-meta-3.rs deleted file mode 100644 index b51e9f2212d..00000000000 --- a/tests/ui/parser/attr-bad-meta-3.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[path() token] //~ ERROR expected `]`, found `token` -mod m {} diff --git a/tests/ui/parser/attr-bad-meta-3.stderr b/tests/ui/parser/attr-bad-meta-3.stderr deleted file mode 100644 index 4fa420c79fc..00000000000 --- a/tests/ui/parser/attr-bad-meta-3.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: expected `]`, found `token` - --> $DIR/attr-bad-meta-3.rs:1:10 - | -LL | #[path() token] - | ^^^^^ expected `]` - -error: aborting due to previous error - diff --git a/tests/ui/parser/attr-bad-meta.rs b/tests/ui/parser/attr-bad-meta.rs deleted file mode 100644 index 8001977f5a3..00000000000 --- a/tests/ui/parser/attr-bad-meta.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[path*] //~ ERROR expected one of `(`, `::`, `=`, `[`, `]`, or `{`, found `*` -mod m {} diff --git a/tests/ui/parser/attr-bad-meta.stderr b/tests/ui/parser/attr-bad-meta.stderr deleted file mode 100644 index 8d65c423c8d..00000000000 --- a/tests/ui/parser/attr-bad-meta.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: expected one of `(`, `::`, `=`, `[`, `]`, or `{`, found `*` - --> $DIR/attr-bad-meta.rs:1:7 - | -LL | #[path*] - | ^ expected one of `(`, `::`, `=`, `[`, `]`, or `{` - -error: aborting due to previous error - diff --git a/tests/ui/parser/attr-before-eof.rs b/tests/ui/parser/attr-before-eof.rs deleted file mode 100644 index 6af1783e630..00000000000 --- a/tests/ui/parser/attr-before-eof.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() {} - -#[derive(Debug)] //~ERROR expected item after attributes diff --git a/tests/ui/parser/attr-before-eof.stderr b/tests/ui/parser/attr-before-eof.stderr deleted file mode 100644 index a2acb94372b..00000000000 --- a/tests/ui/parser/attr-before-eof.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: expected item after attributes - --> $DIR/attr-before-eof.rs:3:1 - | -LL | #[derive(Debug)] - | ^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/tests/ui/parser/attr-dangling-in-fn.rs b/tests/ui/parser/attr-dangling-in-fn.rs deleted file mode 100644 index c7c45bafb0d..00000000000 --- a/tests/ui/parser/attr-dangling-in-fn.rs +++ /dev/null @@ -1,8 +0,0 @@ -// error-pattern:expected statement - -fn f() { - #[foo = "bar"] -} - -fn main() { -} diff --git a/tests/ui/parser/attr-dangling-in-fn.stderr b/tests/ui/parser/attr-dangling-in-fn.stderr deleted file mode 100644 index b1bb3ab3b17..00000000000 --- a/tests/ui/parser/attr-dangling-in-fn.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: expected statement after outer attribute - --> $DIR/attr-dangling-in-fn.rs:4:3 - | -LL | #[foo = "bar"] - | ^^^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/tests/ui/parser/attr-dangling-in-mod.rs b/tests/ui/parser/attr-dangling-in-mod.rs deleted file mode 100644 index 261ed3913af..00000000000 --- a/tests/ui/parser/attr-dangling-in-mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -// error-pattern:expected item - -fn main() { -} - -#[foo = "bar"] diff --git a/tests/ui/parser/attr-dangling-in-mod.stderr b/tests/ui/parser/attr-dangling-in-mod.stderr deleted file mode 100644 index 1c892eac08f..00000000000 --- a/tests/ui/parser/attr-dangling-in-mod.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: expected item after attributes - --> $DIR/attr-dangling-in-mod.rs:6:1 - | -LL | #[foo = "bar"] - | ^^^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/tests/ui/parser/attr-stmt-expr-attr-bad.rs b/tests/ui/parser/attr-stmt-expr-attr-bad.rs deleted file mode 100644 index d1950087c4c..00000000000 --- a/tests/ui/parser/attr-stmt-expr-attr-bad.rs +++ /dev/null @@ -1,108 +0,0 @@ -fn main() {} - -#[cfg(FALSE)] fn e() { let _ = [#[attr]]; } -//~^ ERROR expected expression, found `]` -#[cfg(FALSE)] fn e() { let _ = foo#[attr](); } -//~^ ERROR expected one of -#[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } -//~^ ERROR an inner attribute is not permitted in this context -//~| ERROR an inner attribute is not permitted in this context -//~| ERROR expected expression, found `)` -#[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } -//~^ ERROR an inner attribute is not permitted in this context -//~| ERROR expected expression, found `)` -#[cfg(FALSE)] fn e() { let _ = 0 + #![attr] 0; } -//~^ ERROR an inner attribute is not permitted in this context -#[cfg(FALSE)] fn e() { let _ = !#![attr] 0; } -//~^ ERROR an inner attribute is not permitted in this context -#[cfg(FALSE)] fn e() { let _ = -#![attr] 0; } -//~^ ERROR an inner attribute is not permitted in this context -#[cfg(FALSE)] fn e() { let _ = x #![attr] as Y; } -//~^ ERROR expected one of -#[cfg(FALSE)] fn e() { let _ = || #![attr] foo; } -//~^ ERROR an inner attribute is not permitted in this context -#[cfg(FALSE)] fn e() { let _ = move || #![attr] foo; } -//~^ ERROR an inner attribute is not permitted in this context -#[cfg(FALSE)] fn e() { let _ = || #![attr] {foo}; } -//~^ ERROR an inner attribute is not permitted in this context -#[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; } -//~^ ERROR an inner attribute is not permitted in this context -#[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; } -//~^ ERROR expected expression, found `..` -#[cfg(FALSE)] fn e() { let _ = #[attr] ..; } -//~^ ERROR expected expression, found `..` -#[cfg(FALSE)] fn e() { let _ = #[attr] &#![attr] 0; } -//~^ ERROR an inner attribute is not permitted in this context -#[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; } -//~^ ERROR an inner attribute is not permitted in this context -#[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; } -//~^ ERROR outer attributes are not allowed on `if` -#[cfg(FALSE)] fn e() { let _ = if 0 {#![attr]}; } -//~^ ERROR an inner attribute is not permitted in this context -#[cfg(FALSE)] fn e() { let _ = if 0 {} #[attr] else {}; } -//~^ ERROR expected one of -#[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] {}; } -//~^ ERROR outer attributes are not allowed on `if` -#[cfg(FALSE)] fn e() { let _ = if 0 {} else {#![attr]}; } -//~^ ERROR an inner attribute is not permitted in this context -#[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; } -//~^ ERROR outer attributes are not allowed on `if` -#[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; } -//~^ ERROR outer attributes are not allowed on `if` -#[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {#![attr]}; } -//~^ ERROR an inner attribute is not permitted in this context -#[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; } -//~^ ERROR outer attributes are not allowed on `if` -#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {#![attr]}; } -//~^ ERROR an inner attribute is not permitted in this context -#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} #[attr] else {}; } -//~^ ERROR expected one of -#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] {}; } -//~^ ERROR outer attributes are not allowed on `if` -#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else {#![attr]}; } -//~^ ERROR an inner attribute is not permitted in this context -#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; } -//~^ ERROR outer attributes are not allowed on `if` -#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}; } -//~^ ERROR outer attributes are not allowed on `if` -#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {#![attr]}; } -//~^ ERROR an inner attribute is not permitted in this context - -#[cfg(FALSE)] fn s() { #[attr] #![attr] let _ = 0; } -//~^ ERROR an inner attribute is not permitted following an outer attribute -#[cfg(FALSE)] fn s() { #[attr] #![attr] 0; } -//~^ ERROR an inner attribute is not permitted following an outer attribute -#[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); } -//~^ ERROR an inner attribute is not permitted following an outer attribute -#[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; } -//~^ ERROR an inner attribute is not permitted following an outer attribute -#[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; } -//~^ ERROR an inner attribute is not permitted following an outer attribute - -// FIXME: Allow attributes in pattern constexprs? -// note: requires parens in patterns to allow disambiguation - -#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } -//~^ ERROR inclusive range with no end -//~| ERROR expected one of `=>`, `if`, or `|`, found `#` -#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } -//~^ ERROR inclusive range with no end -//~| ERROR expected one of `=>`, `if`, or `|`, found `#` -#[cfg(FALSE)] fn e() { match 0 { 0..=-#[attr] 10 => () } } -//~^ ERROR unexpected token: `#` -#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } -//~^ ERROR inclusive range with no end -//~| ERROR expected one of `=>`, `if`, or `|`, found `#` - -#[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); } -//~^ ERROR unexpected token: `#` -//~| ERROR expected one of `.` -#[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); } -//~^ ERROR unexpected token: `#` -//~| ERROR expected one of `.` - -// make sure we don't catch this bug again... -#[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } } -//~^ ERROR expected statement after outer attribute -#[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } } -//~^ ERROR expected statement after outer attribute diff --git a/tests/ui/parser/attr-stmt-expr-attr-bad.stderr b/tests/ui/parser/attr-stmt-expr-attr-bad.stderr deleted file mode 100644 index e46c591080d..00000000000 --- a/tests/ui/parser/attr-stmt-expr-attr-bad.stderr +++ /dev/null @@ -1,446 +0,0 @@ -error: expected expression, found `]` - --> $DIR/attr-stmt-expr-attr-bad.rs:3:40 - | -LL | #[cfg(FALSE)] fn e() { let _ = [#[attr]]; } - | ^ expected expression - -error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:5:35 - | -LL | #[cfg(FALSE)] fn e() { let _ = foo#[attr](); } - | ^ expected one of 8 possible tokens - -error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:7:36 - | -LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } - | ^^^^^^^^ - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:7:36 - | -LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } - | ^^^^^^^^ - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: expected expression, found `)` - --> $DIR/attr-stmt-expr-attr-bad.rs:7:44 - | -LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } - | ^ expected expression - -error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:11:38 - | -LL | #[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } - | ^^^^^^^^ - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: expected expression, found `)` - --> $DIR/attr-stmt-expr-attr-bad.rs:11:46 - | -LL | #[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } - | ^ expected expression - -error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:14:36 - | -LL | #[cfg(FALSE)] fn e() { let _ = 0 + #![attr] 0; } - | ^^^^^^^^ - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:16:33 - | -LL | #[cfg(FALSE)] fn e() { let _ = !#![attr] 0; } - | ^^^^^^^^ - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:18:33 - | -LL | #[cfg(FALSE)] fn e() { let _ = -#![attr] 0; } - | ^^^^^^^^ - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:20:34 - | -LL | #[cfg(FALSE)] fn e() { let _ = x #![attr] as Y; } - | ^ expected one of 8 possible tokens - -error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:22:35 - | -LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] foo; } - | ^^^^^^^^ - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:24:40 - | -LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] foo; } - | ^^^^^^^^ - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:26:35 - | -LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] {foo}; } - | ^^^^^^^^ - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:28:40 - | -LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; } - | ^^^^^^^^ - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: expected expression, found `..` - --> $DIR/attr-stmt-expr-attr-bad.rs:30:40 - | -LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; } - | ^^ expected expression - -error: expected expression, found `..` - --> $DIR/attr-stmt-expr-attr-bad.rs:32:40 - | -LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..; } - | ^^ expected expression - -error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:34:41 - | -LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &#![attr] 0; } - | ^^^^^^^^ - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:36:45 - | -LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; } - | ^^^^^^^^ - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: outer attributes are not allowed on `if` and `else` branches - --> $DIR/attr-stmt-expr-attr-bad.rs:38:37 - | -LL | #[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; } - | -- ^^^^^^^ -- the attributes are attached to this branch - | | | - | | help: remove the attributes - | the branch belongs to this `if` - -error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:40:38 - | -LL | #[cfg(FALSE)] fn e() { let _ = if 0 {#![attr]}; } - | ^^^^^^^^ - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:42:40 - | -LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} #[attr] else {}; } - | ^ expected one of `.`, `;`, `?`, `else`, or an operator - -error: outer attributes are not allowed on `if` and `else` branches - --> $DIR/attr-stmt-expr-attr-bad.rs:44:45 - | -LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] {}; } - | ---- ^^^^^^^ -- the attributes are attached to this branch - | | | - | | help: remove the attributes - | the branch belongs to this `else` - -error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:46:46 - | -LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else {#![attr]}; } - | ^^^^^^^^ - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: outer attributes are not allowed on `if` and `else` branches - --> $DIR/attr-stmt-expr-attr-bad.rs:48:45 - | -LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; } - | ---- ^^^^^^^ ------- the attributes are attached to this branch - | | | - | | help: remove the attributes - | the branch belongs to this `else` - -error: outer attributes are not allowed on `if` and `else` branches - --> $DIR/attr-stmt-expr-attr-bad.rs:50:50 - | -LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; } - | -- ^^^^^^^ -- the attributes are attached to this branch - | | | - | | help: remove the attributes - | the branch belongs to this `if` - -error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:52:51 - | -LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {#![attr]}; } - | ^^^^^^^^ - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: outer attributes are not allowed on `if` and `else` branches - --> $DIR/attr-stmt-expr-attr-bad.rs:54:45 - | -LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; } - | -- ^^^^^^^ -- the attributes are attached to this branch - | | | - | | help: remove the attributes - | the branch belongs to this `if` - -error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:56:46 - | -LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {#![attr]}; } - | ^^^^^^^^ - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:58:48 - | -LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} #[attr] else {}; } - | ^ expected one of `.`, `;`, `?`, `else`, or an operator - -error: outer attributes are not allowed on `if` and `else` branches - --> $DIR/attr-stmt-expr-attr-bad.rs:60:53 - | -LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] {}; } - | ---- ^^^^^^^ -- the attributes are attached to this branch - | | | - | | help: remove the attributes - | the branch belongs to this `else` - -error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:62:54 - | -LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else {#![attr]}; } - | ^^^^^^^^ - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: outer attributes are not allowed on `if` and `else` branches - --> $DIR/attr-stmt-expr-attr-bad.rs:64:53 - | -LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; } - | ---- ^^^^^^^ --------------- the attributes are attached to this branch - | | | - | | help: remove the attributes - | the branch belongs to this `else` - -error: outer attributes are not allowed on `if` and `else` branches - --> $DIR/attr-stmt-expr-attr-bad.rs:66:66 - | -LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}; } - | -- ^^^^^^^ -- the attributes are attached to this branch - | | | - | | help: remove the attributes - | the branch belongs to this `if` - -error: an inner attribute is not permitted in this context - --> $DIR/attr-stmt-expr-attr-bad.rs:68:67 - | -LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {#![attr]}; } - | ^^^^^^^^ - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: an inner attribute is not permitted following an outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:71:32 - | -LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] let _ = 0; } - | ------- ^^^^^^^^ not permitted following an outer attribute - | | - | previous outer attribute - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: an inner attribute is not permitted following an outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:73:32 - | -LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] 0; } - | ------- ^^^^^^^^ not permitted following an outer attribute - | | - | previous outer attribute - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files - = note: outer attributes, like `#[test]`, annotate the item following them - -error: an inner attribute is not permitted following an outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:75:32 - | -LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); } - | ------- ^^^^^^^^ ------- the inner attribute doesn't annotate this item macro invocation - | | | - | | not permitted following an outer attribute - | previous outer attribute - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files -help: to annotate the item macro invocation, change the attribute from inner to outer style - | -LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); } -LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!(); } - | - -error: an inner attribute is not permitted following an outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:77:32 - | -LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; } - | ------- ^^^^^^^^ ------- the inner attribute doesn't annotate this item macro invocation - | | | - | | not permitted following an outer attribute - | previous outer attribute - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files -help: to annotate the item macro invocation, change the attribute from inner to outer style - | -LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; } -LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo![]; } - | - -error: an inner attribute is not permitted following an outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:79:32 - | -LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; } - | ------- ^^^^^^^^ ------ the inner attribute doesn't annotate this item macro invocation - | | | - | | not permitted following an outer attribute - | previous outer attribute - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files -help: to annotate the item macro invocation, change the attribute from inner to outer style - | -LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; } -LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!{}; } - | - -error[E0586]: inclusive range with no end - --> $DIR/attr-stmt-expr-attr-bad.rs:85:35 - | -LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } - | ^^^ help: use `..` instead - | - = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) - -error: expected one of `=>`, `if`, or `|`, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:85:38 - | -LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } - | ^ expected one of `=>`, `if`, or `|` - -error[E0586]: inclusive range with no end - --> $DIR/attr-stmt-expr-attr-bad.rs:88:35 - | -LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } - | ^^^ help: use `..` instead - | - = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) - -error: expected one of `=>`, `if`, or `|`, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:88:38 - | -LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } - | ^ expected one of `=>`, `if`, or `|` - -error: unexpected token: `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:91:39 - | -LL | #[cfg(FALSE)] fn e() { match 0 { 0..=-#[attr] 10 => () } } - | ^ - -error[E0586]: inclusive range with no end - --> $DIR/attr-stmt-expr-attr-bad.rs:93:35 - | -LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } - | ^^^ help: use `..` instead - | - = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) - -error: expected one of `=>`, `if`, or `|`, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:93:38 - | -LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } - | ^ expected one of `=>`, `if`, or `|` - -error: unexpected token: `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:97:34 - | -LL | #[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); } - | ^ - -error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:97:34 - | -LL | #[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); } - | ^ expected one of `.`, `;`, `?`, `else`, or an operator - -error: unexpected token: `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:100:34 - | -LL | #[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); } - | ^ - -error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` - --> $DIR/attr-stmt-expr-attr-bad.rs:100:34 - | -LL | #[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); } - | ^ expected one of `.`, `;`, `?`, `else`, or an operator - -error: expected statement after outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:105:37 - | -LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } } - | ^^^^^^^ - -error: expected statement after outer attribute - --> $DIR/attr-stmt-expr-attr-bad.rs:107:37 - | -LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } } - | ^^^^^^^ - -error: aborting due to 53 previous errors - -For more information about this error, try `rustc --explain E0586`. diff --git a/tests/ui/parser/attr-with-a-semicolon.rs b/tests/ui/parser/attr-with-a-semicolon.rs deleted file mode 100644 index 56fe40b916b..00000000000 --- a/tests/ui/parser/attr-with-a-semicolon.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[derive(Debug, Clone)]; //~ERROR expected item after attributes -struct Foo; - -fn main() {} diff --git a/tests/ui/parser/attr-with-a-semicolon.stderr b/tests/ui/parser/attr-with-a-semicolon.stderr deleted file mode 100644 index 0de3490b8ea..00000000000 --- a/tests/ui/parser/attr-with-a-semicolon.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: expected item after attributes - --> $DIR/attr-with-a-semicolon.rs:1:1 - | -LL | #[derive(Debug, Clone)]; - | ^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider removing this semicolon - | -LL - #[derive(Debug, Clone)]; -LL + #[derive(Debug, Clone)] - | - -error: aborting due to previous error - diff --git a/tests/ui/parser/attr.rs b/tests/ui/parser/attr.rs deleted file mode 100644 index 42b2dfde855..00000000000 --- a/tests/ui/parser/attr.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(lang_items)] - -fn main() {} - -#![lang = "foo"] //~ ERROR an inner attribute is not permitted in this context -fn foo() {} diff --git a/tests/ui/parser/attr.stderr b/tests/ui/parser/attr.stderr deleted file mode 100644 index 7cd0ac2244a..00000000000 --- a/tests/ui/parser/attr.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error: an inner attribute is not permitted in this context - --> $DIR/attr.rs:5:1 - | -LL | #![lang = "foo"] - | ^^^^^^^^^^^^^^^^ -LL | fn foo() {} - | ----------- the inner attribute doesn't annotate this function - | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files -help: to annotate the function, change the attribute from inner to outer style - | -LL - #![lang = "foo"] -LL + #[lang = "foo"] - | - -error: aborting due to previous error - diff --git a/tests/ui/parser/attribute-with-no-generics-in-parameter-list.rs b/tests/ui/parser/attribute-with-no-generics-in-parameter-list.rs deleted file mode 100644 index c2cc91d8f77..00000000000 --- a/tests/ui/parser/attribute-with-no-generics-in-parameter-list.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn foo<#[attr]>() {} //~ ERROR attribute without generic parameters - -fn main() {} diff --git a/tests/ui/parser/attribute-with-no-generics-in-parameter-list.stderr b/tests/ui/parser/attribute-with-no-generics-in-parameter-list.stderr deleted file mode 100644 index 4c5964715db..00000000000 --- a/tests/ui/parser/attribute-with-no-generics-in-parameter-list.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: attribute without generic parameters - --> $DIR/attribute-with-no-generics-in-parameter-list.rs:1:8 - | -LL | fn foo<#[attr]>() {} - | ^^^^^^^ attributes are only permitted when preceding parameters - -error: aborting due to previous error - diff --git a/tests/ui/parser/attribute/attr-bad-meta-2.rs b/tests/ui/parser/attribute/attr-bad-meta-2.rs new file mode 100644 index 00000000000..db612ed883d --- /dev/null +++ b/tests/ui/parser/attribute/attr-bad-meta-2.rs @@ -0,0 +1,2 @@ +#[path =] //~ ERROR expected expression, found `]` +mod m {} diff --git a/tests/ui/parser/attribute/attr-bad-meta-2.stderr b/tests/ui/parser/attribute/attr-bad-meta-2.stderr new file mode 100644 index 00000000000..6fc6fb665a8 --- /dev/null +++ b/tests/ui/parser/attribute/attr-bad-meta-2.stderr @@ -0,0 +1,8 @@ +error: expected expression, found `]` + --> $DIR/attr-bad-meta-2.rs:1:9 + | +LL | #[path =] + | ^ expected expression + +error: aborting due to previous error + diff --git a/tests/ui/parser/attribute/attr-bad-meta-3.rs b/tests/ui/parser/attribute/attr-bad-meta-3.rs new file mode 100644 index 00000000000..b51e9f2212d --- /dev/null +++ b/tests/ui/parser/attribute/attr-bad-meta-3.rs @@ -0,0 +1,2 @@ +#[path() token] //~ ERROR expected `]`, found `token` +mod m {} diff --git a/tests/ui/parser/attribute/attr-bad-meta-3.stderr b/tests/ui/parser/attribute/attr-bad-meta-3.stderr new file mode 100644 index 00000000000..4fa420c79fc --- /dev/null +++ b/tests/ui/parser/attribute/attr-bad-meta-3.stderr @@ -0,0 +1,8 @@ +error: expected `]`, found `token` + --> $DIR/attr-bad-meta-3.rs:1:10 + | +LL | #[path() token] + | ^^^^^ expected `]` + +error: aborting due to previous error + diff --git a/tests/ui/parser/attribute/attr-bad-meta.rs b/tests/ui/parser/attribute/attr-bad-meta.rs new file mode 100644 index 00000000000..8001977f5a3 --- /dev/null +++ b/tests/ui/parser/attribute/attr-bad-meta.rs @@ -0,0 +1,2 @@ +#[path*] //~ ERROR expected one of `(`, `::`, `=`, `[`, `]`, or `{`, found `*` +mod m {} diff --git a/tests/ui/parser/attribute/attr-bad-meta.stderr b/tests/ui/parser/attribute/attr-bad-meta.stderr new file mode 100644 index 00000000000..8d65c423c8d --- /dev/null +++ b/tests/ui/parser/attribute/attr-bad-meta.stderr @@ -0,0 +1,8 @@ +error: expected one of `(`, `::`, `=`, `[`, `]`, or `{`, found `*` + --> $DIR/attr-bad-meta.rs:1:7 + | +LL | #[path*] + | ^ expected one of `(`, `::`, `=`, `[`, `]`, or `{` + +error: aborting due to previous error + diff --git a/tests/ui/parser/attribute/attr-before-eof.rs b/tests/ui/parser/attribute/attr-before-eof.rs new file mode 100644 index 00000000000..6af1783e630 --- /dev/null +++ b/tests/ui/parser/attribute/attr-before-eof.rs @@ -0,0 +1,3 @@ +fn main() {} + +#[derive(Debug)] //~ERROR expected item after attributes diff --git a/tests/ui/parser/attribute/attr-before-eof.stderr b/tests/ui/parser/attribute/attr-before-eof.stderr new file mode 100644 index 00000000000..a2acb94372b --- /dev/null +++ b/tests/ui/parser/attribute/attr-before-eof.stderr @@ -0,0 +1,8 @@ +error: expected item after attributes + --> $DIR/attr-before-eof.rs:3:1 + | +LL | #[derive(Debug)] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/parser/attribute/attr-dangling-in-fn.rs b/tests/ui/parser/attribute/attr-dangling-in-fn.rs new file mode 100644 index 00000000000..c7c45bafb0d --- /dev/null +++ b/tests/ui/parser/attribute/attr-dangling-in-fn.rs @@ -0,0 +1,8 @@ +// error-pattern:expected statement + +fn f() { + #[foo = "bar"] +} + +fn main() { +} diff --git a/tests/ui/parser/attribute/attr-dangling-in-fn.stderr b/tests/ui/parser/attribute/attr-dangling-in-fn.stderr new file mode 100644 index 00000000000..b1bb3ab3b17 --- /dev/null +++ b/tests/ui/parser/attribute/attr-dangling-in-fn.stderr @@ -0,0 +1,8 @@ +error: expected statement after outer attribute + --> $DIR/attr-dangling-in-fn.rs:4:3 + | +LL | #[foo = "bar"] + | ^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/parser/attribute/attr-dangling-in-mod.rs b/tests/ui/parser/attribute/attr-dangling-in-mod.rs new file mode 100644 index 00000000000..261ed3913af --- /dev/null +++ b/tests/ui/parser/attribute/attr-dangling-in-mod.rs @@ -0,0 +1,6 @@ +// error-pattern:expected item + +fn main() { +} + +#[foo = "bar"] diff --git a/tests/ui/parser/attribute/attr-dangling-in-mod.stderr b/tests/ui/parser/attribute/attr-dangling-in-mod.stderr new file mode 100644 index 00000000000..1c892eac08f --- /dev/null +++ b/tests/ui/parser/attribute/attr-dangling-in-mod.stderr @@ -0,0 +1,8 @@ +error: expected item after attributes + --> $DIR/attr-dangling-in-mod.rs:6:1 + | +LL | #[foo = "bar"] + | ^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.rs b/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.rs new file mode 100644 index 00000000000..d1950087c4c --- /dev/null +++ b/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.rs @@ -0,0 +1,108 @@ +fn main() {} + +#[cfg(FALSE)] fn e() { let _ = [#[attr]]; } +//~^ ERROR expected expression, found `]` +#[cfg(FALSE)] fn e() { let _ = foo#[attr](); } +//~^ ERROR expected one of +#[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } +//~^ ERROR an inner attribute is not permitted in this context +//~| ERROR an inner attribute is not permitted in this context +//~| ERROR expected expression, found `)` +#[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } +//~^ ERROR an inner attribute is not permitted in this context +//~| ERROR expected expression, found `)` +#[cfg(FALSE)] fn e() { let _ = 0 + #![attr] 0; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = !#![attr] 0; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = -#![attr] 0; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = x #![attr] as Y; } +//~^ ERROR expected one of +#[cfg(FALSE)] fn e() { let _ = || #![attr] foo; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = move || #![attr] foo; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = || #![attr] {foo}; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; } +//~^ ERROR expected expression, found `..` +#[cfg(FALSE)] fn e() { let _ = #[attr] ..; } +//~^ ERROR expected expression, found `..` +#[cfg(FALSE)] fn e() { let _ = #[attr] &#![attr] 0; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; } +//~^ ERROR outer attributes are not allowed on `if` +#[cfg(FALSE)] fn e() { let _ = if 0 {#![attr]}; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = if 0 {} #[attr] else {}; } +//~^ ERROR expected one of +#[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] {}; } +//~^ ERROR outer attributes are not allowed on `if` +#[cfg(FALSE)] fn e() { let _ = if 0 {} else {#![attr]}; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; } +//~^ ERROR outer attributes are not allowed on `if` +#[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; } +//~^ ERROR outer attributes are not allowed on `if` +#[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {#![attr]}; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; } +//~^ ERROR outer attributes are not allowed on `if` +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {#![attr]}; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} #[attr] else {}; } +//~^ ERROR expected one of +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] {}; } +//~^ ERROR outer attributes are not allowed on `if` +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else {#![attr]}; } +//~^ ERROR an inner attribute is not permitted in this context +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; } +//~^ ERROR outer attributes are not allowed on `if` +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}; } +//~^ ERROR outer attributes are not allowed on `if` +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {#![attr]}; } +//~^ ERROR an inner attribute is not permitted in this context + +#[cfg(FALSE)] fn s() { #[attr] #![attr] let _ = 0; } +//~^ ERROR an inner attribute is not permitted following an outer attribute +#[cfg(FALSE)] fn s() { #[attr] #![attr] 0; } +//~^ ERROR an inner attribute is not permitted following an outer attribute +#[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); } +//~^ ERROR an inner attribute is not permitted following an outer attribute +#[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; } +//~^ ERROR an inner attribute is not permitted following an outer attribute +#[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; } +//~^ ERROR an inner attribute is not permitted following an outer attribute + +// FIXME: Allow attributes in pattern constexprs? +// note: requires parens in patterns to allow disambiguation + +#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } +//~^ ERROR inclusive range with no end +//~| ERROR expected one of `=>`, `if`, or `|`, found `#` +#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } +//~^ ERROR inclusive range with no end +//~| ERROR expected one of `=>`, `if`, or `|`, found `#` +#[cfg(FALSE)] fn e() { match 0 { 0..=-#[attr] 10 => () } } +//~^ ERROR unexpected token: `#` +#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } +//~^ ERROR inclusive range with no end +//~| ERROR expected one of `=>`, `if`, or `|`, found `#` + +#[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); } +//~^ ERROR unexpected token: `#` +//~| ERROR expected one of `.` +#[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); } +//~^ ERROR unexpected token: `#` +//~| ERROR expected one of `.` + +// make sure we don't catch this bug again... +#[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } } +//~^ ERROR expected statement after outer attribute +#[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } } +//~^ ERROR expected statement after outer attribute diff --git a/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr b/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr new file mode 100644 index 00000000000..e46c591080d --- /dev/null +++ b/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr @@ -0,0 +1,446 @@ +error: expected expression, found `]` + --> $DIR/attr-stmt-expr-attr-bad.rs:3:40 + | +LL | #[cfg(FALSE)] fn e() { let _ = [#[attr]]; } + | ^ expected expression + +error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:5:35 + | +LL | #[cfg(FALSE)] fn e() { let _ = foo#[attr](); } + | ^ expected one of 8 possible tokens + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:7:36 + | +LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:7:36 + | +LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: expected expression, found `)` + --> $DIR/attr-stmt-expr-attr-bad.rs:7:44 + | +LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } + | ^ expected expression + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:11:38 + | +LL | #[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: expected expression, found `)` + --> $DIR/attr-stmt-expr-attr-bad.rs:11:46 + | +LL | #[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } + | ^ expected expression + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:14:36 + | +LL | #[cfg(FALSE)] fn e() { let _ = 0 + #![attr] 0; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:16:33 + | +LL | #[cfg(FALSE)] fn e() { let _ = !#![attr] 0; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:18:33 + | +LL | #[cfg(FALSE)] fn e() { let _ = -#![attr] 0; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:20:34 + | +LL | #[cfg(FALSE)] fn e() { let _ = x #![attr] as Y; } + | ^ expected one of 8 possible tokens + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:22:35 + | +LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] foo; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:24:40 + | +LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] foo; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:26:35 + | +LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] {foo}; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:28:40 + | +LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: expected expression, found `..` + --> $DIR/attr-stmt-expr-attr-bad.rs:30:40 + | +LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; } + | ^^ expected expression + +error: expected expression, found `..` + --> $DIR/attr-stmt-expr-attr-bad.rs:32:40 + | +LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..; } + | ^^ expected expression + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:34:41 + | +LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &#![attr] 0; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:36:45 + | +LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: outer attributes are not allowed on `if` and `else` branches + --> $DIR/attr-stmt-expr-attr-bad.rs:38:37 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; } + | -- ^^^^^^^ -- the attributes are attached to this branch + | | | + | | help: remove the attributes + | the branch belongs to this `if` + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:40:38 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 {#![attr]}; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:42:40 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} #[attr] else {}; } + | ^ expected one of `.`, `;`, `?`, `else`, or an operator + +error: outer attributes are not allowed on `if` and `else` branches + --> $DIR/attr-stmt-expr-attr-bad.rs:44:45 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] {}; } + | ---- ^^^^^^^ -- the attributes are attached to this branch + | | | + | | help: remove the attributes + | the branch belongs to this `else` + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:46:46 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else {#![attr]}; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: outer attributes are not allowed on `if` and `else` branches + --> $DIR/attr-stmt-expr-attr-bad.rs:48:45 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; } + | ---- ^^^^^^^ ------- the attributes are attached to this branch + | | | + | | help: remove the attributes + | the branch belongs to this `else` + +error: outer attributes are not allowed on `if` and `else` branches + --> $DIR/attr-stmt-expr-attr-bad.rs:50:50 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; } + | -- ^^^^^^^ -- the attributes are attached to this branch + | | | + | | help: remove the attributes + | the branch belongs to this `if` + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:52:51 + | +LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {#![attr]}; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: outer attributes are not allowed on `if` and `else` branches + --> $DIR/attr-stmt-expr-attr-bad.rs:54:45 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; } + | -- ^^^^^^^ -- the attributes are attached to this branch + | | | + | | help: remove the attributes + | the branch belongs to this `if` + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:56:46 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {#![attr]}; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:58:48 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} #[attr] else {}; } + | ^ expected one of `.`, `;`, `?`, `else`, or an operator + +error: outer attributes are not allowed on `if` and `else` branches + --> $DIR/attr-stmt-expr-attr-bad.rs:60:53 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] {}; } + | ---- ^^^^^^^ -- the attributes are attached to this branch + | | | + | | help: remove the attributes + | the branch belongs to this `else` + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:62:54 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else {#![attr]}; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: outer attributes are not allowed on `if` and `else` branches + --> $DIR/attr-stmt-expr-attr-bad.rs:64:53 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; } + | ---- ^^^^^^^ --------------- the attributes are attached to this branch + | | | + | | help: remove the attributes + | the branch belongs to this `else` + +error: outer attributes are not allowed on `if` and `else` branches + --> $DIR/attr-stmt-expr-attr-bad.rs:66:66 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}; } + | -- ^^^^^^^ -- the attributes are attached to this branch + | | | + | | help: remove the attributes + | the branch belongs to this `if` + +error: an inner attribute is not permitted in this context + --> $DIR/attr-stmt-expr-attr-bad.rs:68:67 + | +LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {#![attr]}; } + | ^^^^^^^^ + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted following an outer attribute + --> $DIR/attr-stmt-expr-attr-bad.rs:71:32 + | +LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] let _ = 0; } + | ------- ^^^^^^^^ not permitted following an outer attribute + | | + | previous outer attribute + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted following an outer attribute + --> $DIR/attr-stmt-expr-attr-bad.rs:73:32 + | +LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] 0; } + | ------- ^^^^^^^^ not permitted following an outer attribute + | | + | previous outer attribute + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them + +error: an inner attribute is not permitted following an outer attribute + --> $DIR/attr-stmt-expr-attr-bad.rs:75:32 + | +LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); } + | ------- ^^^^^^^^ ------- the inner attribute doesn't annotate this item macro invocation + | | | + | | not permitted following an outer attribute + | previous outer attribute + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the item macro invocation, change the attribute from inner to outer style + | +LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); } +LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!(); } + | + +error: an inner attribute is not permitted following an outer attribute + --> $DIR/attr-stmt-expr-attr-bad.rs:77:32 + | +LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; } + | ------- ^^^^^^^^ ------- the inner attribute doesn't annotate this item macro invocation + | | | + | | not permitted following an outer attribute + | previous outer attribute + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the item macro invocation, change the attribute from inner to outer style + | +LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; } +LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo![]; } + | + +error: an inner attribute is not permitted following an outer attribute + --> $DIR/attr-stmt-expr-attr-bad.rs:79:32 + | +LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; } + | ------- ^^^^^^^^ ------ the inner attribute doesn't annotate this item macro invocation + | | | + | | not permitted following an outer attribute + | previous outer attribute + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the item macro invocation, change the attribute from inner to outer style + | +LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; } +LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!{}; } + | + +error[E0586]: inclusive range with no end + --> $DIR/attr-stmt-expr-attr-bad.rs:85:35 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } + | ^^^ help: use `..` instead + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error: expected one of `=>`, `if`, or `|`, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:85:38 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } + | ^ expected one of `=>`, `if`, or `|` + +error[E0586]: inclusive range with no end + --> $DIR/attr-stmt-expr-attr-bad.rs:88:35 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } + | ^^^ help: use `..` instead + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error: expected one of `=>`, `if`, or `|`, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:88:38 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } + | ^ expected one of `=>`, `if`, or `|` + +error: unexpected token: `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:91:39 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=-#[attr] 10 => () } } + | ^ + +error[E0586]: inclusive range with no end + --> $DIR/attr-stmt-expr-attr-bad.rs:93:35 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } + | ^^^ help: use `..` instead + | + = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) + +error: expected one of `=>`, `if`, or `|`, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:93:38 + | +LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } + | ^ expected one of `=>`, `if`, or `|` + +error: unexpected token: `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:97:34 + | +LL | #[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); } + | ^ + +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:97:34 + | +LL | #[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); } + | ^ expected one of `.`, `;`, `?`, `else`, or an operator + +error: unexpected token: `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:100:34 + | +LL | #[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); } + | ^ + +error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` + --> $DIR/attr-stmt-expr-attr-bad.rs:100:34 + | +LL | #[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); } + | ^ expected one of `.`, `;`, `?`, `else`, or an operator + +error: expected statement after outer attribute + --> $DIR/attr-stmt-expr-attr-bad.rs:105:37 + | +LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } } + | ^^^^^^^ + +error: expected statement after outer attribute + --> $DIR/attr-stmt-expr-attr-bad.rs:107:37 + | +LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } } + | ^^^^^^^ + +error: aborting due to 53 previous errors + +For more information about this error, try `rustc --explain E0586`. diff --git a/tests/ui/parser/attribute/attr-with-a-semicolon.rs b/tests/ui/parser/attribute/attr-with-a-semicolon.rs new file mode 100644 index 00000000000..56fe40b916b --- /dev/null +++ b/tests/ui/parser/attribute/attr-with-a-semicolon.rs @@ -0,0 +1,4 @@ +#[derive(Debug, Clone)]; //~ERROR expected item after attributes +struct Foo; + +fn main() {} diff --git a/tests/ui/parser/attribute/attr-with-a-semicolon.stderr b/tests/ui/parser/attribute/attr-with-a-semicolon.stderr new file mode 100644 index 00000000000..0de3490b8ea --- /dev/null +++ b/tests/ui/parser/attribute/attr-with-a-semicolon.stderr @@ -0,0 +1,14 @@ +error: expected item after attributes + --> $DIR/attr-with-a-semicolon.rs:1:1 + | +LL | #[derive(Debug, Clone)]; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider removing this semicolon + | +LL - #[derive(Debug, Clone)]; +LL + #[derive(Debug, Clone)] + | + +error: aborting due to previous error + diff --git a/tests/ui/parser/attribute/attr.rs b/tests/ui/parser/attribute/attr.rs new file mode 100644 index 00000000000..42b2dfde855 --- /dev/null +++ b/tests/ui/parser/attribute/attr.rs @@ -0,0 +1,6 @@ +#![feature(lang_items)] + +fn main() {} + +#![lang = "foo"] //~ ERROR an inner attribute is not permitted in this context +fn foo() {} diff --git a/tests/ui/parser/attribute/attr.stderr b/tests/ui/parser/attribute/attr.stderr new file mode 100644 index 00000000000..7cd0ac2244a --- /dev/null +++ b/tests/ui/parser/attribute/attr.stderr @@ -0,0 +1,17 @@ +error: an inner attribute is not permitted in this context + --> $DIR/attr.rs:5:1 + | +LL | #![lang = "foo"] + | ^^^^^^^^^^^^^^^^ +LL | fn foo() {} + | ----------- the inner attribute doesn't annotate this function + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the function, change the attribute from inner to outer style + | +LL - #![lang = "foo"] +LL + #[lang = "foo"] + | + +error: aborting due to previous error + diff --git a/tests/ui/parser/attribute/attribute-with-no-generics-in-parameter-list.rs b/tests/ui/parser/attribute/attribute-with-no-generics-in-parameter-list.rs new file mode 100644 index 00000000000..c2cc91d8f77 --- /dev/null +++ b/tests/ui/parser/attribute/attribute-with-no-generics-in-parameter-list.rs @@ -0,0 +1,3 @@ +fn foo<#[attr]>() {} //~ ERROR attribute without generic parameters + +fn main() {} diff --git a/tests/ui/parser/attribute/attribute-with-no-generics-in-parameter-list.stderr b/tests/ui/parser/attribute/attribute-with-no-generics-in-parameter-list.stderr new file mode 100644 index 00000000000..4c5964715db --- /dev/null +++ b/tests/ui/parser/attribute/attribute-with-no-generics-in-parameter-list.stderr @@ -0,0 +1,8 @@ +error: attribute without generic parameters + --> $DIR/attribute-with-no-generics-in-parameter-list.rs:1:8 + | +LL | fn foo<#[attr]>() {} + | ^^^^^^^ attributes are only permitted when preceding parameters + +error: aborting due to previous error + diff --git a/tests/ui/parser/attribute/attrs-after-extern-mod.rs b/tests/ui/parser/attribute/attrs-after-extern-mod.rs new file mode 100644 index 00000000000..e3f0fa0fc46 --- /dev/null +++ b/tests/ui/parser/attribute/attrs-after-extern-mod.rs @@ -0,0 +1,7 @@ +// Make sure there's an error when given `extern { ... #[attr] }`. + +fn main() {} + +extern "C" { + #[cfg(stage37)] //~ ERROR expected item after attributes +} diff --git a/tests/ui/parser/attribute/attrs-after-extern-mod.stderr b/tests/ui/parser/attribute/attrs-after-extern-mod.stderr new file mode 100644 index 00000000000..135d98457e1 --- /dev/null +++ b/tests/ui/parser/attribute/attrs-after-extern-mod.stderr @@ -0,0 +1,12 @@ +error: expected item after attributes + --> $DIR/attrs-after-extern-mod.rs:6:5 + | +LL | extern "C" { + | - while parsing this item list starting here +LL | #[cfg(stage37)] + | ^^^^^^^^^^^^^^^ +LL | } + | - the item list ends here + +error: aborting due to previous error + diff --git a/tests/ui/parser/attrs-after-extern-mod.rs b/tests/ui/parser/attrs-after-extern-mod.rs deleted file mode 100644 index e3f0fa0fc46..00000000000 --- a/tests/ui/parser/attrs-after-extern-mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -// Make sure there's an error when given `extern { ... #[attr] }`. - -fn main() {} - -extern "C" { - #[cfg(stage37)] //~ ERROR expected item after attributes -} diff --git a/tests/ui/parser/attrs-after-extern-mod.stderr b/tests/ui/parser/attrs-after-extern-mod.stderr deleted file mode 100644 index 135d98457e1..00000000000 --- a/tests/ui/parser/attrs-after-extern-mod.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error: expected item after attributes - --> $DIR/attrs-after-extern-mod.rs:6:5 - | -LL | extern "C" { - | - while parsing this item list starting here -LL | #[cfg(stage37)] - | ^^^^^^^^^^^^^^^ -LL | } - | - the item list ends here - -error: aborting due to previous error - -- cgit 1.4.1-3-g733a5 From c30d57bb77535f3923cbfa666e84d1916b6bce37 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Wed, 4 Oct 2023 01:29:45 +0000 Subject: fix --- tests/ui/parser/break-in-unlabeled-block.fixed | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/ui/parser/break-in-unlabeled-block.fixed b/tests/ui/parser/break-in-unlabeled-block.fixed index 0e496430ae6..08856232521 100644 --- a/tests/ui/parser/break-in-unlabeled-block.fixed +++ b/tests/ui/parser/break-in-unlabeled-block.fixed @@ -9,4 +9,3 @@ fn main() { } } } - -- cgit 1.4.1-3-g733a5 From d23dc2093c2037a3f401d917ddb9e9c8507ef116 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Mon, 9 Oct 2023 22:48:10 +0000 Subject: Account for macros --- compiler/rustc_passes/src/loops.rs | 2 +- .../ui/parser/break-in-unlabeled-block-in-macro.rs | 43 ++++++++++++++ .../break-in-unlabeled-block-in-macro.stderr | 69 ++++++++++++++++++++++ 3 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 tests/ui/parser/break-in-unlabeled-block-in-macro.rs create mode 100644 tests/ui/parser/break-in-unlabeled-block-in-macro.stderr diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index 10763556c7c..4590ab9e4f5 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -231,7 +231,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> { AsyncClosure(closure_span) => { self.sess.emit_err(BreakInsideAsyncBlock { span, closure_span, name }); } - UnlabeledBlock(block_span) if is_break => { + UnlabeledBlock(block_span) if is_break && block_span.ctxt() == break_span.ctxt() => { let suggestion = Some(OutsideLoopSuggestion { block_span, break_span }); self.sess.emit_err(OutsideLoop { span, name, is_break, suggestion }); } diff --git a/tests/ui/parser/break-in-unlabeled-block-in-macro.rs b/tests/ui/parser/break-in-unlabeled-block-in-macro.rs new file mode 100644 index 00000000000..eecc0026b12 --- /dev/null +++ b/tests/ui/parser/break-in-unlabeled-block-in-macro.rs @@ -0,0 +1,43 @@ +macro_rules! foo { + () => { + break (); //~ ERROR `break` outside of a loop or labeled block + }; + ($e: expr) => { + break $e; //~ ERROR `break` outside of a loop or labeled block + }; + (stmt $s: stmt) => { + $s + }; + (@ $e: expr) => { + { break $e; } //~ ERROR `break` outside of a loop or labeled block + }; + (=> $s: stmt) => { + { $s } + }; +} + +fn main() { + { + foo!(); + } + { + foo!(()); + } + { + foo!(stmt break ()); //~ ERROR `break` outside of a loop or labeled block + } + { + foo!(@ ()); + } + { + foo!(=> break ()); //~ ERROR `break` outside of a loop or labeled block + } + { + macro_rules! bar { + () => { + break () //~ ERROR `break` outside of a loop or labeled block + }; + } + bar!() + } +} diff --git a/tests/ui/parser/break-in-unlabeled-block-in-macro.stderr b/tests/ui/parser/break-in-unlabeled-block-in-macro.stderr new file mode 100644 index 00000000000..9407e8ac002 --- /dev/null +++ b/tests/ui/parser/break-in-unlabeled-block-in-macro.stderr @@ -0,0 +1,69 @@ +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-in-unlabeled-block-in-macro.rs:3:9 + | +LL | break (); + | ^^^^^^^^ cannot `break` outside of a loop or labeled block +... +LL | foo!(); + | ------ in this macro invocation + | + = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-in-unlabeled-block-in-macro.rs:6:9 + | +LL | break $e; + | ^^^^^^^^ cannot `break` outside of a loop or labeled block +... +LL | foo!(()); + | -------- in this macro invocation + | + = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-in-unlabeled-block-in-macro.rs:27:19 + | +LL | foo!(stmt 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 ~ foo!(stmt break 'block ()); + | + +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-in-unlabeled-block-in-macro.rs:12:11 + | +LL | { break $e; } + | ^^^^^^^^ cannot `break` outside of a loop or labeled block +... +LL | foo!(@ ()); + | ---------- in this macro invocation + | + = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider labeling this block to be able to break within it + | +LL | 'block: { break 'block $e; } + | +++++++ ++++++ + +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-in-unlabeled-block-in-macro.rs:33:17 + | +LL | foo!(=> break ()); + | ^^^^^^^^ cannot `break` outside of a loop or labeled block + +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-in-unlabeled-block-in-macro.rs:38:17 + | +LL | break () + | ^^^^^^^^ cannot `break` outside of a loop or labeled block +... +LL | bar!() + | ------ in this macro invocation + | + = note: this error originates in the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0268`. -- cgit 1.4.1-3-g733a5