Skip to content

Commit 76b40d2

Browse files
authored
Rollup merge of #82419 - petrochenkov:inertord, r=Aaron1011
expand: Preserve order of inert attributes during expansion Fixes #67839 Fixes #81871 r? `````@Aaron1011`````
2 parents 2d175bb + fc9d578 commit 76b40d2

7 files changed

+126
-47
lines changed

compiler/rustc_expand/src/expand.rs

+14-9
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,8 @@ pub enum InvocationKind {
301301
},
302302
Attr {
303303
attr: ast::Attribute,
304+
// Re-insertion position for inert attributes.
305+
pos: usize,
304306
item: Annotatable,
305307
// Required for resolving derive helper attributes.
306308
derives: Vec<Path>,
@@ -690,7 +692,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
690692
}
691693
_ => unreachable!(),
692694
},
693-
InvocationKind::Attr { attr, mut item, derives } => match ext {
695+
InvocationKind::Attr { attr, pos, mut item, derives } => match ext {
694696
SyntaxExtensionKind::Attr(expander) => {
695697
self.gate_proc_macro_input(&item);
696698
self.gate_proc_macro_attr_item(span, &item);
@@ -721,7 +723,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
721723
ExpandResult::Retry(item) => {
722724
// Reassemble the original invocation for retrying.
723725
return ExpandResult::Retry(Invocation {
724-
kind: InvocationKind::Attr { attr, item, derives },
726+
kind: InvocationKind::Attr { attr, pos, item, derives },
725727
..invoc
726728
});
727729
}
@@ -739,7 +741,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
739741
if *mark_used {
740742
self.cx.sess.mark_attr_used(&attr);
741743
}
742-
item.visit_attrs(|attrs| attrs.push(attr));
744+
item.visit_attrs(|attrs| attrs.insert(pos, attr));
743745
fragment_kind.expect_from_annotatables(iter::once(item))
744746
}
745747
_ => unreachable!(),
@@ -1000,17 +1002,20 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
10001002

10011003
fn collect_attr(
10021004
&mut self,
1003-
(attr, derives): (ast::Attribute, Vec<Path>),
1005+
(attr, pos, derives): (ast::Attribute, usize, Vec<Path>),
10041006
item: Annotatable,
10051007
kind: AstFragmentKind,
10061008
) -> AstFragment {
1007-
self.collect(kind, InvocationKind::Attr { attr, item, derives })
1009+
self.collect(kind, InvocationKind::Attr { attr, pos, item, derives })
10081010
}
10091011

10101012
/// If `item` is an attribute invocation, remove the attribute and return it together with
1011-
/// derives following it. We have to collect the derives in order to resolve legacy derive
1012-
/// helpers (helpers written before derives that introduce them).
1013-
fn take_first_attr(&mut self, item: &mut impl HasAttrs) -> Option<(ast::Attribute, Vec<Path>)> {
1013+
/// its position and derives following it. We have to collect the derives in order to resolve
1014+
/// legacy derive helpers (helpers written before derives that introduce them).
1015+
fn take_first_attr(
1016+
&mut self,
1017+
item: &mut impl HasAttrs,
1018+
) -> Option<(ast::Attribute, usize, Vec<Path>)> {
10141019
let mut attr = None;
10151020

10161021
item.visit_attrs(|attrs| {
@@ -1033,7 +1038,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
10331038
})
10341039
.collect();
10351040

1036-
(attr, following_derives)
1041+
(attr, attr_pos, following_derives)
10371042
})
10381043
});
10391044

src/test/ui/proc-macro/auxiliary/test-macros.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#![crate_type = "proc-macro"]
88

99
extern crate proc_macro;
10-
use proc_macro::TokenStream;
10+
use proc_macro::{TokenStream, TokenTree};
1111

1212
// Macro that return empty token stream.
1313

@@ -80,6 +80,10 @@ pub fn recollect_derive(input: TokenStream) -> TokenStream {
8080
// Macros that print their input in the original and re-collected forms (if they differ).
8181

8282
fn print_helper(input: TokenStream, kind: &str) -> TokenStream {
83+
print_helper_ext(input, kind, true)
84+
}
85+
86+
fn print_helper_ext(input: TokenStream, kind: &str, debug: bool) -> TokenStream {
8387
let input_display = format!("{}", input);
8488
let input_debug = format!("{:#?}", input);
8589
let recollected = input.into_iter().collect();
@@ -89,9 +93,11 @@ fn print_helper(input: TokenStream, kind: &str) -> TokenStream {
8993
if recollected_display != input_display {
9094
println!("PRINT-{} RE-COLLECTED (DISPLAY): {}", kind, recollected_display);
9195
}
92-
println!("PRINT-{} INPUT (DEBUG): {}", kind, input_debug);
93-
if recollected_debug != input_debug {
94-
println!("PRINT-{} RE-COLLECTED (DEBUG): {}", kind, recollected_debug);
96+
if debug {
97+
println!("PRINT-{} INPUT (DEBUG): {}", kind, input_debug);
98+
if recollected_debug != input_debug {
99+
println!("PRINT-{} RE-COLLECTED (DEBUG): {}", kind, recollected_debug);
100+
}
95101
}
96102
recollected
97103
}
@@ -108,8 +114,12 @@ pub fn print_bang_consume(input: TokenStream) -> TokenStream {
108114
}
109115

110116
#[proc_macro_attribute]
111-
pub fn print_attr(_: TokenStream, input: TokenStream) -> TokenStream {
112-
print_helper(input, "ATTR")
117+
pub fn print_attr(args: TokenStream, input: TokenStream) -> TokenStream {
118+
let debug = match &args.into_iter().collect::<Vec<_>>()[..] {
119+
[TokenTree::Ident(ident)] if ident.to_string() == "nodebug" => false,
120+
_ => true,
121+
};
122+
print_helper_ext(input, "ATTR", debug)
113123
}
114124

115125
#[proc_macro_attribute]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// aux-build:test-macros.rs
2+
3+
#![dummy] //~ ERROR cannot find attribute `dummy` in this scope
4+
5+
#[macro_use]
6+
extern crate test_macros;
7+
8+
#[derive(Empty)] //~ ERROR cannot determine resolution for the attribute macro `derive`
9+
#[empty_helper] //~ ERROR cannot find attribute `empty_helper` in this scope
10+
struct Foo {}
11+
12+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error: cannot find attribute `dummy` in this scope
2+
--> $DIR/derive-helper-legacy-spurious.rs:3:4
3+
|
4+
LL | #![dummy]
5+
| ^^^^^
6+
7+
error: cannot determine resolution for the attribute macro `derive`
8+
--> $DIR/derive-helper-legacy-spurious.rs:8:3
9+
|
10+
LL | #[derive(Empty)]
11+
| ^^^^^^
12+
|
13+
= note: import resolution is stuck, try simplifying macro imports
14+
15+
error: cannot find attribute `empty_helper` in this scope
16+
--> $DIR/derive-helper-legacy-spurious.rs:9:3
17+
|
18+
LL | #[empty_helper]
19+
| ^^^^^^^^^^^^
20+
21+
error: aborting due to 3 previous errors
22+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Order of inert attributes, both built-in and custom is preserved during expansion.
2+
3+
// check-pass
4+
// compile-flags: -Z span-debug
5+
// aux-build:test-macros.rs
6+
7+
#![no_std] // Don't load unnecessary hygiene information from std
8+
extern crate std;
9+
10+
#[macro_use]
11+
extern crate test_macros;
12+
13+
/// 1
14+
#[rustfmt::attr2]
15+
#[doc = "3"]
16+
#[print_attr(nodebug)]
17+
#[doc = "4"]
18+
#[rustfmt::attr5]
19+
/// 6
20+
#[print_attr(nodebug)]
21+
struct S;
22+
23+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
PRINT-ATTR INPUT (DISPLAY): /// 1
2+
#[rustfmt :: attr2] #[doc = "3"] #[doc = "4"] #[rustfmt :: attr5] /// 6
3+
#[print_attr(nodebug)] struct S ;
4+
PRINT-ATTR RE-COLLECTED (DISPLAY): #[doc = " 1"] #[rustfmt :: attr2] #[doc = "3"] #[doc = "4"]
5+
#[rustfmt :: attr5] #[doc = " 6"] #[print_attr(nodebug)] struct S ;
6+
PRINT-ATTR INPUT (DISPLAY): #[doc = " 1"] #[rustfmt :: attr2] #[doc = "3"] #[doc = "4"]
7+
#[rustfmt :: attr5] #[doc = " 6"] struct S ;

src/test/ui/proc-macro/issue-75930-derive-cfg.stdout

+32-32
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
PRINT-ATTR INPUT (DISPLAY): #[allow(dead_code)] #[derive(Print)] #[print_helper(b)] #[print_helper(a)]
1+
PRINT-ATTR INPUT (DISPLAY): #[print_helper(a)] #[allow(dead_code)] #[derive(Print)] #[print_helper(b)]
22
struct Foo < #[cfg(FALSE)] A, B >
33
{
44
#[cfg(FALSE)] first : String, #[cfg_attr(FALSE, deny(warnings))] second :
@@ -23,6 +23,31 @@ struct Foo < #[cfg(FALSE)] A, B >
2323
}], #[print_helper(d)] fourth : B
2424
}
2525
PRINT-ATTR INPUT (DEBUG): TokenStream [
26+
Punct {
27+
ch: '#',
28+
spacing: Alone,
29+
span: $DIR/issue-75930-derive-cfg.rs:16:1: 16:2 (#0),
30+
},
31+
Group {
32+
delimiter: Bracket,
33+
stream: TokenStream [
34+
Ident {
35+
ident: "print_helper",
36+
span: $DIR/issue-75930-derive-cfg.rs:16:3: 16:15 (#0),
37+
},
38+
Group {
39+
delimiter: Parenthesis,
40+
stream: TokenStream [
41+
Ident {
42+
ident: "a",
43+
span: $DIR/issue-75930-derive-cfg.rs:16:16: 16:17 (#0),
44+
},
45+
],
46+
span: $DIR/issue-75930-derive-cfg.rs:16:15: 16:18 (#0),
47+
},
48+
],
49+
span: $DIR/issue-75930-derive-cfg.rs:16:2: 16:19 (#0),
50+
},
2651
Punct {
2752
ch: '#',
2853
spacing: Alone,
@@ -98,31 +123,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
98123
],
99124
span: $DIR/issue-75930-derive-cfg.rs:21:2: 21:19 (#0),
100125
},
101-
Punct {
102-
ch: '#',
103-
spacing: Alone,
104-
span: $DIR/issue-75930-derive-cfg.rs:16:1: 16:2 (#0),
105-
},
106-
Group {
107-
delimiter: Bracket,
108-
stream: TokenStream [
109-
Ident {
110-
ident: "print_helper",
111-
span: $DIR/issue-75930-derive-cfg.rs:16:3: 16:15 (#0),
112-
},
113-
Group {
114-
delimiter: Parenthesis,
115-
stream: TokenStream [
116-
Ident {
117-
ident: "a",
118-
span: $DIR/issue-75930-derive-cfg.rs:16:16: 16:17 (#0),
119-
},
120-
],
121-
span: $DIR/issue-75930-derive-cfg.rs:16:15: 16:18 (#0),
122-
},
123-
],
124-
span: $DIR/issue-75930-derive-cfg.rs:16:2: 16:19 (#0),
125-
},
126126
Ident {
127127
ident: "struct",
128128
span: $DIR/issue-75930-derive-cfg.rs:22:1: 22:7 (#0),
@@ -1194,7 +1194,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
11941194
span: $DIR/issue-75930-derive-cfg.rs:22:32: 65:2 (#0),
11951195
},
11961196
]
1197-
PRINT-DERIVE INPUT (DISPLAY): #[allow(dead_code)] #[print_helper(b)] #[print_helper(a)] struct Foo < B >
1197+
PRINT-DERIVE INPUT (DISPLAY): #[print_helper(a)] #[allow(dead_code)] #[print_helper(b)] struct Foo < B >
11981198
{
11991199
second : bool, third :
12001200
[u8 ;
@@ -1217,14 +1217,14 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
12171217
delimiter: Bracket,
12181218
stream: TokenStream [
12191219
Ident {
1220-
ident: "allow",
1220+
ident: "print_helper",
12211221
span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0),
12221222
},
12231223
Group {
12241224
delimiter: Parenthesis,
12251225
stream: TokenStream [
12261226
Ident {
1227-
ident: "dead_code",
1227+
ident: "a",
12281228
span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0),
12291229
},
12301230
],
@@ -1242,14 +1242,14 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
12421242
delimiter: Bracket,
12431243
stream: TokenStream [
12441244
Ident {
1245-
ident: "print_helper",
1245+
ident: "allow",
12461246
span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0),
12471247
},
12481248
Group {
12491249
delimiter: Parenthesis,
12501250
stream: TokenStream [
12511251
Ident {
1252-
ident: "b",
1252+
ident: "dead_code",
12531253
span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0),
12541254
},
12551255
],
@@ -1274,7 +1274,7 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
12741274
delimiter: Parenthesis,
12751275
stream: TokenStream [
12761276
Ident {
1277-
ident: "a",
1277+
ident: "b",
12781278
span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0),
12791279
},
12801280
],

0 commit comments

Comments
 (0)