Skip to content

Expand derive invocations in left-to-right order #84023

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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 {
Expand Down
40 changes: 20 additions & 20 deletions src/test/ui/macros/builtin-std-paths-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
|
Expand All @@ -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
Expand Down Expand Up @@ -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`.
32 changes: 16 additions & 16 deletions src/test/ui/proc-macro/attribute-after-derive.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 changes: 22 additions & 0 deletions src/test/ui/proc-macro/auxiliary/multiple-derives.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 14 additions & 0 deletions src/test/ui/proc-macro/derive-expand-order.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 5 additions & 0 deletions src/test/ui/proc-macro/derive-expand-order.stdout
Original file line number Diff line number Diff line change
@@ -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 { }
16 changes: 8 additions & 8 deletions src/test/ui/proc-macro/issue-36935.stderr
Original file line number Diff line number Diff line change
@@ -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
|
Expand All @@ -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`.
36 changes: 18 additions & 18 deletions src/test/ui/union/union-derive.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
error: this trait cannot be derived for unions
--> $DIR/union-derive.rs:9:5
|
LL | Debug,
| ^^^^^

error: this trait cannot be derived for unions
--> $DIR/union-derive.rs:8:5
--> $DIR/union-derive.rs:4:5
|
LL | Default,
| ^^^^^^^
LL | PartialEq,
| ^^^^^^^^^

error: this trait cannot be derived for unions
--> $DIR/union-derive.rs:7:5
--> $DIR/union-derive.rs:5:5
|
LL | Hash,
| ^^^^
LL | PartialOrd,
| ^^^^^^^^^^

error: this trait cannot be derived for unions
--> $DIR/union-derive.rs:6:5
Expand All @@ -23,16 +17,22 @@ LL | Ord,
| ^^^

error: this trait cannot be derived for unions
--> $DIR/union-derive.rs:5:5
--> $DIR/union-derive.rs:7:5
|
LL | PartialOrd,
| ^^^^^^^^^^
LL | Hash,
| ^^^^

error: this trait cannot be derived for unions
--> $DIR/union-derive.rs:4:5
--> $DIR/union-derive.rs:8:5
|
LL | PartialEq,
| ^^^^^^^^^
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