diff options
| author | Dylan DPC <dylan.dpc@gmail.com> | 2020-04-30 14:07:52 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-30 14:07:52 +0200 |
| commit | 4e6772b52bc9832bb47bedba61abdcfb4ba0128e (patch) | |
| tree | 490b2013b130114b20396cefc0f1f89057e7c556 /src | |
| parent | bf459752d41a93eb6df0e9513de4ef807883a80c (diff) | |
| parent | 6c700dc11c72993d5fa5905355a69c6524e960d3 (diff) | |
| download | rust-4e6772b52bc9832bb47bedba61abdcfb4ba0128e.tar.gz rust-4e6772b52bc9832bb47bedba61abdcfb4ba0128e.zip | |
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 https://github.com/rust-lang/rust/pull/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
Diffstat (limited to 'src')
13 files changed, 124 insertions, 22 deletions
diff --git a/src/librustc_passes/check_attr.rs b/src/librustc_passes/check_attr.rs index 155b88f7e8e..0fb715f4504 100644 --- a/src/librustc_passes/check_attr.rs +++ b/src/librustc_passes/check_attr.rs @@ -76,7 +76,7 @@ impl CheckAttrVisitor<'tcx> { return; } - if target == Target::Fn { + if matches!(target, Target::Fn | Target::Method(_) | Target::ForeignFn) { self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id(hir_id)); } @@ -389,6 +389,9 @@ impl CheckAttrVisitor<'tcx> { ); } } + if target == Target::Closure { + self.tcx.codegen_fn_attrs(self.tcx.hir().local_def_id(expr.hir_id)); + } } fn check_used(&self, attrs: &'hir [Attribute], target: Target) { diff --git a/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs b/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs index ff6e2b82903..eecf2046ccb 100644 --- a/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs +++ b/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs @@ -8,24 +8,28 @@ struct Foo; impl Fn<()> for Foo { //~^ ERROR the precise format of `Fn`-family traits' type parameters is subject to change +//~| ERROR manual implementations of `Fn` are experimental extern "rust-call" fn call(self, args: ()) -> () {} //~^ ERROR rust-call ABI is subject to change } struct Foo1; impl FnOnce() for Foo1 { //~^ ERROR associated type bindings are not allowed here +//~| ERROR manual implementations of `FnOnce` are experimental extern "rust-call" fn call_once(self, args: ()) -> () {} //~^ ERROR rust-call ABI is subject to change } struct Bar; impl FnMut<()> for Bar { //~^ ERROR the precise format of `Fn`-family traits' type parameters is subject to change +//~| ERROR manual implementations of `FnMut` are experimental extern "rust-call" fn call_mut(&self, args: ()) -> () {} //~^ ERROR rust-call ABI is subject to change } struct Baz; impl FnOnce<()> for Baz { //~^ ERROR the precise format of `Fn`-family traits' type parameters is subject to change +//~| ERROR manual implementations of `FnOnce` are experimental extern "rust-call" fn call_once(&self, args: ()) -> () {} //~^ ERROR rust-call ABI is subject to change } diff --git a/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr b/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr index 892020332d7..22a1ce30618 100644 --- a/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr +++ b/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr @@ -1,5 +1,5 @@ error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:11:12 + --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:12:12 | LL | extern "rust-call" fn call(self, args: ()) -> () {} | ^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | extern "rust-call" fn call(self, args: ()) -> () {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:17:12 + --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:19:12 | LL | extern "rust-call" fn call_once(self, args: ()) -> () {} | ^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | extern "rust-call" fn call_once(self, args: ()) -> () {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:23:12 + --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:26:12 | LL | extern "rust-call" fn call_mut(&self, args: ()) -> () {} | ^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | extern "rust-call" fn call_mut(&self, args: ()) -> () {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:29:12 + --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:33:12 | LL | extern "rust-call" fn call_once(&self, args: ()) -> () {} | ^^^^^^^^^^^ @@ -44,13 +44,13 @@ LL | impl Fn<()> for Foo { = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0229]: associated type bindings are not allowed here - --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:15:6 + --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:16:6 | LL | impl FnOnce() for Foo1 { | ^^^^^^^^ associated type not allowed here error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change - --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:21:6 + --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:23:6 | LL | impl FnMut<()> for Bar { | ^^^^^^^^^ help: use parenthetical notation instead: `FnMut() -> ()` @@ -59,7 +59,7 @@ LL | impl FnMut<()> for Bar { = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change - --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:27:6 + --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:30:6 | LL | impl FnOnce<()> for Baz { | ^^^^^^^^^^ help: use parenthetical notation instead: `FnOnce() -> ()` @@ -67,7 +67,39 @@ LL | impl FnOnce<()> for Baz { = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable -error: aborting due to 8 previous errors +error[E0183]: manual implementations of `Fn` are experimental + --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:9:1 + | +LL | impl Fn<()> for Foo { + | ^^^^^^^^^^^^^^^^^^^ manual implementations of `Fn` are experimental + | + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable + +error[E0183]: manual implementations of `FnMut` are experimental + --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:23:1 + | +LL | impl FnMut<()> for Bar { + | ^^^^^^^^^^^^^^^^^^^^^^ manual implementations of `FnMut` are experimental + | + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable + +error[E0183]: manual implementations of `FnOnce` are experimental + --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:16:1 + | +LL | impl FnOnce() for Foo1 { + | ^^^^^^^^^^^^^^^^^^^^^^ manual implementations of `FnOnce` are experimental + | + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable + +error[E0183]: manual implementations of `FnOnce` are experimental + --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:30:1 + | +LL | impl FnOnce<()> for Baz { + | ^^^^^^^^^^^^^^^^^^^^^^^ manual implementations of `FnOnce` are experimental + | + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable + +error: aborting due to 12 previous errors Some errors have detailed explanations: E0229, E0658. For more information about an error, try `rustc --explain E0229`. diff --git a/src/test/ui/feature-gates/feature-gate-unboxed-closures.rs b/src/test/ui/feature-gates/feature-gate-unboxed-closures.rs index b8d3aa4a141..ebc5a2536f6 100644 --- a/src/test/ui/feature-gates/feature-gate-unboxed-closures.rs +++ b/src/test/ui/feature-gates/feature-gate-unboxed-closures.rs @@ -4,6 +4,7 @@ struct Test; impl FnOnce<(u32, u32)> for Test { //~^ ERROR the precise format of `Fn`-family traits' type parameters is subject to change +//~| ERROR manual implementations of `FnOnce` are experimental type Output = u32; extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 { diff --git a/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr b/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr index feda2fe49f9..2c8915d0ac3 100644 --- a/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr +++ b/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr @@ -1,5 +1,5 @@ error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-unboxed-closures.rs:9:12 + --> $DIR/feature-gate-unboxed-closures.rs:10:12 | LL | extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 { | ^^^^^^^^^^^ @@ -16,6 +16,14 @@ LL | impl FnOnce<(u32, u32)> for Test { = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable -error: aborting due to 2 previous errors +error[E0183]: manual implementations of `FnOnce` are experimental + --> $DIR/feature-gate-unboxed-closures.rs:5:1 + | +LL | impl FnOnce<(u32, u32)> for Test { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ manual implementations of `FnOnce` are experimental + | + = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/issues/issue-3214.rs b/src/test/ui/issues/issue-3214.rs index 9a727aa3057..030677c879f 100644 --- a/src/test/ui/issues/issue-3214.rs +++ b/src/test/ui/issues/issue-3214.rs @@ -1,3 +1,5 @@ +// ignore-tidy-linelength + fn foo<T>() { struct Foo { x: T, //~ ERROR can't use generic parameters from outer function @@ -5,6 +7,7 @@ fn foo<T>() { impl<T> Drop for Foo<T> { //~^ ERROR wrong number of type arguments + //~| ERROR the type parameter `T` is not constrained by the impl trait, self type, or predicates fn drop(&mut self) {} } } diff --git a/src/test/ui/issues/issue-3214.stderr b/src/test/ui/issues/issue-3214.stderr index 02c8da10bb4..30bc6cb115f 100644 --- a/src/test/ui/issues/issue-3214.stderr +++ b/src/test/ui/issues/issue-3214.stderr @@ -1,5 +1,5 @@ error[E0401]: can't use generic parameters from outer function - --> $DIR/issue-3214.rs:3:12 + --> $DIR/issue-3214.rs:5:12 | LL | fn foo<T>() { | --- - type parameter from outer function @@ -10,12 +10,18 @@ LL | x: T, | ^ use of generic parameter from outer function error[E0107]: wrong number of type arguments: expected 0, found 1 - --> $DIR/issue-3214.rs:6:26 + --> $DIR/issue-3214.rs:8:26 | LL | impl<T> Drop for Foo<T> { | ^ unexpected type argument -error: aborting due to 2 previous errors +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-3214.rs:8:10 + | +LL | impl<T> Drop for Foo<T> { + | ^ unconstrained type parameter + +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0107, E0401. +Some errors have detailed explanations: E0107, E0207, E0401. For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/macros/issue-68060.rs b/src/test/ui/macros/issue-68060.rs index 85ebd66b66c..bc70f8ffec2 100644 --- a/src/test/ui/macros/issue-68060.rs +++ b/src/test/ui/macros/issue-68060.rs @@ -1,5 +1,3 @@ -// build-fail - #![feature(track_caller)] fn main() { diff --git a/src/test/ui/macros/issue-68060.stderr b/src/test/ui/macros/issue-68060.stderr index 230867410d9..3ea49e614e6 100644 --- a/src/test/ui/macros/issue-68060.stderr +++ b/src/test/ui/macros/issue-68060.stderr @@ -1,5 +1,5 @@ error: `#[target_feature(..)]` can only be applied to `unsafe` functions - --> $DIR/issue-68060.rs:8:13 + --> $DIR/issue-68060.rs:6:13 | LL | #[target_feature(enable = "")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can only be applied to `unsafe` functions @@ -8,13 +8,13 @@ LL | |_| (), | ------ not an `unsafe` function error: the feature named `` is not valid for this target - --> $DIR/issue-68060.rs:8:30 + --> $DIR/issue-68060.rs:6:30 | LL | #[target_feature(enable = "")] | ^^^^^^^^^^^ `` is not valid for this target error[E0737]: `#[track_caller]` requires Rust ABI - --> $DIR/issue-68060.rs:11:13 + --> $DIR/issue-68060.rs:9:13 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ diff --git a/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.rs b/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.rs index 20d29619ba4..1145f7786c7 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.rs +++ b/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.rs @@ -4,4 +4,10 @@ extern "C" fn f() {} //~^^ ERROR `#[track_caller]` requires Rust ABI +extern "C" { + #[track_caller] + fn g(); + //~^^ ERROR `#[track_caller]` requires Rust ABI +} + fn main() {} diff --git a/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr b/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr index 2a3a4385c8b..e08c52fabd6 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr +++ b/src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr @@ -4,6 +4,12 @@ error[E0737]: `#[track_caller]` requires Rust ABI LL | #[track_caller] | ^^^^^^^^^^^^^^^ -error: aborting due to previous error +error[E0737]: `#[track_caller]` requires Rust ABI + --> $DIR/error-with-invalid-abi.rs:8:5 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0737`. diff --git a/src/test/ui/target-feature/invalid-attribute.rs b/src/test/ui/target-feature/invalid-attribute.rs index 46680336632..19c8c3dd488 100644 --- a/src/test/ui/target-feature/invalid-attribute.rs +++ b/src/test/ui/target-feature/invalid-attribute.rs @@ -65,9 +65,26 @@ trait Baz { } #[target_feature(enable = "sse2")] unsafe fn test() {} +trait Quux { + fn foo(); +} + +impl Quux for Foo { + #[target_feature(enable = "sse2")] + //~^ ERROR `#[target_feature(..)]` can only be applied to `unsafe` functions + //~| NOTE can only be applied to `unsafe` functions + fn foo() {} + //~^ NOTE not an `unsafe` function +} + fn main() { unsafe { foo(); bar(); } + #[target_feature(enable = "sse2")] + //~^ ERROR `#[target_feature(..)]` can only be applied to `unsafe` functions + //~| NOTE can only be applied to `unsafe` functions + || {}; + //~^ NOTE not an `unsafe` function } diff --git a/src/test/ui/target-feature/invalid-attribute.stderr b/src/test/ui/target-feature/invalid-attribute.stderr index abfe5dd2197..76273d66ac2 100644 --- a/src/test/ui/target-feature/invalid-attribute.stderr +++ b/src/test/ui/target-feature/invalid-attribute.stderr @@ -91,5 +91,23 @@ error: cannot use `#[inline(always)]` with `#[target_feature]` LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ -error: aborting due to 12 previous errors +error: `#[target_feature(..)]` can only be applied to `unsafe` functions + --> $DIR/invalid-attribute.rs:85:5 + | +LL | #[target_feature(enable = "sse2")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can only be applied to `unsafe` functions +... +LL | || {}; + | ----- not an `unsafe` function + +error: `#[target_feature(..)]` can only be applied to `unsafe` functions + --> $DIR/invalid-attribute.rs:73:5 + | +LL | #[target_feature(enable = "sse2")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can only be applied to `unsafe` functions +... +LL | fn foo() {} + | ----------- not an `unsafe` function + +error: aborting due to 14 previous errors |
