Skip to content

Commit 25ea6be

Browse files
committed
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.
2 parents a836d9b + 21e6cc1 commit 25ea6be

File tree

8 files changed

+112
-65
lines changed

8 files changed

+112
-65
lines changed

compiler/rustc_expand/src/expand.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
491491
let fragment_kind = invoc.fragment_kind;
492492
let (expanded_fragment, new_invocations) = match self.expand_invoc(invoc, &ext.kind) {
493493
ExpandResult::Ready(fragment) => {
494+
let mut derive_invocations = Vec::new();
494495
let derive_placeholders = self
495496
.cx
496497
.resolver
@@ -512,14 +513,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
512513
_ => unreachable!(),
513514
};
514515

515-
invocations.reserve(derives.len());
516+
derive_invocations.reserve(derives.len());
516517
derives
517518
.into_iter()
518519
.map(|(path, _exts)| {
519520
// FIXME: Consider using the derive resolutions (`_exts`)
520521
// instead of enqueuing the derives to be resolved again later.
521522
let expn_id = ExpnId::fresh(None);
522-
invocations.push((
523+
derive_invocations.push((
523524
Invocation {
524525
kind: InvocationKind::Derive {
525526
path,
@@ -546,7 +547,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
546547
})
547548
.unwrap_or_default();
548549

549-
self.collect_invocations(fragment, &derive_placeholders)
550+
let (fragment, collected_invocations) =
551+
self.collect_invocations(fragment, &derive_placeholders);
552+
// We choose to expand any derive invocations associated with this macro invocation
553+
// *before* any macro invocations collected from the output fragment
554+
derive_invocations.extend(collected_invocations);
555+
(fragment, derive_invocations)
550556
}
551557
ExpandResult::Retry(invoc) => {
552558
if force {

src/test/ui/macros/builtin-std-paths-fail.stderr

+20-20
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@ error[E0433]: failed to resolve: could not find `RustcDecodable` in `core`
1010
LL | core::RustcDecodable,
1111
| ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core`
1212

13+
error[E0433]: failed to resolve: could not find `RustcDecodable` in `core`
14+
--> $DIR/builtin-std-paths-fail.rs:2:11
15+
|
16+
LL | core::RustcDecodable,
17+
| ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core`
18+
19+
error[E0433]: failed to resolve: could not find `RustcDecodable` in `core`
20+
--> $DIR/builtin-std-paths-fail.rs:4:11
21+
|
22+
LL | core::RustcDecodable,
23+
| ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core`
24+
1325
error[E0433]: failed to resolve: could not find `bench` in `core`
1426
--> $DIR/builtin-std-paths-fail.rs:7:9
1527
|
@@ -34,17 +46,17 @@ error[E0433]: failed to resolve: could not find `test` in `core`
3446
LL | #[core::test]
3547
| ^^^^ could not find `test` in `core`
3648

37-
error[E0433]: failed to resolve: could not find `RustcDecodable` in `core`
38-
--> $DIR/builtin-std-paths-fail.rs:4:11
49+
error[E0433]: failed to resolve: could not find `RustcDecodable` in `std`
50+
--> $DIR/builtin-std-paths-fail.rs:14:10
3951
|
40-
LL | core::RustcDecodable,
41-
| ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core`
52+
LL | std::RustcDecodable,
53+
| ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std`
4254

43-
error[E0433]: failed to resolve: could not find `RustcDecodable` in `core`
44-
--> $DIR/builtin-std-paths-fail.rs:2:11
55+
error[E0433]: failed to resolve: could not find `RustcDecodable` in `std`
56+
--> $DIR/builtin-std-paths-fail.rs:16:10
4557
|
46-
LL | core::RustcDecodable,
47-
| ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core`
58+
LL | std::RustcDecodable,
59+
| ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std`
4860

4961
error[E0433]: failed to resolve: could not find `RustcDecodable` in `std`
5062
--> $DIR/builtin-std-paths-fail.rs:14:10
@@ -82,18 +94,6 @@ error[E0433]: failed to resolve: could not find `test` in `std`
8294
LL | #[std::test]
8395
| ^^^^ could not find `test` in `std`
8496

85-
error[E0433]: failed to resolve: could not find `RustcDecodable` in `std`
86-
--> $DIR/builtin-std-paths-fail.rs:16:10
87-
|
88-
LL | std::RustcDecodable,
89-
| ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std`
90-
91-
error[E0433]: failed to resolve: could not find `RustcDecodable` in `std`
92-
--> $DIR/builtin-std-paths-fail.rs:14:10
93-
|
94-
LL | std::RustcDecodable,
95-
| ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std`
96-
9797
error: aborting due to 16 previous errors
9898

9999
For more information about this error, try `rustc --explain E0433`.

src/test/ui/proc-macro/attribute-after-derive.stdout

+16-16
Original file line numberDiff line numberDiff line change
@@ -99,22 +99,6 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
9999
span: $DIR/attribute-after-derive.rs:18:1: 21:2 (#0),
100100
},
101101
]
102-
PRINT-ATTR INPUT (DISPLAY): struct DeriveAttribute { }
103-
PRINT-ATTR INPUT (DEBUG): TokenStream [
104-
Ident {
105-
ident: "struct",
106-
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
107-
},
108-
Ident {
109-
ident: "DeriveAttribute",
110-
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
111-
},
112-
Group {
113-
delimiter: Brace,
114-
stream: TokenStream [],
115-
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
116-
},
117-
]
118102
PRINT-DERIVE INPUT (DISPLAY): #[print_attr] struct DeriveAttribute { }
119103
PRINT-DERIVE INPUT (DEBUG): TokenStream [
120104
Punct {
@@ -146,3 +130,19 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [
146130
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
147131
},
148132
]
133+
PRINT-ATTR INPUT (DISPLAY): struct DeriveAttribute { }
134+
PRINT-ATTR INPUT (DEBUG): TokenStream [
135+
Ident {
136+
ident: "struct",
137+
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
138+
},
139+
Ident {
140+
ident: "DeriveAttribute",
141+
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
142+
},
143+
Group {
144+
delimiter: Brace,
145+
stream: TokenStream [],
146+
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
147+
},
148+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// force-host
2+
// no-prefer-dynamic
3+
4+
#![crate_type = "proc-macro"]
5+
6+
extern crate proc_macro;
7+
8+
use proc_macro::TokenStream;
9+
10+
macro_rules! make_derives {
11+
($($name:ident),*) => {
12+
$(
13+
#[proc_macro_derive($name)]
14+
pub fn $name(input: TokenStream) -> TokenStream {
15+
println!("Derive {}: {}", stringify!($name), input);
16+
TokenStream::new()
17+
}
18+
)*
19+
}
20+
}
21+
22+
make_derives!(First, Second, Third, Fourth, Fifth);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// run-pass
2+
// aux-build:multiple-derives.rs
3+
4+
extern crate multiple_derives;
5+
6+
use multiple_derives::*;
7+
8+
#[derive(First)]
9+
#[derive(Second)]
10+
#[derive(Third, Fourth)]
11+
#[derive(Fifth)]
12+
pub struct Foo {}
13+
14+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Derive First: #[derive(Second)] #[derive(Third, Fourth)] #[derive(Fifth)] pub struct Foo { }
2+
Derive Second: #[derive(Third, Fourth)] #[derive(Fifth)] pub struct Foo { }
3+
Derive Third: #[derive(Fifth)] pub struct Foo { }
4+
Derive Fourth: #[derive(Fifth)] pub struct Foo { }
5+
Derive Fifth: pub struct Foo { }
+8-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
error: proc-macro derive panicked
2-
--> $DIR/issue-36935.rs:6:20
3-
|
4-
LL | #[derive(Identity, Panic)]
5-
| ^^^^^
6-
|
7-
= help: message: panic-derive
8-
91
error[E0428]: the name `Baz` is defined multiple times
102
--> $DIR/issue-36935.rs:7:1
113
|
@@ -17,6 +9,14 @@ LL | struct Baz {
179
|
1810
= note: `Baz` must be defined only once in the type namespace of this module
1911

12+
error: proc-macro derive panicked
13+
--> $DIR/issue-36935.rs:6:20
14+
|
15+
LL | #[derive(Identity, Panic)]
16+
| ^^^^^
17+
|
18+
= help: message: panic-derive
19+
2020
error: aborting due to 2 previous errors
2121

2222
For more information about this error, try `rustc --explain E0428`.

src/test/ui/union/union-derive.stderr

+18-18
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
11
error: this trait cannot be derived for unions
2-
--> $DIR/union-derive.rs:9:5
3-
|
4-
LL | Debug,
5-
| ^^^^^
6-
7-
error: this trait cannot be derived for unions
8-
--> $DIR/union-derive.rs:8:5
2+
--> $DIR/union-derive.rs:4:5
93
|
10-
LL | Default,
11-
| ^^^^^^^
4+
LL | PartialEq,
5+
| ^^^^^^^^^
126

137
error: this trait cannot be derived for unions
14-
--> $DIR/union-derive.rs:7:5
8+
--> $DIR/union-derive.rs:5:5
159
|
16-
LL | Hash,
17-
| ^^^^
10+
LL | PartialOrd,
11+
| ^^^^^^^^^^
1812

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

2519
error: this trait cannot be derived for unions
26-
--> $DIR/union-derive.rs:5:5
20+
--> $DIR/union-derive.rs:7:5
2721
|
28-
LL | PartialOrd,
29-
| ^^^^^^^^^^
22+
LL | Hash,
23+
| ^^^^
3024

3125
error: this trait cannot be derived for unions
32-
--> $DIR/union-derive.rs:4:5
26+
--> $DIR/union-derive.rs:8:5
3327
|
34-
LL | PartialEq,
35-
| ^^^^^^^^^
28+
LL | Default,
29+
| ^^^^^^^
30+
31+
error: this trait cannot be derived for unions
32+
--> $DIR/union-derive.rs:9:5
33+
|
34+
LL | Debug,
35+
| ^^^^^
3636

3737
error: aborting due to 6 previous errors
3838

0 commit comments

Comments
 (0)