Expand derive invocations in left-to-right order
While derives were being collected in left-to-order order, the corresponding `Invocation`s were being pushed in the wrong order.
This commit is contained in:
parent
2e495d2e84
commit
21e6cc19fe
@ -491,6 +491,7 @@ pub fn fully_expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragm
|
||||
let fragment_kind = invoc.fragment_kind;
|
||||
let (expanded_fragment, new_invocations) = match self.expand_invoc(invoc, &ext.kind) {
|
||||
ExpandResult::Ready(fragment) => {
|
||||
let mut derive_invocations = Vec::new();
|
||||
let derive_placeholders = self
|
||||
.cx
|
||||
.resolver
|
||||
@ -512,14 +513,14 @@ enum AnnotatableRef<'a> {
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
invocations.reserve(derives.len());
|
||||
derive_invocations.reserve(derives.len());
|
||||
derives
|
||||
.into_iter()
|
||||
.map(|(path, _exts)| {
|
||||
// FIXME: Consider using the derive resolutions (`_exts`)
|
||||
// instead of enqueuing the derives to be resolved again later.
|
||||
let expn_id = ExpnId::fresh(None);
|
||||
invocations.push((
|
||||
derive_invocations.push((
|
||||
Invocation {
|
||||
kind: InvocationKind::Derive {
|
||||
path,
|
||||
@ -546,7 +547,12 @@ enum AnnotatableRef<'a> {
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
self.collect_invocations(fragment, &derive_placeholders)
|
||||
let (fragment, collected_invocations) =
|
||||
self.collect_invocations(fragment, &derive_placeholders);
|
||||
// We choose to expand any derive invocations associated with this macro invocation
|
||||
// *before* any macro invocations collected from the output fragment
|
||||
derive_invocations.extend(collected_invocations);
|
||||
(fragment, derive_invocations)
|
||||
}
|
||||
ExpandResult::Retry(invoc) => {
|
||||
if force {
|
||||
|
@ -10,6 +10,18 @@ error[E0433]: failed to resolve: could not find `RustcDecodable` in `core`
|
||||
LL | core::RustcDecodable,
|
||||
| ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core`
|
||||
|
||||
error[E0433]: failed to resolve: could not find `RustcDecodable` in `core`
|
||||
--> $DIR/builtin-std-paths-fail.rs:2:11
|
||||
|
|
||||
LL | core::RustcDecodable,
|
||||
| ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core`
|
||||
|
||||
error[E0433]: failed to resolve: could not find `RustcDecodable` in `core`
|
||||
--> $DIR/builtin-std-paths-fail.rs:4:11
|
||||
|
|
||||
LL | core::RustcDecodable,
|
||||
| ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core`
|
||||
|
||||
error[E0433]: failed to resolve: could not find `bench` in `core`
|
||||
--> $DIR/builtin-std-paths-fail.rs:7:9
|
||||
|
|
||||
@ -34,17 +46,17 @@ error[E0433]: failed to resolve: could not find `test` in `core`
|
||||
LL | #[core::test]
|
||||
| ^^^^ could not find `test` in `core`
|
||||
|
||||
error[E0433]: failed to resolve: could not find `RustcDecodable` in `core`
|
||||
--> $DIR/builtin-std-paths-fail.rs:4:11
|
||||
error[E0433]: failed to resolve: could not find `RustcDecodable` in `std`
|
||||
--> $DIR/builtin-std-paths-fail.rs:14:10
|
||||
|
|
||||
LL | core::RustcDecodable,
|
||||
| ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core`
|
||||
LL | std::RustcDecodable,
|
||||
| ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std`
|
||||
|
||||
error[E0433]: failed to resolve: could not find `RustcDecodable` in `core`
|
||||
--> $DIR/builtin-std-paths-fail.rs:2:11
|
||||
error[E0433]: failed to resolve: could not find `RustcDecodable` in `std`
|
||||
--> $DIR/builtin-std-paths-fail.rs:16:10
|
||||
|
|
||||
LL | core::RustcDecodable,
|
||||
| ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core`
|
||||
LL | std::RustcDecodable,
|
||||
| ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std`
|
||||
|
||||
error[E0433]: failed to resolve: could not find `RustcDecodable` in `std`
|
||||
--> $DIR/builtin-std-paths-fail.rs:14:10
|
||||
@ -82,18 +94,6 @@ error[E0433]: failed to resolve: could not find `test` in `std`
|
||||
LL | #[std::test]
|
||||
| ^^^^ could not find `test` in `std`
|
||||
|
||||
error[E0433]: failed to resolve: could not find `RustcDecodable` in `std`
|
||||
--> $DIR/builtin-std-paths-fail.rs:16:10
|
||||
|
|
||||
LL | std::RustcDecodable,
|
||||
| ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std`
|
||||
|
||||
error[E0433]: failed to resolve: could not find `RustcDecodable` in `std`
|
||||
--> $DIR/builtin-std-paths-fail.rs:14:10
|
||||
|
|
||||
LL | std::RustcDecodable,
|
||||
| ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std`
|
||||
|
||||
error: aborting due to 16 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0433`.
|
||||
|
@ -99,22 +99,6 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
||||
span: $DIR/attribute-after-derive.rs:18:1: 21:2 (#0),
|
||||
},
|
||||
]
|
||||
PRINT-ATTR INPUT (DISPLAY): struct DeriveAttribute { }
|
||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||
Ident {
|
||||
ident: "struct",
|
||||
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
|
||||
},
|
||||
Ident {
|
||||
ident: "DeriveAttribute",
|
||||
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
|
||||
},
|
||||
Group {
|
||||
delimiter: Brace,
|
||||
stream: TokenStream [],
|
||||
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
|
||||
},
|
||||
]
|
||||
PRINT-DERIVE INPUT (DISPLAY): #[print_attr] struct DeriveAttribute { }
|
||||
PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
||||
Punct {
|
||||
@ -146,3 +130,19 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
|
||||
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
|
||||
},
|
||||
]
|
||||
PRINT-ATTR INPUT (DISPLAY): struct DeriveAttribute { }
|
||||
PRINT-ATTR INPUT (DEBUG): TokenStream [
|
||||
Ident {
|
||||
ident: "struct",
|
||||
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
|
||||
},
|
||||
Ident {
|
||||
ident: "DeriveAttribute",
|
||||
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
|
||||
},
|
||||
Group {
|
||||
delimiter: Brace,
|
||||
stream: TokenStream [],
|
||||
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
|
||||
},
|
||||
]
|
||||
|
22
src/test/ui/proc-macro/auxiliary/multiple-derives.rs
Normal file
22
src/test/ui/proc-macro/auxiliary/multiple-derives.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// force-host
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
macro_rules! make_derives {
|
||||
($($name:ident),*) => {
|
||||
$(
|
||||
#[proc_macro_derive($name)]
|
||||
pub fn $name(input: TokenStream) -> TokenStream {
|
||||
println!("Derive {}: {}", stringify!($name), input);
|
||||
TokenStream::new()
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
make_derives!(First, Second, Third, Fourth, Fifth);
|
14
src/test/ui/proc-macro/derive-expand-order.rs
Normal file
14
src/test/ui/proc-macro/derive-expand-order.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// run-pass
|
||||
// aux-build:multiple-derives.rs
|
||||
|
||||
extern crate multiple_derives;
|
||||
|
||||
use multiple_derives::*;
|
||||
|
||||
#[derive(First)]
|
||||
#[derive(Second)]
|
||||
#[derive(Third, Fourth)]
|
||||
#[derive(Fifth)]
|
||||
pub struct Foo {}
|
||||
|
||||
fn main() {}
|
5
src/test/ui/proc-macro/derive-expand-order.stdout
Normal file
5
src/test/ui/proc-macro/derive-expand-order.stdout
Normal file
@ -0,0 +1,5 @@
|
||||
Derive First: #[derive(Second)] #[derive(Third, Fourth)] #[derive(Fifth)] pub struct Foo { }
|
||||
Derive Second: #[derive(Third, Fourth)] #[derive(Fifth)] pub struct Foo { }
|
||||
Derive Third: #[derive(Fifth)] pub struct Foo { }
|
||||
Derive Fourth: #[derive(Fifth)] pub struct Foo { }
|
||||
Derive Fifth: pub struct Foo { }
|
@ -1,11 +1,3 @@
|
||||
error: proc-macro derive panicked
|
||||
--> $DIR/issue-36935.rs:6:20
|
||||
|
|
||||
LL | #[derive(Identity, Panic)]
|
||||
| ^^^^^
|
||||
|
|
||||
= help: message: panic-derive
|
||||
|
||||
error[E0428]: the name `Baz` is defined multiple times
|
||||
--> $DIR/issue-36935.rs:7:1
|
||||
|
|
||||
@ -17,6 +9,14 @@ LL | struct Baz {
|
||||
|
|
||||
= note: `Baz` must be defined only once in the type namespace of this module
|
||||
|
||||
error: proc-macro derive panicked
|
||||
--> $DIR/issue-36935.rs:6:20
|
||||
|
|
||||
LL | #[derive(Identity, Panic)]
|
||||
| ^^^^^
|
||||
|
|
||||
= help: message: panic-derive
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0428`.
|
||||
|
@ -1,26 +1,8 @@
|
||||
error: this trait cannot be derived for unions
|
||||
--> $DIR/union-derive.rs:9:5
|
||||
--> $DIR/union-derive.rs:4:5
|
||||
|
|
||||
LL | Debug,
|
||||
| ^^^^^
|
||||
|
||||
error: this trait cannot be derived for unions
|
||||
--> $DIR/union-derive.rs:8:5
|
||||
|
|
||||
LL | Default,
|
||||
| ^^^^^^^
|
||||
|
||||
error: this trait cannot be derived for unions
|
||||
--> $DIR/union-derive.rs:7:5
|
||||
|
|
||||
LL | Hash,
|
||||
| ^^^^
|
||||
|
||||
error: this trait cannot be derived for unions
|
||||
--> $DIR/union-derive.rs:6:5
|
||||
|
|
||||
LL | Ord,
|
||||
| ^^^
|
||||
LL | PartialEq,
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: this trait cannot be derived for unions
|
||||
--> $DIR/union-derive.rs:5:5
|
||||
@ -29,10 +11,28 @@ LL | PartialOrd,
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: this trait cannot be derived for unions
|
||||
--> $DIR/union-derive.rs:4:5
|
||||
--> $DIR/union-derive.rs:6:5
|
||||
|
|
||||
LL | PartialEq,
|
||||
| ^^^^^^^^^
|
||||
LL | Ord,
|
||||
| ^^^
|
||||
|
||||
error: this trait cannot be derived for unions
|
||||
--> $DIR/union-derive.rs:7:5
|
||||
|
|
||||
LL | Hash,
|
||||
| ^^^^
|
||||
|
||||
error: this trait cannot be derived for unions
|
||||
--> $DIR/union-derive.rs:8:5
|
||||
|
|
||||
LL | Default,
|
||||
| ^^^^^^^
|
||||
|
||||
error: this trait cannot be derived for unions
|
||||
--> $DIR/union-derive.rs:9:5
|
||||
|
|
||||
LL | Debug,
|
||||
| ^^^^^
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user