diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 873095dca8722..32a0df2f619ad 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -624,8 +624,6 @@ parse_or_pattern_not_allowed_in_let_binding = top-level or-patterns are not allo parse_out_of_range_hex_escape = out of range hex escape .label = must be a character in the range [\x00-\x7f] -parse_outer_attr_ambiguous = ambiguous outer attributes - parse_outer_attr_explanation = outer attributes, like `#[test]`, annotate the item following them parse_outer_attribute_not_allowed_on_if_else = outer attributes are not allowed on `if` and `else` branches diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index d06f03a7c1767..d33f9369c249f 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -495,15 +495,6 @@ pub(crate) struct OuterAttributeNotAllowedOnIfElse { pub attributes: Span, } -#[derive(Diagnostic)] -#[diag(parse_outer_attr_ambiguous)] -pub(crate) struct AmbiguousOuterAttributes { - #[primary_span] - pub span: Span, - #[subdiagnostic] - pub sugg: WrapInParentheses, -} - #[derive(Diagnostic)] #[diag(parse_missing_in_in_for_loop)] pub(crate) struct MissingInInForLoop { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 8ed2a6edf1aec..8a4546107186b 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -327,9 +327,7 @@ impl<'a> Parser<'a> { this.parse_expr_assoc_with(prec + prec_adjustment, LhsExpr::NotYetParsed) })?; - self.error_ambiguous_outer_attrs(&lhs, lhs_span, rhs.span); - let span = lhs_span.to(rhs.span); - + let span = self.mk_expr_sp(&lhs, lhs_span, rhs.span); lhs = match op { AssocOp::Add | AssocOp::Subtract @@ -428,18 +426,6 @@ impl<'a> Parser<'a> { }); } - fn error_ambiguous_outer_attrs(&self, lhs: &P, lhs_span: Span, rhs_span: Span) { - if let Some(attr) = lhs.attrs.iter().find(|a| a.style == AttrStyle::Outer) { - self.dcx().emit_err(errors::AmbiguousOuterAttributes { - span: attr.span.to(rhs_span), - sugg: errors::WrapInParentheses::Expression { - left: attr.span.shrink_to_lo(), - right: lhs_span.shrink_to_hi(), - }, - }); - } - } - /// Possibly translate the current token to an associative operator. /// The method does not advance the current token. /// @@ -520,8 +506,7 @@ impl<'a> Parser<'a> { None }; let rhs_span = rhs.as_ref().map_or(cur_op_span, |x| x.span); - self.error_ambiguous_outer_attrs(&lhs, lhs.span, rhs_span); - let span = lhs.span.to(rhs_span); + let span = self.mk_expr_sp(&lhs, lhs.span, rhs_span); let limits = if op == AssocOp::DotDot { RangeLimits::HalfOpen } else { RangeLimits::Closed }; let range = self.mk_range(Some(lhs), rhs, limits); @@ -737,8 +722,7 @@ impl<'a> Parser<'a> { expr_kind: fn(P, P) -> ExprKind, ) -> PResult<'a, P> { let mk_expr = |this: &mut Self, lhs: P, rhs: P| { - this.error_ambiguous_outer_attrs(&lhs, lhs_span, rhs.span); - this.mk_expr(lhs_span.to(rhs.span), expr_kind(lhs, rhs)) + this.mk_expr(this.mk_expr_sp(&lhs, lhs_span, rhs.span), expr_kind(lhs, rhs)) }; // Save the state of the parser before parsing type normally, in case there is a @@ -3829,6 +3813,16 @@ impl<'a> Parser<'a> { self.mk_expr(span, ExprKind::Err(guar)) } + /// Create expression span ensuring the span of the parent node + /// is larger than the span of lhs and rhs, including the attributes. + fn mk_expr_sp(&self, lhs: &P, lhs_span: Span, rhs_span: Span) -> Span { + lhs.attrs + .iter() + .find(|a| a.style == AttrStyle::Outer) + .map_or(lhs_span, |a| a.span) + .to(rhs_span) + } + fn collect_tokens_for_expr( &mut self, attrs: AttrWrapper, diff --git a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed index 84dac431169ab..05d5b3d10eaf8 100644 --- a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed +++ b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed @@ -16,7 +16,7 @@ fn foo( fn skip_on_statements() { #[rustfmt::skip] - { 5+3; } + 5+3; } #[rustfmt::skip] @@ -33,11 +33,11 @@ mod foo { #[clippy::msrv = "1.29"] fn msrv_1_29() { #[cfg_attr(rustfmt, rustfmt::skip)] - { 1+29; } + 1+29; } #[clippy::msrv = "1.30"] fn msrv_1_30() { #[rustfmt::skip] - { 1+30; } + 1+30; } diff --git a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs index 4ab5c70e13b5b..bc29e20210e8a 100644 --- a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs +++ b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs @@ -16,7 +16,7 @@ fn foo( fn skip_on_statements() { #[cfg_attr(rustfmt, rustfmt::skip)] - { 5+3; } + 5+3; } #[cfg_attr(rustfmt, rustfmt_skip)] @@ -33,11 +33,11 @@ mod foo { #[clippy::msrv = "1.29"] fn msrv_1_29() { #[cfg_attr(rustfmt, rustfmt::skip)] - { 1+29; } + 1+29; } #[clippy::msrv = "1.30"] fn msrv_1_30() { #[cfg_attr(rustfmt, rustfmt::skip)] - { 1+30; } + 1+30; } diff --git a/src/tools/rustfmt/tests/source/attrib.rs b/src/tools/rustfmt/tests/source/attrib.rs index fc13cd02b03ef..d45fba5522436 100644 --- a/src/tools/rustfmt/tests/source/attrib.rs +++ b/src/tools/rustfmt/tests/source/attrib.rs @@ -214,8 +214,8 @@ type Os = NoSource; // #3313 fn stmt_expr_attributes() { let foo ; - (#[must_use] - foo) = false ; + #[must_use] + foo = false ; } // #3509 diff --git a/src/tools/rustfmt/tests/target/attrib.rs b/src/tools/rustfmt/tests/target/attrib.rs index 7b3309676de2f..7e61f68d76a14 100644 --- a/src/tools/rustfmt/tests/target/attrib.rs +++ b/src/tools/rustfmt/tests/target/attrib.rs @@ -248,8 +248,8 @@ type Os = NoSource; // #3313 fn stmt_expr_attributes() { let foo; - (#[must_use] - foo) = false; + #[must_use] + foo = false; } // #3509 diff --git a/tests/pretty/ast-stmt-expr-attr.rs b/tests/pretty/ast-stmt-expr-attr.rs index 899f7173f704e..fd7272a1b1fd3 100644 --- a/tests/pretty/ast-stmt-expr-attr.rs +++ b/tests/pretty/ast-stmt-expr-attr.rs @@ -13,17 +13,17 @@ fn syntax() { let _ = #[attr] (); let _ = #[attr] (#[attr] 0,); let _ = #[attr] (#[attr] 0, 0); - let _ = (#[attr] 0) + #[attr] 0; - let _ = (#[attr] 0) / #[attr] 0; - let _ = (#[attr] 0) & #[attr] 0; - let _ = (#[attr] 0) % #[attr] 0; + let _ = #[attr] 0 + #[attr] 0; + let _ = #[attr] 0 / #[attr] 0; + let _ = #[attr] 0 & #[attr] 0; + let _ = #[attr] 0 % #[attr] 0; let _ = #[attr] (0 + 0); let _ = #[attr] !0; let _ = #[attr] -0; let _ = #[attr] false; let _ = #[attr] 0; let _ = #[attr] 'c'; - let _ = (#[attr] x) as Y; + let _ = #[attr] x as Y; let _ = #[attr] (x as Y); let _ = #[attr] while true { @@ -88,9 +88,9 @@ fn syntax() { let _ = (); foo }; - let _ = (#[attr] x) = y; + let _ = #[attr] x = y; let _ = #[attr] (x = y); - let _ = (#[attr] x) += y; + let _ = #[attr] x += y; let _ = #[attr] (x += y); let _ = #[attr] foo.bar; let _ = (#[attr] foo).bar; @@ -98,8 +98,8 @@ fn syntax() { let _ = (#[attr] foo).0; let _ = #[attr] foo[bar]; let _ = (#[attr] foo)[bar]; - let _ = (#[attr] 0)..#[attr] 0; - let _ = (#[attr] 0)..; + let _ = #[attr] 0..#[attr] 0; + let _ = #[attr] 0..; let _ = #[attr] (0..0); let _ = #[attr] (0..); let _ = #[attr] (..0); diff --git a/tests/pretty/stmt_expr_attributes.rs b/tests/pretty/stmt_expr_attributes.rs index 5eb7d2fcae36a..01a503ce7eeaf 100644 --- a/tests/pretty/stmt_expr_attributes.rs +++ b/tests/pretty/stmt_expr_attributes.rs @@ -147,13 +147,13 @@ fn _11() { let _ = #[rustc_dummy] (0); let _ = #[rustc_dummy] (0,); let _ = #[rustc_dummy] (0, 0); - let _ = (#[rustc_dummy] 0) + #[rustc_dummy] 0; + let _ = #[rustc_dummy] 0 + #[rustc_dummy] 0; let _ = #[rustc_dummy] !0; let _ = #[rustc_dummy] -0i32; let _ = #[rustc_dummy] false; let _ = #[rustc_dummy] 'c'; let _ = #[rustc_dummy] 0; - let _ = (#[rustc_dummy] 0) as usize; + let _ = #[rustc_dummy] 0 as usize; let _ = #[rustc_dummy] while false { #![rustc_dummy] @@ -213,8 +213,8 @@ fn _11() { #![rustc_dummy] }; let mut x = 0; - let _ = (#[rustc_dummy] x) = 15; - let _ = (#[rustc_dummy] x) += 15; + let _ = #[rustc_dummy] x = 15; + let _ = #[rustc_dummy] x += 15; let s = Foo { data: () }; let _ = #[rustc_dummy] s.data; let _ = (#[rustc_dummy] s).data; @@ -224,8 +224,8 @@ fn _11() { let v = vec!(0); let _ = #[rustc_dummy] v[0]; let _ = (#[rustc_dummy] v)[0]; - let _ = (#[rustc_dummy] 0)..#[rustc_dummy] 0; - let _ = (#[rustc_dummy] 0)..; + let _ = #[rustc_dummy] 0..#[rustc_dummy] 0; + let _ = #[rustc_dummy] 0..; let _ = #[rustc_dummy] (0..0); let _ = #[rustc_dummy] (0..); let _ = #[rustc_dummy] (..0); diff --git a/tests/ui/lint/unused/unused-doc-comments-edge-cases.rs b/tests/ui/lint/unused/unused-doc-comments-edge-cases.rs index 0f9eac93930bc..ba32fb566e83b 100644 --- a/tests/ui/lint/unused/unused-doc-comments-edge-cases.rs +++ b/tests/ui/lint/unused/unused-doc-comments-edge-cases.rs @@ -20,10 +20,10 @@ fn doc_comment_between_if_else(num: u8) -> bool { } fn doc_comment_on_expr(num: u8) -> bool { - (/// useless doc comment + /// useless doc comment //~^ ERROR: attributes on expressions are experimental //~| ERROR: unused doc comment - num) == 3 + num == 3 } fn doc_comment_on_expr_field() -> bool { diff --git a/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr b/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr index add85b2f5e043..55e4834e6707a 100644 --- a/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr +++ b/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr @@ -5,10 +5,10 @@ LL | else { | ^^^^ expected expression error[E0658]: attributes on expressions are experimental - --> $DIR/unused-doc-comments-edge-cases.rs:23:6 + --> $DIR/unused-doc-comments-edge-cases.rs:23:5 | -LL | (/// useless doc comment - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | /// useless doc comment + | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #15701 for more information = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable @@ -32,12 +32,12 @@ LL | #![deny(unused_doc_comments)] | ^^^^^^^^^^^^^^^^^^^ error: unused doc comment - --> $DIR/unused-doc-comments-edge-cases.rs:23:6 + --> $DIR/unused-doc-comments-edge-cases.rs:23:5 | -LL | (/// useless doc comment - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | /// useless doc comment + | ^^^^^^^^^^^^^^^^^^^^^^^ ... -LL | num) == 3 +LL | num == 3 | --- rustdoc does not generate documentation for expressions | = help: use `//` for a plain comment diff --git a/tests/ui/parser/attribute/attr-binary-expr-ambigous.fixed b/tests/ui/parser/attribute/attr-binary-expr-ambigous.fixed deleted file mode 100644 index aae71ede77132..0000000000000 --- a/tests/ui/parser/attribute/attr-binary-expr-ambigous.fixed +++ /dev/null @@ -1,15 +0,0 @@ -//@ run-rustfix -#![feature(stmt_expr_attributes)] -#![allow(unused_assignments, unused_attributes)] - -fn main() { - let mut x = (#[deprecated] 1) + 2; //~ ERROR ambiguous - - (#[deprecated] x) = 4; //~ ERROR ambiguous - - x = (#[deprecated] 5) as i32; //~ ERROR ambiguous - - let _r = (#[deprecated] 1)..6; //~ ERROR ambiguous - - println!("{}", x); -} diff --git a/tests/ui/parser/attribute/attr-binary-expr-ambigous.rs b/tests/ui/parser/attribute/attr-binary-expr-ambigous.rs deleted file mode 100644 index 613e01d743bdd..0000000000000 --- a/tests/ui/parser/attribute/attr-binary-expr-ambigous.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ run-rustfix -#![feature(stmt_expr_attributes)] -#![allow(unused_assignments, unused_attributes)] - -fn main() { - let mut x = #[deprecated] 1 + 2; //~ ERROR ambiguous - - #[deprecated] x = 4; //~ ERROR ambiguous - - x = #[deprecated] 5 as i32; //~ ERROR ambiguous - - let _r = #[deprecated] 1..6; //~ ERROR ambiguous - - println!("{}", x); -} diff --git a/tests/ui/parser/attribute/attr-binary-expr-ambigous.stderr b/tests/ui/parser/attribute/attr-binary-expr-ambigous.stderr deleted file mode 100644 index 0430570fd49d9..0000000000000 --- a/tests/ui/parser/attribute/attr-binary-expr-ambigous.stderr +++ /dev/null @@ -1,46 +0,0 @@ -error: ambiguous outer attributes - --> $DIR/attr-binary-expr-ambigous.rs:6:17 - | -LL | let mut x = #[deprecated] 1 + 2; - | ^^^^^^^^^^^^^^^^^^^ - | -help: wrap the expression in parentheses - | -LL | let mut x = (#[deprecated] 1) + 2; - | + + - -error: ambiguous outer attributes - --> $DIR/attr-binary-expr-ambigous.rs:8:5 - | -LL | #[deprecated] x = 4; - | ^^^^^^^^^^^^^^^^^^^ - | -help: wrap the expression in parentheses - | -LL | (#[deprecated] x) = 4; - | + + - -error: ambiguous outer attributes - --> $DIR/attr-binary-expr-ambigous.rs:10:9 - | -LL | x = #[deprecated] 5 as i32; - | ^^^^^^^^^^^^^^^^^^^^^^ - | -help: wrap the expression in parentheses - | -LL | x = (#[deprecated] 5) as i32; - | + + - -error: ambiguous outer attributes - --> $DIR/attr-binary-expr-ambigous.rs:12:14 - | -LL | let _r = #[deprecated] 1..6; - | ^^^^^^^^^^^^^^^^^^ - | -help: wrap the expression in parentheses - | -LL | let _r = (#[deprecated] 1)..6; - | + + - -error: aborting due to 4 previous errors - diff --git a/tests/ui/proc-macro/issue-81555.rs b/tests/ui/proc-macro/issue-81555.rs index b337ab7ce37db..7a61a31952f41 100644 --- a/tests/ui/proc-macro/issue-81555.rs +++ b/tests/ui/proc-macro/issue-81555.rs @@ -10,5 +10,6 @@ use test_macros::identity_attr; fn main() { let _x; let y = (); - (#[identity_attr] _x) = y; + #[identity_attr] + _x = y; }