expand: Preserve order of inert attributes during expansion
This commit is contained in:
parent
c02d21033d
commit
fc9d578bc5
|
@ -301,6 +301,8 @@ pub enum InvocationKind {
|
||||||
},
|
},
|
||||||
Attr {
|
Attr {
|
||||||
attr: ast::Attribute,
|
attr: ast::Attribute,
|
||||||
|
// Re-insertion position for inert attributes.
|
||||||
|
pos: usize,
|
||||||
item: Annotatable,
|
item: Annotatable,
|
||||||
// Required for resolving derive helper attributes.
|
// Required for resolving derive helper attributes.
|
||||||
derives: Vec<Path>,
|
derives: Vec<Path>,
|
||||||
|
@ -690,7 +692,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
InvocationKind::Attr { attr, mut item, derives } => match ext {
|
InvocationKind::Attr { attr, pos, mut item, derives } => match ext {
|
||||||
SyntaxExtensionKind::Attr(expander) => {
|
SyntaxExtensionKind::Attr(expander) => {
|
||||||
self.gate_proc_macro_input(&item);
|
self.gate_proc_macro_input(&item);
|
||||||
self.gate_proc_macro_attr_item(span, &item);
|
self.gate_proc_macro_attr_item(span, &item);
|
||||||
|
@ -721,7 +723,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
ExpandResult::Retry(item) => {
|
ExpandResult::Retry(item) => {
|
||||||
// Reassemble the original invocation for retrying.
|
// Reassemble the original invocation for retrying.
|
||||||
return ExpandResult::Retry(Invocation {
|
return ExpandResult::Retry(Invocation {
|
||||||
kind: InvocationKind::Attr { attr, item, derives },
|
kind: InvocationKind::Attr { attr, pos, item, derives },
|
||||||
..invoc
|
..invoc
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -739,7 +741,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
if *mark_used {
|
if *mark_used {
|
||||||
self.cx.sess.mark_attr_used(&attr);
|
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))
|
fragment_kind.expect_from_annotatables(iter::once(item))
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
@ -1000,17 +1002,20 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||||
|
|
||||||
fn collect_attr(
|
fn collect_attr(
|
||||||
&mut self,
|
&mut self,
|
||||||
(attr, derives): (ast::Attribute, Vec<Path>),
|
(attr, pos, derives): (ast::Attribute, usize, Vec<Path>),
|
||||||
item: Annotatable,
|
item: Annotatable,
|
||||||
kind: AstFragmentKind,
|
kind: AstFragmentKind,
|
||||||
) -> AstFragment {
|
) -> 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
|
/// 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
|
/// its position and derives following it. We have to collect the derives in order to resolve
|
||||||
/// helpers (helpers written before derives that introduce them).
|
/// legacy derive helpers (helpers written before derives that introduce them).
|
||||||
fn take_first_attr(&mut self, item: &mut impl HasAttrs) -> Option<(ast::Attribute, Vec<Path>)> {
|
fn take_first_attr(
|
||||||
|
&mut self,
|
||||||
|
item: &mut impl HasAttrs,
|
||||||
|
) -> Option<(ast::Attribute, usize, Vec<Path>)> {
|
||||||
let mut attr = None;
|
let mut attr = None;
|
||||||
|
|
||||||
item.visit_attrs(|attrs| {
|
item.visit_attrs(|attrs| {
|
||||||
|
@ -1033,7 +1038,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
(attr, following_derives)
|
(attr, attr_pos, following_derives)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,7 @@
|
||||||
extern crate test_macros;
|
extern crate test_macros;
|
||||||
|
|
||||||
#[derive(Empty)] //~ ERROR cannot determine resolution for the attribute macro `derive`
|
#[derive(Empty)] //~ ERROR cannot determine resolution for the attribute macro `derive`
|
||||||
#[empty_helper] //~ WARN derive helper attribute is used before it is introduced
|
#[empty_helper] //~ ERROR cannot find attribute `empty_helper` in this scope
|
||||||
//~| WARN this was previously accepted
|
|
||||||
struct Foo {}
|
struct Foo {}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -12,17 +12,11 @@ LL | #[derive(Empty)]
|
||||||
|
|
|
|
||||||
= note: import resolution is stuck, try simplifying macro imports
|
= 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
|
--> $DIR/derive-helper-legacy-spurious.rs:9:3
|
||||||
|
|
|
|
||||||
LL | #[derive(Empty)]
|
|
||||||
| ----- the attribute is introduced here
|
|
||||||
LL | #[empty_helper]
|
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 <https://github.com/rust-lang/rust/issues/79202>
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors; 1 warning emitted
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
PRINT-ATTR INPUT (DISPLAY): /// 1
|
PRINT-ATTR INPUT (DISPLAY): /// 1
|
||||||
#[doc = "3"] #[doc = "4"] #[rustfmt :: attr5] /// 6
|
#[rustfmt :: attr2] #[doc = "3"] #[doc = "4"] #[rustfmt :: attr5] /// 6
|
||||||
#[print_attr(nodebug)] #[rustfmt :: attr2] struct S ;
|
#[print_attr(nodebug)] struct S ;
|
||||||
PRINT-ATTR RE-COLLECTED (DISPLAY): #[doc = " 1"] #[doc = "3"] #[doc = "4"] #[rustfmt :: attr5] #[doc = " 6"]
|
PRINT-ATTR RE-COLLECTED (DISPLAY): #[doc = " 1"] #[rustfmt :: attr2] #[doc = "3"] #[doc = "4"]
|
||||||
#[print_attr(nodebug)] #[rustfmt :: attr2] struct S ;
|
#[rustfmt :: attr5] #[doc = " 6"] #[print_attr(nodebug)] struct S ;
|
||||||
PRINT-ATTR INPUT (DISPLAY): #[doc = " 1"] #[doc = "3"] #[doc = "4"] #[doc = " 6"] #[rustfmt :: attr2]
|
PRINT-ATTR INPUT (DISPLAY): #[doc = " 1"] #[rustfmt :: attr2] #[doc = "3"] #[doc = "4"]
|
||||||
#[rustfmt :: attr5] struct S ;
|
#[rustfmt :: attr5] #[doc = " 6"] struct S ;
|
||||||
|
|
|
@ -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 >
|
struct Foo < #[cfg(FALSE)] A, B >
|
||||||
{
|
{
|
||||||
#[cfg(FALSE)] first : String, #[cfg_attr(FALSE, deny(warnings))] second :
|
#[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_helper(d)] fourth : B
|
||||||
}
|
}
|
||||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
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 {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
spacing: Alone,
|
spacing: Alone,
|
||||||
|
@ -98,31 +123,6 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||||
],
|
],
|
||||||
span: $DIR/issue-75930-derive-cfg.rs:21:2: 21:19 (#0),
|
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 {
|
||||||
ident: "struct",
|
ident: "struct",
|
||||||
span: $DIR/issue-75930-derive-cfg.rs:22:1: 22:7 (#0),
|
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),
|
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 :
|
second : bool, third :
|
||||||
[u8 ;
|
[u8 ;
|
||||||
|
@ -1208,6 +1208,31 @@ PRINT-DERIVE INPUT (DISPLAY): #[allow(dead_code)] #[print_helper(b)] #[print_hel
|
||||||
}], #[print_helper(d)] fourth : B,
|
}], #[print_helper(d)] fourth : B,
|
||||||
}
|
}
|
||||||
PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
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 {
|
Punct {
|
||||||
ch: '#',
|
ch: '#',
|
||||||
spacing: Alone,
|
spacing: Alone,
|
||||||
|
@ -1258,31 +1283,6 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
||||||
],
|
],
|
||||||
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,
|
|
||||||
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 {
|
||||||
ident: "struct",
|
ident: "struct",
|
||||||
span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0),
|
span: $DIR/issue-75930-derive-cfg.rs:22:1: 65:2 (#0),
|
||||||
|
|
Loading…
Reference in a new issue