Skip to content

Commit f6caae5

Browse files
committed
Feature gate macro attributes in #[derive] output
1 parent dbdbd30 commit f6caae5

File tree

7 files changed

+124
-29
lines changed

7 files changed

+124
-29
lines changed

compiler/rustc_feature/src/active.rs

+4
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,10 @@ declare_features! (
634634

635635
/// Lessens the requirements for structs to implement `Unsize`.
636636
(active, relaxed_struct_unsize, "1.51.0", Some(1), None),
637+
638+
/// Allows macro attributes to observe output of `#[derive]`.
639+
(active, macro_attributes_in_derive_output, "1.51.0", Some(81119), None),
640+
637641
// -------------------------------------------------------------------------
638642
// feature-group-end: actual feature gates
639643
// -------------------------------------------------------------------------

compiler/rustc_resolve/src/macros.rs

+30
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,36 @@ impl<'a> ResolverExpand for Resolver<'a> {
280280
if let Res::Def(_, _) = res {
281281
let normal_module_def_id = self.macro_def_scope(invoc_id).nearest_parent_mod;
282282
self.definitions.add_parent_module_of_macro_def(invoc_id, normal_module_def_id);
283+
284+
// Gate macro attributes in `#[derive]` output.
285+
if !self.session.features_untracked().macro_attributes_in_derive_output
286+
&& kind == MacroKind::Attr
287+
&& ext.builtin_name != Some(sym::derive)
288+
{
289+
let mut expn_id = parent_scope.expansion;
290+
loop {
291+
// Helper attr table is a quick way to determine whether the attr is `derive`.
292+
if self.helper_attrs.contains_key(&expn_id) {
293+
feature_err(
294+
&self.session.parse_sess,
295+
sym::macro_attributes_in_derive_output,
296+
path.span,
297+
"macro attributes in `#[derive]` output are unstable",
298+
)
299+
.emit();
300+
break;
301+
} else {
302+
let expn_data = expn_id.expn_data();
303+
match expn_data.kind {
304+
ExpnKind::Root
305+
| ExpnKind::Macro(MacroKind::Bang | MacroKind::Derive, _) => {
306+
break;
307+
}
308+
_ => expn_id = expn_data.parent,
309+
}
310+
}
311+
}
312+
}
283313
}
284314

285315
Ok(ext)

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,7 @@ symbols! {
679679
loop_break_value,
680680
lt,
681681
macro_at_most_once_rep,
682+
macro_attributes_in_derive_output,
682683
macro_escape,
683684
macro_export,
684685
macro_lifetime_matcher,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// gate-test-macro_attributes_in_derive_output
2+
// aux-build: test-macros.rs
3+
4+
#![feature(proc_macro_hygiene)]
5+
#![feature(stmt_expr_attributes)]
6+
7+
#[macro_use]
8+
extern crate test_macros;
9+
10+
#[derive(Empty)]
11+
#[empty_attr] //~ ERROR macro attributes in `#[derive]` output are unstable
12+
struct S1 {
13+
field: [u8; 10],
14+
}
15+
16+
#[derive(Empty)]
17+
#[empty_helper]
18+
#[empty_attr] //~ ERROR macro attributes in `#[derive]` output are unstable
19+
struct S2 {
20+
field: [u8; 10],
21+
}
22+
23+
#[derive(Empty)]
24+
struct S3 {
25+
field: [u8; #[identity_attr] 10], //~ ERROR macro attributes in `#[derive]` output are unstable
26+
}
27+
28+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
error[E0658]: macro attributes in `#[derive]` output are unstable
2+
--> $DIR/attribute-after-derive-feature-gate.rs:11:3
3+
|
4+
LL | #[empty_attr]
5+
| ^^^^^^^^^^
6+
|
7+
= note: see issue #81119 <https://github.com/rust-lang/rust/issues/81119> for more information
8+
= help: add `#![feature(macro_attributes_in_derive_output)]` to the crate attributes to enable
9+
10+
error[E0658]: macro attributes in `#[derive]` output are unstable
11+
--> $DIR/attribute-after-derive-feature-gate.rs:18:3
12+
|
13+
LL | #[empty_attr]
14+
| ^^^^^^^^^^
15+
|
16+
= note: see issue #81119 <https://github.com/rust-lang/rust/issues/81119> for more information
17+
= help: add `#![feature(macro_attributes_in_derive_output)]` to the crate attributes to enable
18+
19+
error[E0658]: macro attributes in `#[derive]` output are unstable
20+
--> $DIR/attribute-after-derive-feature-gate.rs:25:19
21+
|
22+
LL | field: [u8; #[identity_attr] 10],
23+
| ^^^^^^^^^^^^^
24+
|
25+
= note: see issue #81119 <https://github.com/rust-lang/rust/issues/81119> for more information
26+
= help: add `#![feature(macro_attributes_in_derive_output)]` to the crate attributes to enable
27+
28+
error: aborting due to 3 previous errors
29+
30+
For more information about this error, try `rustc --explain E0658`.

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

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
// compile-flags: -Z span-debug
66
// aux-build: test-macros.rs
77

8+
#![feature(macro_attributes_in_derive_output)]
9+
810
#![no_std] // Don't load unnecessary hygiene information from std
911
extern crate std;
1012

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

+29-29
Original file line numberDiff line numberDiff line change
@@ -3,146 +3,146 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
33
Punct {
44
ch: '#',
55
spacing: Alone,
6-
span: $DIR/attribute-after-derive.rs:15:1: 15:2 (#0),
6+
span: $DIR/attribute-after-derive.rs:17:1: 17:2 (#0),
77
},
88
Group {
99
delimiter: Bracket,
1010
stream: TokenStream [
1111
Ident {
1212
ident: "derive",
13-
span: $DIR/attribute-after-derive.rs:15:3: 15:9 (#0),
13+
span: $DIR/attribute-after-derive.rs:17:3: 17:9 (#0),
1414
},
1515
Group {
1616
delimiter: Parenthesis,
1717
stream: TokenStream [
1818
Ident {
1919
ident: "Print",
20-
span: $DIR/attribute-after-derive.rs:15:10: 15:15 (#0),
20+
span: $DIR/attribute-after-derive.rs:17:10: 17:15 (#0),
2121
},
2222
],
23-
span: $DIR/attribute-after-derive.rs:15:9: 15:16 (#0),
23+
span: $DIR/attribute-after-derive.rs:17:9: 17:16 (#0),
2424
},
2525
],
26-
span: $DIR/attribute-after-derive.rs:15:2: 15:17 (#0),
26+
span: $DIR/attribute-after-derive.rs:17:2: 17:17 (#0),
2727
},
2828
Ident {
2929
ident: "struct",
30-
span: $DIR/attribute-after-derive.rs:16:1: 16:7 (#0),
30+
span: $DIR/attribute-after-derive.rs:18:1: 18:7 (#0),
3131
},
3232
Ident {
3333
ident: "AttributeDerive",
34-
span: $DIR/attribute-after-derive.rs:16:8: 16:23 (#0),
34+
span: $DIR/attribute-after-derive.rs:18:8: 18:23 (#0),
3535
},
3636
Group {
3737
delimiter: Brace,
3838
stream: TokenStream [
3939
Punct {
4040
ch: '#',
4141
spacing: Alone,
42-
span: $DIR/attribute-after-derive.rs:17:5: 17:6 (#0),
42+
span: $DIR/attribute-after-derive.rs:19:5: 19:6 (#0),
4343
},
4444
Group {
4545
delimiter: Bracket,
4646
stream: TokenStream [
4747
Ident {
4848
ident: "cfg",
49-
span: $DIR/attribute-after-derive.rs:17:7: 17:10 (#0),
49+
span: $DIR/attribute-after-derive.rs:19:7: 19:10 (#0),
5050
},
5151
Group {
5252
delimiter: Parenthesis,
5353
stream: TokenStream [
5454
Ident {
5555
ident: "FALSE",
56-
span: $DIR/attribute-after-derive.rs:17:11: 17:16 (#0),
56+
span: $DIR/attribute-after-derive.rs:19:11: 19:16 (#0),
5757
},
5858
],
59-
span: $DIR/attribute-after-derive.rs:17:10: 17:17 (#0),
59+
span: $DIR/attribute-after-derive.rs:19:10: 19:17 (#0),
6060
},
6161
],
62-
span: $DIR/attribute-after-derive.rs:17:6: 17:18 (#0),
62+
span: $DIR/attribute-after-derive.rs:19:6: 19:18 (#0),
6363
},
6464
Ident {
6565
ident: "field",
66-
span: $DIR/attribute-after-derive.rs:18:5: 18:10 (#0),
66+
span: $DIR/attribute-after-derive.rs:20:5: 20:10 (#0),
6767
},
6868
Punct {
6969
ch: ':',
7070
spacing: Alone,
71-
span: $DIR/attribute-after-derive.rs:18:10: 18:11 (#0),
71+
span: $DIR/attribute-after-derive.rs:20:10: 20:11 (#0),
7272
},
7373
Ident {
7474
ident: "u8",
75-
span: $DIR/attribute-after-derive.rs:18:12: 18:14 (#0),
75+
span: $DIR/attribute-after-derive.rs:20:12: 20:14 (#0),
7676
},
7777
Punct {
7878
ch: ',',
7979
spacing: Alone,
80-
span: $DIR/attribute-after-derive.rs:18:14: 18:15 (#0),
80+
span: $DIR/attribute-after-derive.rs:20:14: 20:15 (#0),
8181
},
8282
],
83-
span: $DIR/attribute-after-derive.rs:16:24: 19:2 (#0),
83+
span: $DIR/attribute-after-derive.rs:18:24: 21:2 (#0),
8484
},
8585
]
8686
PRINT-DERIVE INPUT (DISPLAY): struct AttributeDerive { }
8787
PRINT-DERIVE INPUT (DEBUG): TokenStream [
8888
Ident {
8989
ident: "struct",
90-
span: $DIR/attribute-after-derive.rs:16:1: 19:2 (#0),
90+
span: $DIR/attribute-after-derive.rs:18:1: 21:2 (#0),
9191
},
9292
Ident {
9393
ident: "AttributeDerive",
94-
span: $DIR/attribute-after-derive.rs:16:1: 19:2 (#0),
94+
span: $DIR/attribute-after-derive.rs:18:1: 21:2 (#0),
9595
},
9696
Group {
9797
delimiter: Brace,
9898
stream: TokenStream [],
99-
span: $DIR/attribute-after-derive.rs:16:1: 19:2 (#0),
99+
span: $DIR/attribute-after-derive.rs:18:1: 21:2 (#0),
100100
},
101101
]
102102
PRINT-ATTR INPUT (DISPLAY): struct DeriveAttribute { }
103103
PRINT-ATTR INPUT (DEBUG): TokenStream [
104104
Ident {
105105
ident: "struct",
106-
span: $DIR/attribute-after-derive.rs:23:1: 26:2 (#0),
106+
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
107107
},
108108
Ident {
109109
ident: "DeriveAttribute",
110-
span: $DIR/attribute-after-derive.rs:23:1: 26:2 (#0),
110+
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
111111
},
112112
Group {
113113
delimiter: Brace,
114114
stream: TokenStream [],
115-
span: $DIR/attribute-after-derive.rs:23:1: 26:2 (#0),
115+
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
116116
},
117117
]
118118
PRINT-DERIVE INPUT (DISPLAY): #[print_attr] struct DeriveAttribute { }
119119
PRINT-DERIVE INPUT (DEBUG): TokenStream [
120120
Punct {
121121
ch: '#',
122122
spacing: Alone,
123-
span: $DIR/attribute-after-derive.rs:23:1: 26:2 (#0),
123+
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
124124
},
125125
Group {
126126
delimiter: Bracket,
127127
stream: TokenStream [
128128
Ident {
129129
ident: "print_attr",
130-
span: $DIR/attribute-after-derive.rs:23:1: 26:2 (#0),
130+
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
131131
},
132132
],
133-
span: $DIR/attribute-after-derive.rs:23:1: 26:2 (#0),
133+
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
134134
},
135135
Ident {
136136
ident: "struct",
137-
span: $DIR/attribute-after-derive.rs:23:1: 26:2 (#0),
137+
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
138138
},
139139
Ident {
140140
ident: "DeriveAttribute",
141-
span: $DIR/attribute-after-derive.rs:23:1: 26:2 (#0),
141+
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
142142
},
143143
Group {
144144
delimiter: Brace,
145145
stream: TokenStream [],
146-
span: $DIR/attribute-after-derive.rs:23:1: 26:2 (#0),
146+
span: $DIR/attribute-after-derive.rs:25:1: 28:2 (#0),
147147
},
148148
]

0 commit comments

Comments
 (0)