Skip to content

Commit db13848

Browse files
author
hyd-dev
committed
Adjust check_no_mangle and check_export_name to warn/error on #[no_mangle]/#[export_name] on trait methods
1 parent 0bb2ea6 commit db13848

5 files changed

+254
-196
lines changed

compiler/rustc_passes/src/check_attr.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,10 @@ impl CheckAttrVisitor<'tcx> {
962962
}
963963
}
964964

965+
fn is_impl_item(&self, hir_id: HirId) -> bool {
966+
matches!(self.tcx.hir().get(hir_id), hir::Node::ImplItem(..))
967+
}
968+
965969
/// Checks if `#[export_name]` is applied to a function or static. Returns `true` if valid.
966970
fn check_export_name(
967971
&self,
@@ -971,7 +975,8 @@ impl CheckAttrVisitor<'tcx> {
971975
target: Target,
972976
) -> bool {
973977
match target {
974-
Target::Static | Target::Fn | Target::Method(..) => true,
978+
Target::Static | Target::Fn => true,
979+
Target::Method(..) if self.is_impl_item(hir_id) => true,
975980
// FIXME(#80564): We permit struct fields, match arms and macro defs to have an
976981
// `#[export_name]` attribute with just a lint, because we previously
977982
// erroneously allowed it and some crates used it accidentally, to to be compatible
@@ -985,9 +990,9 @@ impl CheckAttrVisitor<'tcx> {
985990
.sess
986991
.struct_span_err(
987992
attr.span,
988-
"attribute should be applied to a function or static",
993+
"attribute should be applied to a free function, impl method or static",
989994
)
990-
.span_label(*span, "not a function or static")
995+
.span_label(*span, "not a free function, impl method or static")
991996
.emit();
992997
false
993998
}
@@ -1169,7 +1174,8 @@ impl CheckAttrVisitor<'tcx> {
11691174
/// Checks if `#[no_mangle]` is applied to a function or static.
11701175
fn check_no_mangle(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) {
11711176
match target {
1172-
Target::Static | Target::Fn | Target::Method(..) => {}
1177+
Target::Static | Target::Fn => {}
1178+
Target::Method(..) if self.is_impl_item(hir_id) => {}
11731179
// FIXME(#80564): We permit struct fields, match arms and macro defs to have an
11741180
// `#[no_mangle]` attribute with just a lint, because we previously
11751181
// erroneously allowed it and some crates used it accidentally, to to be compatible
@@ -1181,14 +1187,16 @@ impl CheckAttrVisitor<'tcx> {
11811187
// FIXME: #[no_mangle] was previously allowed on non-functions/statics and some
11821188
// crates used this, so only emit a warning.
11831189
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
1184-
lint.build("attribute should be applied to a function or static")
1185-
.warn(
1186-
"this was previously accepted by the compiler but is \
1187-
being phased out; it will become a hard error in \
1188-
a future release!",
1189-
)
1190-
.span_label(*span, "not a function or static")
1191-
.emit();
1190+
lint.build(
1191+
"attribute should be applied to a free function, impl method or static",
1192+
)
1193+
.warn(
1194+
"this was previously accepted by the compiler but is \
1195+
being phased out; it will become a hard error in \
1196+
a future release!",
1197+
)
1198+
.span_label(*span, "not a free function, impl method or static")
1199+
.emit();
11921200
});
11931201
}
11941202
}

src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//~ NOTE: not an `extern crate` item
2-
//~^ NOTE: not a function or static
2+
//~^ NOTE: not a free function, impl method or static
33
//~^^ NOTE: not a function or closure
44
// This is testing whether various builtin attributes signals an
55
// error or warning when put in "weird" places.
@@ -25,7 +25,7 @@
2525
#![no_link]
2626
//~^ ERROR: attribute should be applied to an `extern crate` item
2727
#![export_name = "2200"]
28-
//~^ ERROR: attribute should be applied to a function or static
28+
//~^ ERROR: attribute should be applied to a free function, impl method or static
2929
#![inline]
3030
//~^ ERROR: attribute should be applied to function or closure
3131
#[inline]
@@ -83,27 +83,37 @@ mod no_link {
8383
}
8484

8585
#[export_name = "2200"]
86-
//~^ ERROR attribute should be applied to a function or static
86+
//~^ ERROR attribute should be applied to a free function, impl method or static
8787
mod export_name {
88-
//~^ NOTE not a function or static
88+
//~^ NOTE not a free function, impl method or static
8989

9090
mod inner { #![export_name="2200"] }
91-
//~^ ERROR attribute should be applied to a function or static
92-
//~| NOTE not a function or static
91+
//~^ ERROR attribute should be applied to a free function, impl method or static
92+
//~| NOTE not a free function, impl method or static
9393

9494
#[export_name = "2200"] fn f() { }
9595

9696
#[export_name = "2200"] struct S;
97-
//~^ ERROR attribute should be applied to a function or static
98-
//~| NOTE not a function or static
97+
//~^ ERROR attribute should be applied to a free function, impl method or static
98+
//~| NOTE not a free function, impl method or static
9999

100100
#[export_name = "2200"] type T = S;
101-
//~^ ERROR attribute should be applied to a function or static
102-
//~| NOTE not a function or static
101+
//~^ ERROR attribute should be applied to a free function, impl method or static
102+
//~| NOTE not a free function, impl method or static
103103

104104
#[export_name = "2200"] impl S { }
105-
//~^ ERROR attribute should be applied to a function or static
106-
//~| NOTE not a function or static
105+
//~^ ERROR attribute should be applied to a free function, impl method or static
106+
//~| NOTE not a free function, impl method or static
107+
108+
trait Tr {
109+
#[export_name = "2200"] fn foo();
110+
//~^ ERROR attribute should be applied to a free function, impl method or static
111+
//~| NOTE not a free function, impl method or static
112+
113+
#[export_name = "2200"] fn bar() {}
114+
//~^ ERROR attribute should be applied to a free function, impl method or static
115+
//~| NOTE not a free function, impl method or static
116+
}
107117
}
108118

109119
#[start]

src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,31 +17,31 @@ LL | #[inline = "2100"] fn f() { }
1717
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
1818

1919
error: `start` attribute can only be used on functions
20-
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:109:1
20+
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:119:1
2121
|
2222
LL | #[start]
2323
| ^^^^^^^^
2424

2525
error: `start` attribute can only be used on functions
26-
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:112:17
26+
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:122:17
2727
|
2828
LL | mod inner { #![start] }
2929
| ^^^^^^^^^
3030

3131
error: `start` attribute can only be used on functions
32-
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:117:5
32+
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:127:5
3333
|
3434
LL | #[start] struct S;
3535
| ^^^^^^^^
3636

3737
error: `start` attribute can only be used on functions
38-
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:120:5
38+
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:130:5
3939
|
4040
LL | #[start] type T = S;
4141
| ^^^^^^^^
4242

4343
error: `start` attribute can only be used on functions
44-
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:123:5
44+
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:133:5
4545
|
4646
LL | #[start] impl S { }
4747
| ^^^^^^^^
@@ -76,7 +76,7 @@ LL | |
7676
LL | | }
7777
| |_- not an `extern crate` item
7878

79-
error: attribute should be applied to a function or static
79+
error: attribute should be applied to a free function, impl method or static
8080
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:85:1
8181
|
8282
LL | #[export_name = "2200"]
@@ -87,17 +87,17 @@ LL | |
8787
LL | |
8888
LL | | mod inner { #![export_name="2200"] }
8989
... |
90-
LL | |
90+
LL | | }
9191
LL | | }
92-
| |_- not a function or static
92+
| |_- not a free function, impl method or static
9393

9494
error: attribute should be applied to an `extern crate` item
9595
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:25:1
9696
|
9797
LL | #![no_link]
9898
| ^^^^^^^^^^^
9999

100-
error: attribute should be applied to a function or static
100+
error: attribute should be applied to a free function, impl method or static
101101
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:27:1
102102
|
103103
LL | #![export_name = "2200"]
@@ -199,31 +199,43 @@ error: attribute should be applied to an `extern crate` item
199199
LL | #[no_link] impl S { }
200200
| ^^^^^^^^^^ ---------- not an `extern crate` item
201201

202-
error: attribute should be applied to a function or static
202+
error: attribute should be applied to a free function, impl method or static
203203
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:90:17
204204
|
205205
LL | mod inner { #![export_name="2200"] }
206-
| ------------^^^^^^^^^^^^^^^^^^^^^^-- not a function or static
206+
| ------------^^^^^^^^^^^^^^^^^^^^^^-- not a free function, impl method or static
207207

208-
error: attribute should be applied to a function or static
208+
error: attribute should be applied to a free function, impl method or static
209209
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:96:5
210210
|
211211
LL | #[export_name = "2200"] struct S;
212-
| ^^^^^^^^^^^^^^^^^^^^^^^ --------- not a function or static
212+
| ^^^^^^^^^^^^^^^^^^^^^^^ --------- not a free function, impl method or static
213213

214-
error: attribute should be applied to a function or static
214+
error: attribute should be applied to a free function, impl method or static
215215
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:100:5
216216
|
217217
LL | #[export_name = "2200"] type T = S;
218-
| ^^^^^^^^^^^^^^^^^^^^^^^ ----------- not a function or static
218+
| ^^^^^^^^^^^^^^^^^^^^^^^ ----------- not a free function, impl method or static
219219

220-
error: attribute should be applied to a function or static
220+
error: attribute should be applied to a free function, impl method or static
221221
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:104:5
222222
|
223223
LL | #[export_name = "2200"] impl S { }
224-
| ^^^^^^^^^^^^^^^^^^^^^^^ ---------- not a function or static
224+
| ^^^^^^^^^^^^^^^^^^^^^^^ ---------- not a free function, impl method or static
225+
226+
error: attribute should be applied to a free function, impl method or static
227+
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:109:9
228+
|
229+
LL | #[export_name = "2200"] fn foo();
230+
| ^^^^^^^^^^^^^^^^^^^^^^^ --------- not a free function, impl method or static
231+
232+
error: attribute should be applied to a free function, impl method or static
233+
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:113:9
234+
|
235+
LL | #[export_name = "2200"] fn bar() {}
236+
| ^^^^^^^^^^^^^^^^^^^^^^^ ----------- not a free function, impl method or static
225237

226-
error: aborting due to 32 previous errors
238+
error: aborting due to 34 previous errors
227239

228240
Some errors have detailed explanations: E0518, E0658.
229241
For more information about an error, try `rustc --explain E0518`.

src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -295,31 +295,43 @@ mod automatically_derived {
295295
}
296296

297297
#[no_mangle]
298-
//~^ WARN attribute should be applied to a function or static [unused_attributes]
298+
//~^ WARN attribute should be applied to a free function, impl method or static [unused_attributes]
299299
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
300300
mod no_mangle {
301-
//~^ NOTE not a function or static
301+
//~^ NOTE not a free function, impl method or static
302302
mod inner { #![no_mangle] }
303-
//~^ WARN attribute should be applied to a function or static [unused_attributes]
303+
//~^ WARN attribute should be applied to a free function, impl method or static [unused_attributes]
304304
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
305-
//~| NOTE not a function or static
305+
//~| NOTE not a free function, impl method or static
306306

307307
#[no_mangle] fn f() { }
308308

309309
#[no_mangle] struct S;
310-
//~^ WARN attribute should be applied to a function or static [unused_attributes]
310+
//~^ WARN attribute should be applied to a free function, impl method or static [unused_attributes]
311311
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
312-
//~| NOTE not a function or static
312+
//~| NOTE not a free function, impl method or static
313313

314314
#[no_mangle] type T = S;
315-
//~^ WARN attribute should be applied to a function or static [unused_attributes]
315+
//~^ WARN attribute should be applied to a free function, impl method or static [unused_attributes]
316316
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
317-
//~| NOTE not a function or static
317+
//~| NOTE not a free function, impl method or static
318318

319319
#[no_mangle] impl S { }
320-
//~^ WARN attribute should be applied to a function or static [unused_attributes]
320+
//~^ WARN attribute should be applied to a free function, impl method or static [unused_attributes]
321321
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
322-
//~| NOTE not a function or static
322+
//~| NOTE not a free function, impl method or static
323+
324+
trait Tr {
325+
#[no_mangle] fn foo();
326+
//~^ WARN attribute should be applied to a free function, impl method or static [unused_attributes]
327+
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
328+
//~| NOTE not a free function, impl method or static
329+
330+
#[no_mangle] fn bar() {}
331+
//~^ WARN attribute should be applied to a free function, impl method or static [unused_attributes]
332+
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
333+
//~| NOTE not a free function, impl method or static
334+
}
323335
}
324336

325337
#[should_panic]

0 commit comments

Comments
 (0)