Skip to content

Commit 44266ca

Browse files
committed
Add a future incompat warning for #[no_link]
This is a pre-1.0 attribute that accidentally got stabilized. It was only meant for compiler plugins which we no longer support, not for regular crates. It is rather fragile and can easily lead to linker errors depending on where rustc decides to codegen functions and statics, which varies between rustc versions. It might also be unsound if a crate for example expects a global constructor it defined to run. Using it doesn't have an effect on the size of the produced binaries except when it defines a `#[used]` static given that we remove all unused functions and statics at link time already.
1 parent fb5f32b commit 44266ca

16 files changed

Lines changed: 505 additions & 79 deletions

‎compiler/rustc_attr_parsing/src/attributes/no_link.rs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use rustc_feature::AttributeStability;
2+
use rustc_lint_defs::builtin::NO_LINK_ATTRIBUTES;
23

34
use super::prelude::*;
5+
use crate::diagnostics::NoLinkAttrUsed;
46

57
pub(crate) struct NoLinkParser;
68
impl NoArgsAttributeParser for NoLinkParser {
@@ -14,4 +16,8 @@ impl NoArgsAttributeParser for NoLinkParser {
1416
]);
1517
const STABILITY: AttributeStability = AttributeStability::Stable;
1618
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoLink;
19+
20+
fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) {
21+
cx.emit_lint(NO_LINK_ATTRIBUTES, NoLinkAttrUsed, attr_span);
22+
}
1723
}

‎compiler/rustc_attr_parsing/src/diagnostics.rs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2132,3 +2132,7 @@ pub(crate) enum MacroExport {
21322132
#[note("declarative macros follow the same exporting rules as regular items")]
21332133
OnDeclMacro,
21342134
}
2135+
2136+
#[derive(Diagnostic)]
2137+
#[diag("use of deprecated `no_link` attribute")]
2138+
pub(crate) struct NoLinkAttrUsed;

‎compiler/rustc_lint_defs/src/builtin.rs‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ pub mod hardwired {
8383
NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE,
8484
NON_CONTIGUOUS_RANGE_ENDPOINTS,
8585
NON_EXHAUSTIVE_OMITTED_PATTERNS,
86+
NO_LINK_ATTRIBUTES,
8687
OUT_OF_SCOPE_MACRO_CALLS,
8788
OVERLAPPING_RANGE_ENDPOINTS,
8889
PARTIAL_STACK_PROTECTOR,
@@ -6019,3 +6020,35 @@ declare_lint! {
60196020
r#"detects default field values on types that have const parameters"#,
60206021
@feature_gate = default_field_values;
60216022
}
6023+
6024+
declare_lint! {
6025+
/// The `no_link_attr_used` lint detects that you used `#[no_link]` on an
6026+
/// `extern crate` item.
6027+
///
6028+
/// ### Example
6029+
///
6030+
/// ```rust
6031+
/// #[no_link]
6032+
/// extern crate std;
6033+
/// ```
6034+
///
6035+
/// {{produces}}
6036+
///
6037+
/// ### Explanation
6038+
///
6039+
/// This is a pre-1.0 attribute that accidentally got stabilized. It was only meant
6040+
/// for compiler plugins which we no longer support, not for regular crates. It is
6041+
/// rather fragile and can easily lead to linker errors depending on where rustc
6042+
/// decides to codegen functions and statics, which varies between rustc versions. It
6043+
/// might also be unsound if a crate for example expects a global constructor it
6044+
/// defined to run. Using it doesn't have an effect on the size of the produced
6045+
/// binaries except when it defines a `#[used]` static given that we remove all unused
6046+
/// functions and statics at link time already.
6047+
pub NO_LINK_ATTRIBUTES,
6048+
Deny,
6049+
"detects usage of `#[no_link]` on `extern crate` items",
6050+
@future_incompatible = FutureIncompatibleInfo {
6051+
reason: fcw!(FutureReleaseError #164032),
6052+
report_in_deps: true,
6053+
};
6054+
}

‎tests/ui/attributes/malformed-attrs.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ static mut TLS: u8 = 42;
207207

208208
#[no_link()]
209209
//~^ ERROR malformed
210+
//~| ERROR use of deprecated `no_link` attribute
211+
//~| WARN this was previously accepted by the compiler
210212
#[macro_use = 1]
211213
//~^ ERROR malformed
212214
extern crate wloop;

‎tests/ui/attributes/malformed-attrs.stderr‎

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ LL | #[cfg_attr(predicate, attr1, attr2, ...)]
2323
| ++++++++++++++++++++++++++++++
2424

2525
error[E0463]: can't find crate for `wloop`
26-
--> $DIR/malformed-attrs.rs:212:1
26+
--> $DIR/malformed-attrs.rs:214:1
2727
|
2828
LL | extern crate wloop;
2929
| ^^^^^^^^^^^^^^^^^^^ can't find crate
@@ -783,7 +783,7 @@ LL + #[no_link]
783783
|
784784

785785
error[E0539]: malformed `macro_use` attribute input
786-
--> $DIR/malformed-attrs.rs:210:3
786+
--> $DIR/malformed-attrs.rs:212:3
787787
|
788788
LL | #[macro_use = 1]
789789
| ^^^^^^^^^^---
@@ -801,7 +801,7 @@ LL + #[macro_use(name1, name2, ...)]
801801
|
802802

803803
error[E0539]: malformed `macro_export` attribute input
804-
--> $DIR/malformed-attrs.rs:215:3
804+
--> $DIR/malformed-attrs.rs:217:3
805805
|
806806
LL | #[macro_export = 18]
807807
| ^^^^^^^^^^^^^----
@@ -818,7 +818,7 @@ LL + #[macro_export(local_inner_macros)]
818818
|
819819

820820
error[E0658]: the `allow_internal_unsafe` attribute side-steps the `unsafe_code` lint
821-
--> $DIR/malformed-attrs.rs:217:3
821+
--> $DIR/malformed-attrs.rs:219:3
822822
|
823823
LL | #[allow_internal_unsafe = 1]
824824
| ^^^^^^^^^^^^^^^^^^^^^
@@ -827,7 +827,7 @@ LL | #[allow_internal_unsafe = 1]
827827
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
828828

829829
error[E0565]: malformed `allow_internal_unsafe` attribute input
830-
--> $DIR/malformed-attrs.rs:217:3
830+
--> $DIR/malformed-attrs.rs:219:3
831831
|
832832
LL | #[allow_internal_unsafe = 1]
833833
| ^^^^^^^^^^^^^^^^^^^^^^---
@@ -964,8 +964,18 @@ LL | #[automatically_derived = 18]
964964
= help: the `automatically_derived` attribute can only be applied to trait impl blocks
965965
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
966966

967+
error: use of deprecated `no_link` attribute
968+
--> $DIR/malformed-attrs.rs:208:1
969+
|
970+
LL | #[no_link()]
971+
| ^^^^^^^^^^^^
972+
|
973+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
974+
= note: for more information, see issue #164032 <https://github.com/rust-lang/rust/issues/164032>
975+
= note: `#[deny(no_link_attributes)]` (part of `#[deny(future_incompatible)]`) on by default
976+
967977
error: valid forms for the attribute are `ignore` and `ignore = "reason"`
968-
--> $DIR/malformed-attrs.rs:224:3
978+
--> $DIR/malformed-attrs.rs:226:3
969979
|
970980
LL | #[ignore = 1]
971981
| ^^^^^^^^^^
@@ -984,7 +994,7 @@ LL | #[coroutine = 63] || {}
984994
= note: expected unit type `()`
985995
found coroutine `{coroutine@$DIR/malformed-attrs.rs:117:23: 117:25}`
986996

987-
error: aborting due to 74 previous errors; 8 warnings emitted
997+
error: aborting due to 75 previous errors; 8 warnings emitted
988998

989999
Some errors have detailed explanations: E0308, E0463, E0539, E0565, E0658, E0805.
9901000
For more information about an error, try `rustc --explain E0308`.
@@ -1010,9 +1020,20 @@ LL | #[ignore()]
10101020
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
10111021
= note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default
10121022

1023+
Future breakage diagnostic:
1024+
error: use of deprecated `no_link` attribute
1025+
--> $DIR/malformed-attrs.rs:208:1
1026+
|
1027+
LL | #[no_link()]
1028+
| ^^^^^^^^^^^^
1029+
|
1030+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
1031+
= note: for more information, see issue #164032 <https://github.com/rust-lang/rust/issues/164032>
1032+
= note: `#[deny(no_link_attributes)]` (part of `#[deny(future_incompatible)]`) on by default
1033+
10131034
Future breakage diagnostic:
10141035
error: valid forms for the attribute are `ignore` and `ignore = "reason"`
1015-
--> $DIR/malformed-attrs.rs:224:3
1036+
--> $DIR/malformed-attrs.rs:226:3
10161037
|
10171038
LL | #[ignore = 1]
10181039
| ^^^^^^^^^^
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//@ no-prefer-dynamic
22

33
#![crate_type = "rlib"]
4+
#![warn(no_link_attributes)]
45

56
#[macro_use] #[no_link] extern crate empty_crate_1 as t1;
67
#[macro_use] extern crate empty_crate_2 as t2;

‎tests/ui/attributes/no_link/no-link-struct.rs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
//@ check-pass
22
//@ aux-build:empty-struct.rs
33

4+
#![warn(no_link_attributes)]
5+
46
#[no_link]
7+
//~^ WARN use of deprecated `no_link` attribute
8+
//~| WARN this was previously accepted by the compiler
59
extern crate empty_struct;
610

711
fn main() {
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
warning: use of deprecated `no_link` attribute
2+
--> $DIR/no-link-struct.rs:6:1
3+
|
4+
LL | #[no_link]
5+
| ^^^^^^^^^^
6+
|
7+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8+
= note: for more information, see issue #164032 <https://github.com/rust-lang/rust/issues/164032>
9+
note: the lint level is defined here
10+
--> $DIR/no-link-struct.rs:4:9
11+
|
12+
LL | #![warn(no_link_attributes)]
13+
| ^^^^^^^^^^^^^^^^^^
14+
15+
warning: 1 warning emitted
16+
17+
Future incompatibility report: Future breakage diagnostic:
18+
warning: use of deprecated `no_link` attribute
19+
--> $DIR/no-link-struct.rs:6:1
20+
|
21+
LL | #[no_link]
22+
| ^^^^^^^^^^
23+
|
24+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
25+
= note: for more information, see issue #164032 <https://github.com/rust-lang/rust/issues/164032>
26+
note: the lint level is defined here
27+
--> $DIR/no-link-struct.rs:4:9
28+
|
29+
LL | #![warn(no_link_attributes)]
30+
| ^^^^^^^^^^^^^^^^^^
31+

‎tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
//~| WARN previously accepted
3030
#![no_link]
3131
//~^ ERROR: the `no_link` attribute cannot be used on crates
32+
//~| ERROR use of deprecated `no_link` attribute
33+
//~| WARN this was previously accepted by the compiler
34+
//~| NOTE `#[deny(no_link_attributes)]` (part of `#[deny(future_incompatible)]`) on by default
35+
//~| NOTE for more information, see issue #164032 <https://github.com/rust-lang/rust/issues/164032>
3236
#![export_name = "2200"]
3337
//~^ ERROR: attribute cannot be used on
3438
//~| NOTE takes precedence
@@ -58,38 +62,65 @@ mod inline {
5862

5963
#[no_link]
6064
//~^ ERROR the `no_link` attribute cannot be used on modules
65+
//~| ERROR use of deprecated `no_link` attribute
66+
//~| WARN this was previously accepted by the compiler
67+
//~| NOTE for more information, see issue #164032 <https://github.com/rust-lang/rust/issues/164032>
6168
mod no_link {
6269
mod inner { #![no_link] }
6370
//~^ ERROR the `no_link` attribute cannot be used on modules
71+
//~| ERROR use of deprecated `no_link` attribute
72+
//~| WARN this was previously accepted by the compiler
73+
//~| NOTE for more information, see issue #164032 <https://github.com/rust-lang/rust/issues/164032>
6474

6575
#[no_link] fn f() {
6676
//~^ ERROR the `no_link` attribute cannot be used on functions
77+
//~| ERROR use of deprecated `no_link` attribute
78+
//~| WARN this was previously accepted by the compiler
79+
//~| NOTE for more information, see issue #164032 <https://github.com/rust-lang/rust/issues/164032>
6780
match () {
6881
#[no_link]
6982
//~^ WARN the `no_link` attribute cannot be used on match arms [unused_attributes]
7083
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
84+
//~| ERROR use of deprecated `no_link` attribute
85+
//~| WARN this was previously accepted by the compiler
86+
//~| NOTE for more information, see issue #164032 <https://github.com/rust-lang/rust/issues/164032>
7187
_ => ()
7288
}
7389
}
7490

7591
#[no_link]
7692
//~^ ERROR the `no_link` attribute cannot be used on structs
93+
//~| ERROR use of deprecated `no_link` attribute
94+
//~| WARN this was previously accepted by the compiler
95+
//~| NOTE for more information, see issue #164032 <https://github.com/rust-lang/rust/issues/164032>
7796
struct S {
7897
#[no_link]
7998
//~^ WARN the `no_link` attribute cannot be used on struct fields [unused_attributes]
8099
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
100+
//~| ERROR use of deprecated `no_link` attribute
101+
//~| WARN this was previously accepted by the compiler
102+
//~| NOTE for more information, see issue #164032 <https://github.com/rust-lang/rust/issues/164032>
81103
field: ()
82104
}
83105

84106
#[no_link]type T = S;
85107
//~^ ERROR the `no_link` attribute cannot be used on type aliases
108+
//~| ERROR use of deprecated `no_link` attribute
109+
//~| WARN this was previously accepted by the compiler
110+
//~| NOTE for more information, see issue #164032 <https://github.com/rust-lang/rust/issues/164032>
86111

87112
#[no_link] impl S { }
88113
//~^ ERROR the `no_link` attribute cannot be used on inherent impl blocks
114+
//~| ERROR use of deprecated `no_link` attribute
115+
//~| WARN this was previously accepted by the compiler
116+
//~| NOTE for more information, see issue #164032 <https://github.com/rust-lang/rust/issues/164032>
89117

90118
#[no_link]
91119
//~^ WARN the `no_link` attribute cannot be used on macro defs
92120
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
121+
//~| ERROR use of deprecated `no_link` attribute
122+
//~| WARN this was previously accepted by the compiler
123+
//~| NOTE for more information, see issue #164032 <https://github.com/rust-lang/rust/issues/164032>
93124
macro_rules! m{() => {}}
94125
}
95126

0 commit comments

Comments
 (0)