about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2022-01-27 10:49:52 +0100
committerlcnr <rust@lcnr.de>2022-02-01 09:55:19 +0100
commitea624699e3311985deec9b150ed02242b86aeb95 (patch)
treef4a56c675f094a521eb329a3bf68669bd1cb971b /src
parent7fcf7745cc9845118a9ffeea066e7ee31236d15f (diff)
downloadrust-ea624699e3311985deec9b150ed02242b86aeb95.tar.gz
rust-ea624699e3311985deec9b150ed02242b86aeb95.zip
implement lint for suspicious auto trait impls
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
4 files changed, 91 insertions, 4 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> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^-----------------