Skip to content

Commit 4e6772b

Browse files
authored
Rollup merge of #71205 - NeoRaider:check_attr, r=jonas-schievink
rustc: fix check_attr() for methods, closures and foreign functions This fixes an issue that previously turned up for methods in #69274, but also exists for closures and foreign function: `check_attr` does not call `codegen_fn_attrs()` for these types when it should, meaning that incorrectly used function attributes are not diagnosed without codegen. The issue affects our UI tests, as they run with `--emit=metadata` by default, but as it turns out, this is not the only case: Function attributes are not checked on any dead code without this fix! This makes the fix a **breaking change**. The following very silly Rust programs compiles fine on stable Rust when it should not, which is fixed by this PR. ```rust fn main() { #[target_feature(enable = "sse2")] || {}; } ``` I assume any real-world program which may trigger this issue would at least emit a dead code warning, but of course that is no guarantee that such code does not exist... Fixes #70307
2 parents bf45975 + 6c700dc commit 4e6772b

13 files changed

+124
-22
lines changed

src/librustc_passes/check_attr.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ impl CheckAttrVisitor<'tcx> {
7676
return;
7777
}
7878

79-
if target == Target::Fn {
79+
if matches!(target, Target::Fn | Target::Method(_) | Target::ForeignFn) {
8080
self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id(hir_id));
8181
}
8282

@@ -389,6 +389,9 @@ impl CheckAttrVisitor<'tcx> {
389389
);
390390
}
391391
}
392+
if target == Target::Closure {
393+
self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id(expr.hir_id));
394+
}
392395
}
393396

394397
fn check_used(&self, attrs: &'hir [Attribute], target: Target) {

src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs

+4
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,28 @@
88
struct Foo;
99
impl Fn<()> for Foo {
1010
//~^ ERROR the precise format of `Fn`-family traits' type parameters is subject to change
11+
//~| ERROR manual implementations of `Fn` are experimental
1112
extern "rust-call" fn call(self, args: ()) -> () {}
1213
//~^ ERROR rust-call ABI is subject to change
1314
}
1415
struct Foo1;
1516
impl FnOnce() for Foo1 {
1617
//~^ ERROR associated type bindings are not allowed here
18+
//~| ERROR manual implementations of `FnOnce` are experimental
1719
extern "rust-call" fn call_once(self, args: ()) -> () {}
1820
//~^ ERROR rust-call ABI is subject to change
1921
}
2022
struct Bar;
2123
impl FnMut<()> for Bar {
2224
//~^ ERROR the precise format of `Fn`-family traits' type parameters is subject to change
25+
//~| ERROR manual implementations of `FnMut` are experimental
2326
extern "rust-call" fn call_mut(&self, args: ()) -> () {}
2427
//~^ ERROR rust-call ABI is subject to change
2528
}
2629
struct Baz;
2730
impl FnOnce<()> for Baz {
2831
//~^ ERROR the precise format of `Fn`-family traits' type parameters is subject to change
32+
//~| ERROR manual implementations of `FnOnce` are experimental
2933
extern "rust-call" fn call_once(&self, args: ()) -> () {}
3034
//~^ ERROR rust-call ABI is subject to change
3135
}

src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr

+40-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0658]: rust-call ABI is subject to change
2-
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:11:12
2+
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:12:12
33
|
44
LL | extern "rust-call" fn call(self, args: ()) -> () {}
55
| ^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | extern "rust-call" fn call(self, args: ()) -> () {}
88
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
99

1010
error[E0658]: rust-call ABI is subject to change
11-
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:17:12
11+
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:19:12
1212
|
1313
LL | extern "rust-call" fn call_once(self, args: ()) -> () {}
1414
| ^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL | extern "rust-call" fn call_once(self, args: ()) -> () {}
1717
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
1818

1919
error[E0658]: rust-call ABI is subject to change
20-
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:23:12
20+
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:26:12
2121
|
2222
LL | extern "rust-call" fn call_mut(&self, args: ()) -> () {}
2323
| ^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL | extern "rust-call" fn call_mut(&self, args: ()) -> () {}
2626
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
2727

2828
error[E0658]: rust-call ABI is subject to change
29-
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:29:12
29+
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:33:12
3030
|
3131
LL | extern "rust-call" fn call_once(&self, args: ()) -> () {}
3232
| ^^^^^^^^^^^
@@ -44,13 +44,13 @@ LL | impl Fn<()> for Foo {
4444
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
4545

4646
error[E0229]: associated type bindings are not allowed here
47-
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:15:6
47+
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:16:6
4848
|
4949
LL | impl FnOnce() for Foo1 {
5050
| ^^^^^^^^ associated type not allowed here
5151

5252
error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change
53-
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:21:6
53+
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:23:6
5454
|
5555
LL | impl FnMut<()> for Bar {
5656
| ^^^^^^^^^ help: use parenthetical notation instead: `FnMut() -> ()`
@@ -59,15 +59,47 @@ LL | impl FnMut<()> for Bar {
5959
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
6060

6161
error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change
62-
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:27:6
62+
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:30:6
6363
|
6464
LL | impl FnOnce<()> for Baz {
6565
| ^^^^^^^^^^ help: use parenthetical notation instead: `FnOnce() -> ()`
6666
|
6767
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
6868
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
6969

70-
error: aborting due to 8 previous errors
70+
error[E0183]: manual implementations of `Fn` are experimental
71+
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:9:1
72+
|
73+
LL | impl Fn<()> for Foo {
74+
| ^^^^^^^^^^^^^^^^^^^ manual implementations of `Fn` are experimental
75+
|
76+
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
77+
78+
error[E0183]: manual implementations of `FnMut` are experimental
79+
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:23:1
80+
|
81+
LL | impl FnMut<()> for Bar {
82+
| ^^^^^^^^^^^^^^^^^^^^^^ manual implementations of `FnMut` are experimental
83+
|
84+
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
85+
86+
error[E0183]: manual implementations of `FnOnce` are experimental
87+
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:16:1
88+
|
89+
LL | impl FnOnce() for Foo1 {
90+
| ^^^^^^^^^^^^^^^^^^^^^^ manual implementations of `FnOnce` are experimental
91+
|
92+
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
93+
94+
error[E0183]: manual implementations of `FnOnce` are experimental
95+
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:30:1
96+
|
97+
LL | impl FnOnce<()> for Baz {
98+
| ^^^^^^^^^^^^^^^^^^^^^^^ manual implementations of `FnOnce` are experimental
99+
|
100+
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
101+
102+
error: aborting due to 12 previous errors
71103

72104
Some errors have detailed explanations: E0229, E0658.
73105
For more information about an error, try `rustc --explain E0229`.

src/test/ui/feature-gates/feature-gate-unboxed-closures.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ struct Test;
44

55
impl FnOnce<(u32, u32)> for Test {
66
//~^ ERROR the precise format of `Fn`-family traits' type parameters is subject to change
7+
//~| ERROR manual implementations of `FnOnce` are experimental
78
type Output = u32;
89

910
extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 {

src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0658]: rust-call ABI is subject to change
2-
--> $DIR/feature-gate-unboxed-closures.rs:9:12
2+
--> $DIR/feature-gate-unboxed-closures.rs:10:12
33
|
44
LL | extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 {
55
| ^^^^^^^^^^^
@@ -16,6 +16,14 @@ LL | impl FnOnce<(u32, u32)> for Test {
1616
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
1717
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
1818

19-
error: aborting due to 2 previous errors
19+
error[E0183]: manual implementations of `FnOnce` are experimental
20+
--> $DIR/feature-gate-unboxed-closures.rs:5:1
21+
|
22+
LL | impl FnOnce<(u32, u32)> for Test {
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ manual implementations of `FnOnce` are experimental
24+
|
25+
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
26+
27+
error: aborting due to 3 previous errors
2028

2129
For more information about this error, try `rustc --explain E0658`.

src/test/ui/issues/issue-3214.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
// ignore-tidy-linelength
2+
13
fn foo<T>() {
24
struct Foo {
35
x: T, //~ ERROR can't use generic parameters from outer function
46
}
57

68
impl<T> Drop for Foo<T> {
79
//~^ ERROR wrong number of type arguments
10+
//~| ERROR the type parameter `T` is not constrained by the impl trait, self type, or predicates
811
fn drop(&mut self) {}
912
}
1013
}

src/test/ui/issues/issue-3214.stderr

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0401]: can't use generic parameters from outer function
2-
--> $DIR/issue-3214.rs:3:12
2+
--> $DIR/issue-3214.rs:5:12
33
|
44
LL | fn foo<T>() {
55
| --- - type parameter from outer function
@@ -10,12 +10,18 @@ LL | x: T,
1010
| ^ use of generic parameter from outer function
1111

1212
error[E0107]: wrong number of type arguments: expected 0, found 1
13-
--> $DIR/issue-3214.rs:6:26
13+
--> $DIR/issue-3214.rs:8:26
1414
|
1515
LL | impl<T> Drop for Foo<T> {
1616
| ^ unexpected type argument
1717

18-
error: aborting due to 2 previous errors
18+
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
19+
--> $DIR/issue-3214.rs:8:10
20+
|
21+
LL | impl<T> Drop for Foo<T> {
22+
| ^ unconstrained type parameter
23+
24+
error: aborting due to 3 previous errors
1925

20-
Some errors have detailed explanations: E0107, E0401.
26+
Some errors have detailed explanations: E0107, E0207, E0401.
2127
For more information about an error, try `rustc --explain E0107`.

src/test/ui/macros/issue-68060.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// build-fail
2-
31
#![feature(track_caller)]
42

53
fn main() {

src/test/ui/macros/issue-68060.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: `#[target_feature(..)]` can only be applied to `unsafe` functions
2-
--> $DIR/issue-68060.rs:8:13
2+
--> $DIR/issue-68060.rs:6:13
33
|
44
LL | #[target_feature(enable = "")]
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can only be applied to `unsafe` functions
@@ -8,13 +8,13 @@ LL | |_| (),
88
| ------ not an `unsafe` function
99

1010
error: the feature named `` is not valid for this target
11-
--> $DIR/issue-68060.rs:8:30
11+
--> $DIR/issue-68060.rs:6:30
1212
|
1313
LL | #[target_feature(enable = "")]
1414
| ^^^^^^^^^^^ `` is not valid for this target
1515

1616
error[E0737]: `#[track_caller]` requires Rust ABI
17-
--> $DIR/issue-68060.rs:11:13
17+
--> $DIR/issue-68060.rs:9:13
1818
|
1919
LL | #[track_caller]
2020
| ^^^^^^^^^^^^^^^

src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.rs

+6
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,10 @@
44
extern "C" fn f() {}
55
//~^^ ERROR `#[track_caller]` requires Rust ABI
66

7+
extern "C" {
8+
#[track_caller]
9+
fn g();
10+
//~^^ ERROR `#[track_caller]` requires Rust ABI
11+
}
12+
713
fn main() {}

src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr

+7-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ error[E0737]: `#[track_caller]` requires Rust ABI
44
LL | #[track_caller]
55
| ^^^^^^^^^^^^^^^
66

7-
error: aborting due to previous error
7+
error[E0737]: `#[track_caller]` requires Rust ABI
8+
--> $DIR/error-with-invalid-abi.rs:8:5
9+
|
10+
LL | #[track_caller]
11+
| ^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 2 previous errors
814

915
For more information about this error, try `rustc --explain E0737`.

src/test/ui/target-feature/invalid-attribute.rs

+17
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,26 @@ trait Baz { }
6565
#[target_feature(enable = "sse2")]
6666
unsafe fn test() {}
6767

68+
trait Quux {
69+
fn foo();
70+
}
71+
72+
impl Quux for Foo {
73+
#[target_feature(enable = "sse2")]
74+
//~^ ERROR `#[target_feature(..)]` can only be applied to `unsafe` functions
75+
//~| NOTE can only be applied to `unsafe` functions
76+
fn foo() {}
77+
//~^ NOTE not an `unsafe` function
78+
}
79+
6880
fn main() {
6981
unsafe {
7082
foo();
7183
bar();
7284
}
85+
#[target_feature(enable = "sse2")]
86+
//~^ ERROR `#[target_feature(..)]` can only be applied to `unsafe` functions
87+
//~| NOTE can only be applied to `unsafe` functions
88+
|| {};
89+
//~^ NOTE not an `unsafe` function
7390
}

src/test/ui/target-feature/invalid-attribute.stderr

+19-1
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,23 @@ error: cannot use `#[inline(always)]` with `#[target_feature]`
9191
LL | #[inline(always)]
9292
| ^^^^^^^^^^^^^^^^^
9393

94-
error: aborting due to 12 previous errors
94+
error: `#[target_feature(..)]` can only be applied to `unsafe` functions
95+
--> $DIR/invalid-attribute.rs:85:5
96+
|
97+
LL | #[target_feature(enable = "sse2")]
98+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can only be applied to `unsafe` functions
99+
...
100+
LL | || {};
101+
| ----- not an `unsafe` function
102+
103+
error: `#[target_feature(..)]` can only be applied to `unsafe` functions
104+
--> $DIR/invalid-attribute.rs:73:5
105+
|
106+
LL | #[target_feature(enable = "sse2")]
107+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can only be applied to `unsafe` functions
108+
...
109+
LL | fn foo() {}
110+
| ----------- not an `unsafe` function
111+
112+
error: aborting due to 14 previous errors
95113

0 commit comments

Comments
 (0)