Auto merge of #84023 - Aaron1011:derive-invoc-order, r=petrochenkov

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:
bors 2021-04-10 22:04:37 +00:00
commit 25ea6be13e
8 changed files with 118 additions and 71 deletions

View file

@ -491,6 +491,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
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 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
_ => 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 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
})
.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 {

View file

@ -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`.

View file

@ -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),
},
]

View 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);

View 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() {}

View 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 { }

View file

@ -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`.

View file

@ -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