Skip to content

Commit fc125a5

Browse files
committed
emit specific warning to clarify that foreign items can't have no_mangle
remove extra commented code Deduplicate some diagnostics code add code symbols, machine applicable suggestion clarify error message
1 parent 2f662b1 commit fc125a5

File tree

3 files changed

+102
-0
lines changed

3 files changed

+102
-0
lines changed

compiler/rustc_passes/src/check_attr.rs

+30
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,36 @@ impl CheckAttrVisitor<'tcx> {
13311331
Target::Field | Target::Arm | Target::MacroDef => {
13321332
self.inline_attr_str_error_with_macro_def(hir_id, attr, "no_mangle");
13331333
}
1334+
// FIXME: #[no_mangle] was previously allowed on non-functions/statics, this should be an error
1335+
// The error should specify that the item that is wrong is specifically a *foreign* fn/static
1336+
// otherwise the error seems odd
1337+
Target::ForeignFn | Target::ForeignStatic => {
1338+
let foreign_item_kind = match target {
1339+
Target::ForeignFn => "function",
1340+
Target::ForeignStatic => "static",
1341+
_ => unreachable!(),
1342+
};
1343+
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
1344+
lint.build(&format!(
1345+
"`#[no_mangle]` has no effect on a foreign {}",
1346+
foreign_item_kind
1347+
))
1348+
.warn(
1349+
"this was previously accepted by the compiler but is \
1350+
being phased out; it will become a hard error in \
1351+
a future release!",
1352+
)
1353+
.span_label(*span, format!("foreign {}", foreign_item_kind))
1354+
.note("symbol names in extern blocks are not mangled")
1355+
.span_suggestion(
1356+
attr.span,
1357+
"remove this attribute",
1358+
String::new(),
1359+
Applicability::MachineApplicable,
1360+
)
1361+
.emit();
1362+
});
1363+
}
13341364
_ => {
13351365
// FIXME: #[no_mangle] was previously allowed on non-functions/statics and some
13361366
// crates used this, so only emit a warning.
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#![warn(unused_attributes)]
2+
3+
// Tests that placing the #[no_mangle] attribute on a foreign fn or static emits
4+
// a specialized warning.
5+
// The previous warning only talks about a "function or static" but foreign fns/statics
6+
// are also not allowed to have #[no_mangle]
7+
8+
// build-pass
9+
10+
extern "C" {
11+
#[no_mangle]
12+
//~^ WARNING `#[no_mangle]` has no effect on a foreign static
13+
//~^^ WARNING this was previously accepted by the compiler
14+
pub static FOO: u8;
15+
16+
#[no_mangle]
17+
//~^ WARNING `#[no_mangle]` has no effect on a foreign function
18+
//~^^ WARNING this was previously accepted by the compiler
19+
pub fn bar();
20+
}
21+
22+
fn no_new_warn() {
23+
// Should emit the generic "not a function or static" warning
24+
#[no_mangle]
25+
//~^ WARNING attribute should be applied to a free function, impl method or static
26+
//~^^ WARNING this was previously accepted by the compiler
27+
let x = 0_u8;
28+
}
29+
30+
fn main() {}
+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
warning: attribute should be applied to a free function, impl method or static
2+
--> $DIR/extern-no-mangle.rs:24:5
3+
|
4+
LL | #[no_mangle]
5+
| ^^^^^^^^^^^^
6+
...
7+
LL | let x = 0_u8;
8+
| ------------- not a free function, impl method or static
9+
|
10+
note: the lint level is defined here
11+
--> $DIR/extern-no-mangle.rs:1:9
12+
|
13+
LL | #![warn(unused_attributes)]
14+
| ^^^^^^^^^^^^^^^^^
15+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
16+
17+
warning: `#[no_mangle]` has no effect on a foreign static
18+
--> $DIR/extern-no-mangle.rs:11:5
19+
|
20+
LL | #[no_mangle]
21+
| ^^^^^^^^^^^^ help: remove this attribute
22+
...
23+
LL | pub static FOO: u8;
24+
| ------------------- foreign static
25+
|
26+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
27+
= note: symbol names in extern blocks are not mangled
28+
29+
warning: `#[no_mangle]` has no effect on a foreign function
30+
--> $DIR/extern-no-mangle.rs:16:5
31+
|
32+
LL | #[no_mangle]
33+
| ^^^^^^^^^^^^ help: remove this attribute
34+
...
35+
LL | pub fn bar();
36+
| ------------- foreign function
37+
|
38+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
39+
= note: symbol names in extern blocks are not mangled
40+
41+
warning: 3 warnings emitted
42+

0 commit comments

Comments
 (0)