about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-04-30 14:07:52 +0200
committerGitHub <noreply@github.com>2020-04-30 14:07:52 +0200
commit4e6772b52bc9832bb47bedba61abdcfb4ba0128e (patch)
tree490b2013b130114b20396cefc0f1f89057e7c556 /src
parentbf459752d41a93eb6df0e9513de4ef807883a80c (diff)
parent6c700dc11c72993d5fa5905355a69c6524e960d3 (diff)
downloadrust-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')
-rw-r--r--src/librustc_passes/check_attr.rs5
-rw-r--r--src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs4
-rw-r--r--src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr48
-rw-r--r--src/test/ui/feature-gates/feature-gate-unboxed-closures.rs1
-rw-r--r--src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr12
-rw-r--r--src/test/ui/issues/issue-3214.rs3
-rw-r--r--src/test/ui/issues/issue-3214.stderr14
-rw-r--r--src/test/ui/macros/issue-68060.rs2
-rw-r--r--src/test/ui/macros/issue-68060.stderr6
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.rs6
-rw-r--r--src/test/ui/rfc-2091-track-caller/error-with-invalid-abi.stderr8
-rw-r--r--src/test/ui/target-feature/invalid-attribute.rs17
-rw-r--r--src/test/ui/target-feature/invalid-attribute.stderr20
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