about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-02-01 16:08:04 +0100
committerGitHub <noreply@github.com>2022-02-01 16:08:04 +0100
commiteb01fe85f721bb669305ff30cb0081d15495919f (patch)
treeb590ff9e86a417f4fb3d041a7a621b7fccb297d9 /src
parent741b62af0749ddf88ebbd7cad6ec7a15ab1fc1cb (diff)
parent94b0a7b8e9affe00c83c7afdb725edd530d855ee (diff)
downloadrust-eb01fe85f721bb669305ff30cb0081d15495919f.tar.gz
rust-eb01fe85f721bb669305ff30cb0081d15495919f.zip
Rollup merge of #93267 - lcnr:auto-trait-lint, r=nikomatsakis
implement a lint for suspicious auto trait impls

cc https://github.com/rust-lang/rust/pull/85048#issuecomment-1019805102

r? ``@nikomatsakis``
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/auto-traits/suspicious-impls-lint.rs34
-rw-r--r--src/test/ui/auto-traits/suspicious-impls-lint.stderr52
-rw-r--r--src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.rs1
-rw-r--r--src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.stderr8
-rw-r--r--src/tools/clippy/tests/ui/non_send_fields_in_send_ty.rs1
-rw-r--r--src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr52
6 files changed, 118 insertions, 30 deletions
diff --git a/src/test/ui/auto-traits/suspicious-impls-lint.rs b/src/test/ui/auto-traits/suspicious-impls-lint.rs
new file mode 100644
index 00000000000..1026a35a455
--- /dev/null
+++ b/src/test/ui/auto-traits/suspicious-impls-lint.rs
@@ -0,0 +1,34 @@
+#![deny(suspicious_auto_trait_impls)]
+
+struct MayImplementSendOk<T>(T);
+unsafe impl<T: Send> Send for MayImplementSendOk<T> {} // ok
+
+struct MayImplementSendErr<T>(T);
+unsafe impl<T: Send> Send for MayImplementSendErr<&T> {}
+//~^ ERROR
+//~| WARNING this will change its meaning
+
+struct ContainsNonSendDirect<T>(*const T);
+unsafe impl<T: Send> Send for ContainsNonSendDirect<&T> {} // ok
+
+struct ContainsPtr<T>(*const T);
+struct ContainsIndirectNonSend<T>(ContainsPtr<T>);
+unsafe impl<T: Send> Send for ContainsIndirectNonSend<&T> {} // ok
+
+struct ContainsVec<T>(Vec<T>);
+unsafe impl Send for ContainsVec<i32> {}
+//~^ ERROR
+//~| WARNING this will change its meaning
+
+struct TwoParams<T, U>(T, U);
+unsafe impl<T: Send, U: Send> Send for TwoParams<T, U> {} // ok
+
+struct TwoParamsFlipped<T, U>(T, U);
+unsafe impl<T: Send, U: Send> Send for TwoParamsFlipped<U, T> {} // ok
+
+struct TwoParamsSame<T, U>(T, U);
+unsafe impl<T: Send> Send for TwoParamsSame<T, T> {}
+//~^ ERROR
+//~| WARNING this will change its meaning
+
+fn main() {}
diff --git a/src/test/ui/auto-traits/suspicious-impls-lint.stderr b/src/test/ui/auto-traits/suspicious-impls-lint.stderr
new file mode 100644
index 00000000000..f91aa862271
--- /dev/null
+++ b/src/test/ui/auto-traits/suspicious-impls-lint.stderr
@@ -0,0 +1,52 @@
+error: cross-crate traits with a default impl, like `Send`, should not be specialized
+  --> $DIR/suspicious-impls-lint.rs:7:1
+   |
+LL | unsafe impl<T: Send> Send for MayImplementSendErr<&T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/suspicious-impls-lint.rs:1:9
+   |
+LL | #![deny(suspicious_auto_trait_impls)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = warning: this will change its meaning in a future release!
+   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
+note: try using the same sequence of generic parameters as the struct definition
+  --> $DIR/suspicious-impls-lint.rs:6:1
+   |
+LL | struct MayImplementSendErr<T>(T);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `&T` is not a generic parameter
+
+error: cross-crate traits with a default impl, like `Send`, should not be specialized
+  --> $DIR/suspicious-impls-lint.rs:19:1
+   |
+LL | unsafe impl Send for ContainsVec<i32> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this will change its meaning in a future release!
+   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
+note: try using the same sequence of generic parameters as the struct definition
+  --> $DIR/suspicious-impls-lint.rs:18:1
+   |
+LL | struct ContainsVec<T>(Vec<T>);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `i32` is not a generic parameter
+
+error: cross-crate traits with a default impl, like `Send`, should not be specialized
+  --> $DIR/suspicious-impls-lint.rs:30:1
+   |
+LL | unsafe impl<T: Send> Send for TwoParamsSame<T, T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this will change its meaning in a future release!
+   = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
+note: try using the same sequence of generic parameters as the struct definition
+  --> $DIR/suspicious-impls-lint.rs:29:1
+   |
+LL | struct TwoParamsSame<T, U>(T, U);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `T` is mentioned multiple times
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.rs b/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.rs
index 772ac322032..cc75cd4909a 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.rs
+++ b/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.rs
@@ -1,4 +1,5 @@
 // aux-build:tdticc_coherence_lib.rs
+#![allow(suspicious_auto_trait_impls)]
 
 // Test that we do not consider associated types to be sendable without
 // some applicable trait bound (and we don't ICE).
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.stderr b/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.stderr
index 90ab5be016c..cf5c15df705 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:13:1
+  --> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:14:1
    |
 LL | impl DefaultedTrait for (A,) { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^----
@@ -10,7 +10,7 @@ LL | impl DefaultedTrait for (A,) { }
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:16:1
+  --> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:17:1
    |
 LL | impl !DefaultedTrait for (B,) { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^----
@@ -21,13 +21,13 @@ LL | impl !DefaultedTrait for (B,) { }
    = note: define and implement a trait or new type instead
 
 error[E0321]: cross-crate traits with a default impl, like `DefaultedTrait`, can only be implemented for a struct/enum type defined in the current crate
-  --> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:20:1
+  --> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:21:1
    |
 LL | impl DefaultedTrait for Box<C> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait for type in another crate
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:21:1
+  --> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:22:1
    |
 LL | impl DefaultedTrait for lib::Something<C> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^-----------------
diff --git a/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.rs b/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.rs
index 828248d922f..514fb25c8cf 100644
--- a/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.rs
+++ b/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::non_send_fields_in_send_ty)]
+#![allow(suspicious_auto_trait_impls)]
 #![feature(extern_types)]
 
 use std::cell::UnsafeCell;
diff --git a/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr b/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr
index 60df4e226e4..b6c904a147a 100644
--- a/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr
+++ b/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr
@@ -1,167 +1,167 @@
 error: some fields in `RingBuffer<T>` are not safe to be sent to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:16:1
+  --> $DIR/non_send_fields_in_send_ty.rs:17:1
    |
 LL | unsafe impl<T> Send for RingBuffer<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `-D clippy::non-send-fields-in-send-ty` implied by `-D warnings`
 note: it is not safe to send field `data` to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:11:5
+  --> $DIR/non_send_fields_in_send_ty.rs:12:5
    |
 LL |     data: Vec<UnsafeCell<T>>,
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
    = help: add bounds on type parameter `T` that satisfy `Vec<UnsafeCell<T>>: Send`
 
 error: some fields in `MvccRwLock<T>` are not safe to be sent to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:24:1
+  --> $DIR/non_send_fields_in_send_ty.rs:25:1
    |
 LL | unsafe impl<T> Send for MvccRwLock<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: it is not safe to send field `lock` to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:21:5
+  --> $DIR/non_send_fields_in_send_ty.rs:22:5
    |
 LL |     lock: Mutex<Box<T>>,
    |     ^^^^^^^^^^^^^^^^^^^
    = help: add bounds on type parameter `T` that satisfy `Mutex<Box<T>>: Send`
 
 error: some fields in `ArcGuard<RC, T>` are not safe to be sent to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:32:1
+  --> $DIR/non_send_fields_in_send_ty.rs:33:1
    |
 LL | unsafe impl<RC, T: Send> Send for ArcGuard<RC, T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: it is not safe to send field `head` to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:29:5
+  --> $DIR/non_send_fields_in_send_ty.rs:30:5
    |
 LL |     head: Arc<RC>,
    |     ^^^^^^^^^^^^^
    = help: add bounds on type parameter `RC` that satisfy `Arc<RC>: Send`
 
 error: some fields in `DeviceHandle<T>` are not safe to be sent to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:48:1
+  --> $DIR/non_send_fields_in_send_ty.rs:49:1
    |
 LL | unsafe impl<T: UsbContext> Send for DeviceHandle<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: it is not safe to send field `context` to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:44:5
+  --> $DIR/non_send_fields_in_send_ty.rs:45:5
    |
 LL |     context: T,
    |     ^^^^^^^^^^
    = help: add `T: Send` bound in `Send` impl
 
 error: some fields in `NoGeneric` are not safe to be sent to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:55:1
+  --> $DIR/non_send_fields_in_send_ty.rs:56:1
    |
 LL | unsafe impl Send for NoGeneric {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: it is not safe to send field `rc_is_not_send` to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:52:5
+  --> $DIR/non_send_fields_in_send_ty.rs:53:5
    |
 LL |     rc_is_not_send: Rc<String>,
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: use a thread-safe type that implements `Send`
 
 error: some fields in `MultiField<T>` are not safe to be sent to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:63:1
+  --> $DIR/non_send_fields_in_send_ty.rs:64:1
    |
 LL | unsafe impl<T> Send for MultiField<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: it is not safe to send field `field1` to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:58:5
+  --> $DIR/non_send_fields_in_send_ty.rs:59:5
    |
 LL |     field1: T,
    |     ^^^^^^^^^
    = help: add `T: Send` bound in `Send` impl
 note: it is not safe to send field `field2` to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:59:5
+  --> $DIR/non_send_fields_in_send_ty.rs:60:5
    |
 LL |     field2: T,
    |     ^^^^^^^^^
    = help: add `T: Send` bound in `Send` impl
 note: it is not safe to send field `field3` to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:60:5
+  --> $DIR/non_send_fields_in_send_ty.rs:61:5
    |
 LL |     field3: T,
    |     ^^^^^^^^^
    = help: add `T: Send` bound in `Send` impl
 
 error: some fields in `MyOption<T>` are not safe to be sent to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:70:1
+  --> $DIR/non_send_fields_in_send_ty.rs:71:1
    |
 LL | unsafe impl<T> Send for MyOption<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: it is not safe to send field `0` to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:66:12
+  --> $DIR/non_send_fields_in_send_ty.rs:67:12
    |
 LL |     MySome(T),
    |            ^
    = help: add `T: Send` bound in `Send` impl
 
 error: some fields in `MultiParam<A, B>` are not safe to be sent to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:82:1
+  --> $DIR/non_send_fields_in_send_ty.rs:83:1
    |
 LL | unsafe impl<A, B> Send for MultiParam<A, B> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: it is not safe to send field `vec` to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:79:5
+  --> $DIR/non_send_fields_in_send_ty.rs:80:5
    |
 LL |     vec: Vec<(A, B)>,
    |     ^^^^^^^^^^^^^^^^
    = help: add bounds on type parameters `A, B` that satisfy `Vec<(A, B)>: Send`
 
 error: some fields in `HeuristicTest` are not safe to be sent to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:100:1
+  --> $DIR/non_send_fields_in_send_ty.rs:101:1
    |
 LL | unsafe impl Send for HeuristicTest {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: it is not safe to send field `field4` to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:95:5
+  --> $DIR/non_send_fields_in_send_ty.rs:96:5
    |
 LL |     field4: (*const NonSend, Rc<u8>),
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: use a thread-safe type that implements `Send`
 
 error: some fields in `AttrTest3<T>` are not safe to be sent to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:119:1
+  --> $DIR/non_send_fields_in_send_ty.rs:120:1
    |
 LL | unsafe impl<T> Send for AttrTest3<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: it is not safe to send field `0` to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:114:11
+  --> $DIR/non_send_fields_in_send_ty.rs:115:11
    |
 LL |     Enum2(T),
    |           ^
    = help: add `T: Send` bound in `Send` impl
 
 error: some fields in `Complex<P, u32>` are not safe to be sent to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:127:1
+  --> $DIR/non_send_fields_in_send_ty.rs:128:1
    |
 LL | unsafe impl<P> Send for Complex<P, u32> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: it is not safe to send field `field1` to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:123:5
+  --> $DIR/non_send_fields_in_send_ty.rs:124:5
    |
 LL |     field1: A,
    |     ^^^^^^^^^
    = help: add `P: Send` bound in `Send` impl
 
 error: some fields in `Complex<Q, MutexGuard<'static, bool>>` are not safe to be sent to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:130:1
+  --> $DIR/non_send_fields_in_send_ty.rs:131:1
    |
 LL | unsafe impl<Q: Send> Send for Complex<Q, MutexGuard<'static, bool>> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: it is not safe to send field `field2` to another thread
-  --> $DIR/non_send_fields_in_send_ty.rs:124:5
+  --> $DIR/non_send_fields_in_send_ty.rs:125:5
    |
 LL |     field2: B,
    |     ^^^^^^^^^