diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 5a4737842f0..10c19ea105e 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -301,6 +301,8 @@ pub enum InvocationKind { }, Attr { attr: ast::Attribute, + // Re-insertion position for inert attributes. + pos: usize, item: Annotatable, // Required for resolving derive helper attributes. derives: Vec, @@ -690,7 +692,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } _ => unreachable!(), }, - InvocationKind::Attr { attr, mut item, derives } => match ext { + InvocationKind::Attr { attr, pos, mut item, derives } => match ext { SyntaxExtensionKind::Attr(expander) => { self.gate_proc_macro_input(&item); self.gate_proc_macro_attr_item(span, &item); @@ -721,7 +723,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { ExpandResult::Retry(item) => { // Reassemble the original invocation for retrying. return ExpandResult::Retry(Invocation { - kind: InvocationKind::Attr { attr, item, derives }, + kind: InvocationKind::Attr { attr, pos, item, derives }, ..invoc }); } @@ -739,7 +741,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { if *mark_used { self.cx.sess.mark_attr_used(&attr); } - item.visit_attrs(|attrs| attrs.push(attr)); + item.visit_attrs(|attrs| attrs.insert(pos, attr)); fragment_kind.expect_from_annotatables(iter::once(item)) } _ => unreachable!(), @@ -1000,17 +1002,20 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { fn collect_attr( &mut self, - (attr, derives): (ast::Attribute, Vec), + (attr, pos, derives): (ast::Attribute, usize, Vec), item: Annotatable, kind: AstFragmentKind, ) -> AstFragment { - self.collect(kind, InvocationKind::Attr { attr, item, derives }) + self.collect(kind, InvocationKind::Attr { attr, pos, item, derives }) } /// If `item` is an attribute invocation, remove the attribute and return it together with - /// derives following it. We have to collect the derives in order to resolve legacy derive - /// helpers (helpers written before derives that introduce them). - fn take_first_attr(&mut self, item: &mut impl HasAttrs) -> Option<(ast::Attribute, Vec)> { + /// its position and derives following it. We have to collect the derives in order to resolve + /// legacy derive helpers (helpers written before derives that introduce them). + fn take_first_attr( + &mut self, + item: &mut impl HasAttrs, + ) -> Option<(ast::Attribute, usize, Vec)> { let mut attr = None; item.visit_attrs(|attrs| { @@ -1033,7 +1038,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { }) .collect(); - (attr, following_derives) + (attr, attr_pos, following_derives) }) }); diff --git a/src/test/ui/proc-macro/derive-helper-legacy-spurious.rs b/src/test/ui/proc-macro/derive-helper-legacy-spurious.rs index 8180aab0caa..4a7e48eed46 100644 --- a/src/test/ui/proc-macro/derive-helper-legacy-spurious.rs +++ b/src/test/ui/proc-macro/derive-helper-legacy-spurious.rs @@ -6,8 +6,7 @@ extern crate test_macros; #[derive(Empty)] //~ ERROR cannot determine resolution for the attribute macro `derive` -#[empty_helper] //~ WARN derive helper attribute is used before it is introduced - //~| WARN this was previously accepted +#[empty_helper] //~ ERROR cannot find attribute `empty_helper` in this scope struct Foo {} fn main() {} diff --git a/src/test/ui/proc-macro/derive-helper-legacy-spurious.stderr b/src/test/ui/proc-macro/derive-helper-legacy-spurious.stderr index 96754fed993..fd1ed8a3d0f 100644 --- a/src/test/ui/proc-macro/derive-helper-legacy-spurious.stderr +++ b/src/test/ui/proc-macro/derive-helper-legacy-spurious.stderr @@ -12,17 +12,11 @@ LL | #[derive(Empty)] | = note: import resolution is stuck, try simplifying macro imports -warning: derive helper attribute is used before it is introduced +error: cannot find attribute `empty_helper` in this scope --> $DIR/derive-helper-legacy-spurious.rs:9:3 | -LL | #[derive(Empty)] - | ----- the attribute is introduced here LL | #[empty_helper] | ^^^^^^^^^^^^ - | - = note: `#[warn(legacy_derive_helpers)]` on by default - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #79202 -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 3 previous errors diff --git a/src/test/ui/proc-macro/inert-attribute-order.stdout b/src/test/ui/proc-macro/inert-attribute-order.stdout index 7c0620b50b3..cc215545952 100644 --- a/src/test/ui/proc-macro/inert-attribute-order.stdout +++ b/src/test/ui/proc-macro/inert-attribute-order.stdout @@ -1,7 +1,7 @@ PRINT-ATTR INPUT (DISPLAY): /// 1 -#[doc = "3"] #[doc = "4"] #[rustfmt :: attr5] /// 6 -#[print_attr(nodebug)] #[rustfmt :: attr2] struct S ; -PRINT-ATTR RE-COLLECTED (DISPLAY): #[doc = " 1"] #[doc = "3"] #[doc = "4"] #[rustfmt :: attr5] #[doc = " 6"] -#[print_attr(nodebug)] #[rustfmt :: attr2] struct S ; -PRINT-ATTR INPUT (DISPLAY): #[doc = " 1"] #[doc = "3"] #[doc = "4"] #[doc = " 6"] #[rustfmt :: attr2] -#[rustfmt :: attr5] struct S ; +#[rustfmt :: attr2] #[doc = "3"] #[doc = "4"] #[rustfmt :: attr5] /// 6 +#[print_attr(nodebug)] struct S ; +PRINT-ATTR RE-COLLECTED (DISPLAY): #[doc = " 1"] #[rustfmt :: attr2] #[doc = "3"] #[doc = "4"] +#[rustfmt :: attr5] #[doc = " 6"] #[print_attr(nodebug)] struct S ; +PRINT-ATTR INPUT (DISPLAY): #[doc = " 1"] #[rustfmt :: attr2] #[doc = "3"] #[doc = "4"] +#[rustfmt :: attr5] #[doc = " 6"] struct S ; diff --git a/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout b/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout index 19aa4dfb60e..15e63c20eb9 100644 --- a/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout +++ b/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout @@ -1,4 +1,4 @@ -PRINT-ATTR INPUT (DISPLAY): #[allow(dead_code)] #[derive(Print)] #[print_helper(b)] #[print_helper(a)] +PRINT-ATTR INPUT (DISPLAY): #[print_helper(a)] #[allow(dead_code)] #[derive(Print)] #[print_helper(b)] struct Foo < #[cfg(FALSE)] A, B > { #[cfg(FALSE)] first : String, #[cfg_attr(FALSE, deny(warnings))] second : @@ -23,6 +23,31 @@ struct Foo < #[cfg(FALSE)] A, B > }], #[print_helper(d)] fourth : B } PRINT-ATTR INPUT (DEBUG): TokenStream [ + Punct { + ch: '#', + spacing: Alone, + span: $DIR/issue-75930-derive-cfg.rs:16:1: 16:2 (#0), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "print_helper", + span: $DIR/issue-75930-derive-cfg.rs:16:3: 16:15 (#0), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "a", + span: $DIR/issue-75930-derive-cfg.rs:16:16: 16:17 (#0), + }, + ], + span: $DIR/issue-75930-derive-cfg.rs:16:15: 16:18 (#0), + }, + ], + span: $DIR/issue-75930-derive-cfg.rs:16:2: 16:19 (#0), + }, Punct { ch: '#', spacing: Alone, @@ -98,31 +123,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ ], span: $DIR/issue-75930-derive-cfg.rs:21:2: 21:19 (#0), }, - Punct { - ch: '#', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:16:1: 16:2 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "print_helper", - span: $DIR/issue-75930-derive-cfg.rs:16:3: 16:15 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "a", - span: $DIR/issue-75930-derive-cfg.rs:16:16: 16:17 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:16:15: 16:18 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:16:2: 16:19 (#0), - }, Ident { ident: "struct", span: $DIR/issue-75930-derive-cfg.rs:22:1: 22:7 (#0), @@ -1194,7 +1194,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ span: $DIR/issue-75930-derive-cfg.rs:22:32: 65:2 (#0), }, ] -PRINT-DERIVE INPUT (DISPLAY): #[allow(dead_code)] #[print_helper(b)] #[print_helper(a)] struct Foo < B > +PRINT-DERIVE INPUT (DISPLAY): #[print_helper(a)] #[allow(dead_code)] #[print_helper(b)] struct Foo < B > { second : bool, third : [u8 ; @@ -1208,6 +1208,31 @@ PRINT-DERIVE INPUT (DISPLAY): #[allow(dead_code)] #[print_helper(b)] #[print_hel }], #[print_helper(d)] fourth : B, } PRINT-DERIVE INPUT (DEBUG): TokenStream [ + Punct { + ch: '#', + spacing: Alone, + span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "print_helper", + span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "a", + span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0), + }, + ], + span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0), + }, + ], + span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0), + }, Punct { ch: '#', spacing: Alone, @@ -1258,31 +1283,6 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ ], span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0), }, - Punct { - ch: '#', - spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "print_helper", - span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "a", - span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0), - }, - ], - span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0), - }, Ident { ident: "struct", span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0),