diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/auto-traits | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/auto-traits')
26 files changed, 617 insertions, 0 deletions
diff --git a/src/test/ui/auto-traits/auto-is-contextual.rs b/src/test/ui/auto-traits/auto-is-contextual.rs new file mode 100644 index 000000000..a2ddd5374 --- /dev/null +++ b/src/test/ui/auto-traits/auto-is-contextual.rs @@ -0,0 +1,18 @@ +// run-pass + +#![allow(path_statements)] +#![allow(dead_code)] +macro_rules! auto { + () => (struct S;) +} + +auto!(); + +fn auto() {} + +fn main() { + auto(); + let auto = 10; + auto; + auto as u8; +} diff --git a/src/test/ui/auto-traits/auto-trait-projection-recursion.rs b/src/test/ui/auto-traits/auto-trait-projection-recursion.rs new file mode 100644 index 000000000..a36f26f02 --- /dev/null +++ b/src/test/ui/auto-traits/auto-trait-projection-recursion.rs @@ -0,0 +1,34 @@ +// Checking the `Send` bound in `main` requires: +// +// checking <C<'static> as Y>::P: Send +// which normalizes to Box<X<C<'?1>>>: Send +// which needs X<C<'?1>>: Send +// which needs <C<'?1> as Y>::P: Send +// +// At this point we used to normalize the predicate to `Box<X<C<'?2>>>: Send` +// and continue in a loop where we created new region variables to the +// recursion limit. To avoid this we now "canonicalize" region variables to +// lowest unified region vid. This means we instead have to prove +// `Box<X<C<'?1>>>: Send`, which we can because auto traits are coinductive. + +// check-pass + +// Avoid a really long error message if this regresses. +#![recursion_limit="20"] + +trait Y { + type P; +} + +impl<'a> Y for C<'a> { + type P = Box<X<C<'a>>>; +} + +struct C<'a>(&'a ()); +struct X<T: Y>(T::P); + +fn is_send<S: Send>() {} + +fn main() { + is_send::<X<C<'static>>>(); +} diff --git a/src/test/ui/auto-traits/auto-trait-validation.fixed b/src/test/ui/auto-traits/auto-trait-validation.fixed new file mode 100644 index 000000000..da878ac62 --- /dev/null +++ b/src/test/ui/auto-traits/auto-trait-validation.fixed @@ -0,0 +1,13 @@ +#![feature(auto_traits)] + +// run-rustfix + +auto trait Generic {} +//~^ auto traits cannot have generic parameters [E0567] +auto trait Bound {} +//~^ auto traits cannot have super traits or lifetime bounds [E0568] +auto trait LifetimeBound {} +//~^ auto traits cannot have super traits or lifetime bounds [E0568] +auto trait MyTrait { } +//~^ auto traits cannot have associated items [E0380] +fn main() {} diff --git a/src/test/ui/auto-traits/auto-trait-validation.rs b/src/test/ui/auto-traits/auto-trait-validation.rs new file mode 100644 index 000000000..d43055e27 --- /dev/null +++ b/src/test/ui/auto-traits/auto-trait-validation.rs @@ -0,0 +1,13 @@ +#![feature(auto_traits)] + +// run-rustfix + +auto trait Generic<T> {} +//~^ auto traits cannot have generic parameters [E0567] +auto trait Bound : Copy {} +//~^ auto traits cannot have super traits or lifetime bounds [E0568] +auto trait LifetimeBound : 'static {} +//~^ auto traits cannot have super traits or lifetime bounds [E0568] +auto trait MyTrait { fn foo() {} } +//~^ auto traits cannot have associated items [E0380] +fn main() {} diff --git a/src/test/ui/auto-traits/auto-trait-validation.stderr b/src/test/ui/auto-traits/auto-trait-validation.stderr new file mode 100644 index 000000000..2c380e5b0 --- /dev/null +++ b/src/test/ui/auto-traits/auto-trait-validation.stderr @@ -0,0 +1,37 @@ +error[E0567]: auto traits cannot have generic parameters + --> $DIR/auto-trait-validation.rs:5:19 + | +LL | auto trait Generic<T> {} + | -------^^^ help: remove the parameters + | | + | auto trait cannot have generic parameters + +error[E0568]: auto traits cannot have super traits or lifetime bounds + --> $DIR/auto-trait-validation.rs:7:17 + | +LL | auto trait Bound : Copy {} + | -----^^^^^^^ help: remove the super traits or lifetime bounds + | | + | auto trait cannot have super traits or lifetime bounds + +error[E0568]: auto traits cannot have super traits or lifetime bounds + --> $DIR/auto-trait-validation.rs:9:25 + | +LL | auto trait LifetimeBound : 'static {} + | -------------^^^^^^^^^^ help: remove the super traits or lifetime bounds + | | + | auto trait cannot have super traits or lifetime bounds + +error[E0380]: auto traits cannot have associated items + --> $DIR/auto-trait-validation.rs:11:25 + | +LL | auto trait MyTrait { fn foo() {} } + | ------- ---^^^----- + | | | + | | help: remove these associated items + | auto trait cannot have associated items + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0380, E0567, E0568. +For more information about an error, try `rustc --explain E0380`. diff --git a/src/test/ui/auto-traits/auto-traits.rs b/src/test/ui/auto-traits/auto-traits.rs new file mode 100644 index 000000000..7b52d9c17 --- /dev/null +++ b/src/test/ui/auto-traits/auto-traits.rs @@ -0,0 +1,32 @@ +// run-pass +#![allow(unused_doc_comments)] +#![feature(auto_traits)] +#![feature(negative_impls)] + +auto trait Auto {} +unsafe auto trait AutoUnsafe {} + +impl !Auto for bool {} +impl !AutoUnsafe for bool {} + +struct AutoBool(#[allow(unused_tuple_struct_fields)] bool); + +impl Auto for AutoBool {} +unsafe impl AutoUnsafe for AutoBool {} + +fn take_auto<T: Auto>(_: T) {} +fn take_auto_unsafe<T: AutoUnsafe>(_: T) {} + +fn main() { + // Parse inside functions. + auto trait AutoInner {} + unsafe auto trait AutoUnsafeInner {} + + take_auto(0); + take_auto(AutoBool(true)); + take_auto_unsafe(0); + take_auto_unsafe(AutoBool(true)); + + /// Auto traits are allowed in trait object bounds. + let _: &(dyn Send + Auto) = &0; +} diff --git a/src/test/ui/auto-traits/issue-23080-2.rs b/src/test/ui/auto-traits/issue-23080-2.rs new file mode 100644 index 000000000..cb4cf6de1 --- /dev/null +++ b/src/test/ui/auto-traits/issue-23080-2.rs @@ -0,0 +1,13 @@ +#![feature(auto_traits)] +#![feature(negative_impls)] + +unsafe auto trait Trait { + type Output; //~ ERROR E0380 +} + +fn call_method<T: Trait>(x: T) {} + +fn main() { + // ICE + call_method(()); +} diff --git a/src/test/ui/auto-traits/issue-23080-2.stderr b/src/test/ui/auto-traits/issue-23080-2.stderr new file mode 100644 index 000000000..267a712f6 --- /dev/null +++ b/src/test/ui/auto-traits/issue-23080-2.stderr @@ -0,0 +1,11 @@ +error[E0380]: auto traits cannot have associated items + --> $DIR/issue-23080-2.rs:5:10 + | +LL | unsafe auto trait Trait { + | ----- auto trait cannot have associated items +LL | type Output; + | -----^^^^^^- help: remove these associated items + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0380`. diff --git a/src/test/ui/auto-traits/issue-23080.rs b/src/test/ui/auto-traits/issue-23080.rs new file mode 100644 index 000000000..84e2ce66f --- /dev/null +++ b/src/test/ui/auto-traits/issue-23080.rs @@ -0,0 +1,17 @@ +#![feature(auto_traits)] +#![feature(negative_impls)] + +unsafe auto trait Trait { + fn method(&self) { //~ ERROR E0380 + println!("Hello"); + } +} + +fn call_method<T: Trait>(x: T) { + x.method(); +} + +fn main() { + // ICE + call_method(()); +} diff --git a/src/test/ui/auto-traits/issue-23080.stderr b/src/test/ui/auto-traits/issue-23080.stderr new file mode 100644 index 000000000..c1b16b2f4 --- /dev/null +++ b/src/test/ui/auto-traits/issue-23080.stderr @@ -0,0 +1,14 @@ +error[E0380]: auto traits cannot have associated items + --> $DIR/issue-23080.rs:5:8 + | +LL | unsafe auto trait Trait { + | ----- auto trait cannot have associated items +LL | fn method(&self) { + | _____- ^^^^^^ +LL | | println!("Hello"); +LL | | } + | |_____- help: remove these associated items + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0380`. diff --git a/src/test/ui/auto-traits/issue-84075.rs b/src/test/ui/auto-traits/issue-84075.rs new file mode 100644 index 000000000..a6afe24ea --- /dev/null +++ b/src/test/ui/auto-traits/issue-84075.rs @@ -0,0 +1,16 @@ +// Regression test for issue #84075. + +#![feature(auto_traits)] + +auto trait Magic where Self: Copy {} //~ ERROR E0568 +impl<T: Magic> Magic for T {} + +fn copy<T: Magic>(x: T) -> (T, T) { (x, x) } + +#[derive(Debug)] +struct NoClone; + +fn main() { + let (a, b) = copy(NoClone); + println!("{:?} {:?}", a, b); +} diff --git a/src/test/ui/auto-traits/issue-84075.stderr b/src/test/ui/auto-traits/issue-84075.stderr new file mode 100644 index 000000000..02dca598e --- /dev/null +++ b/src/test/ui/auto-traits/issue-84075.stderr @@ -0,0 +1,11 @@ +error[E0568]: auto traits cannot have super traits or lifetime bounds + --> $DIR/issue-84075.rs:5:18 + | +LL | auto trait Magic where Self: Copy {} + | ----- ^^^^^^^^^^^^^^^^ help: remove the super traits or lifetime bounds + | | + | auto trait cannot have super traits or lifetime bounds + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0568`. 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 000000000..7712e84f4 --- /dev/null +++ b/src/test/ui/auto-traits/suspicious-impls-lint.rs @@ -0,0 +1,50 @@ +#![deny(suspicious_auto_trait_impls)] + +use std::marker::PhantomData; + +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 + +pub struct WithPhantomDataNonSend<T, U>(PhantomData<*const T>, U); +unsafe impl<T> Send for WithPhantomDataNonSend<T, i8> {} // ok + +pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U); +unsafe impl<T> Send for WithPhantomDataSend<*const T, i8> {} +//~^ ERROR +//~| WARNING this will change its meaning + +pub struct WithLifetime<'a, T>(&'a (), T); +unsafe impl<T> Send for WithLifetime<'static, T> {} // ok +unsafe impl<T> Sync for WithLifetime<'static, Vec<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 000000000..97b2d7221 --- /dev/null +++ b/src/test/ui/auto-traits/suspicious-impls-lint.stderr @@ -0,0 +1,82 @@ +error: cross-crate traits with a default impl, like `Send`, should not be specialized + --> $DIR/suspicious-impls-lint.rs:9: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: `&T` is not a generic parameter +note: try using the same sequence of generic parameters as the struct definition + --> $DIR/suspicious-impls-lint.rs:8:1 + | +LL | struct MayImplementSendErr<T>(T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cross-crate traits with a default impl, like `Send`, should not be specialized + --> $DIR/suspicious-impls-lint.rs:21: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: `i32` is not a generic parameter +note: try using the same sequence of generic parameters as the struct definition + --> $DIR/suspicious-impls-lint.rs:20:1 + | +LL | struct ContainsVec<T>(Vec<T>); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: cross-crate traits with a default impl, like `Send`, should not be specialized + --> $DIR/suspicious-impls-lint.rs:32: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: `T` is mentioned multiple times +note: try using the same sequence of generic parameters as the struct definition + --> $DIR/suspicious-impls-lint.rs:31:1 + | +LL | struct TwoParamsSame<T, U>(T, U); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cross-crate traits with a default impl, like `Send`, should not be specialized + --> $DIR/suspicious-impls-lint.rs:40:1 + | +LL | unsafe impl<T> Send for WithPhantomDataSend<*const T, i8> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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: `*const T` is not a generic parameter +note: try using the same sequence of generic parameters as the struct definition + --> $DIR/suspicious-impls-lint.rs:39:1 + | +LL | pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cross-crate traits with a default impl, like `Sync`, should not be specialized + --> $DIR/suspicious-impls-lint.rs:46:1 + | +LL | unsafe impl<T> Sync for WithLifetime<'static, Vec<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: `Vec<T>` is not a generic parameter +note: try using the same sequence of generic parameters as the struct definition + --> $DIR/suspicious-impls-lint.rs:44:1 + | +LL | pub struct WithLifetime<'a, T>(&'a (), T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs new file mode 100644 index 000000000..98359ef51 --- /dev/null +++ b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs @@ -0,0 +1,16 @@ +#![feature(auto_traits)] +#![feature(negative_impls)] + +auto trait Magic : Sized where Option<Self> : Magic {} //~ ERROR E0568 +//~^ ERROR E0568 +impl<T:Magic> Magic for T {} + +fn copy<T: Magic>(x: T) -> (T, T) { (x, x) } + +#[derive(Debug)] +struct NoClone; + +fn main() { + let (a, b) = copy(NoClone); + println!("{:?} {:?}", a, b); +} diff --git a/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr new file mode 100644 index 000000000..4827916fa --- /dev/null +++ b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr @@ -0,0 +1,19 @@ +error[E0568]: auto traits cannot have super traits or lifetime bounds + --> $DIR/typeck-auto-trait-no-supertraits-2.rs:4:17 + | +LL | auto trait Magic : Sized where Option<Self> : Magic {} + | -----^^^^^^^^ help: remove the super traits or lifetime bounds + | | + | auto trait cannot have super traits or lifetime bounds + +error[E0568]: auto traits cannot have super traits or lifetime bounds + --> $DIR/typeck-auto-trait-no-supertraits-2.rs:4:26 + | +LL | auto trait Magic : Sized where Option<Self> : Magic {} + | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the super traits or lifetime bounds + | | + | auto trait cannot have super traits or lifetime bounds + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0568`. diff --git a/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits.rs b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits.rs new file mode 100644 index 000000000..2a76893fe --- /dev/null +++ b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits.rs @@ -0,0 +1,39 @@ +// This test is for #29859, we need to ensure auto traits, +// (also known previously as default traits), do not have +// supertraits. Since the compiler synthesizes these +// instances on demand, we are essentially enabling +// users to write axioms if we view trait selection, +// as a proof system. +// +// For example the below test allows us to add the rule: +// forall (T : Type), T : Copy +// +// Providing a copy instance for *any* type, which +// is most definitely unsound. Imagine copying a +// type that contains a mutable reference, enabling +// mutable aliasing. +// +// You can imagine an even more dangerous test, +// which currently compiles on nightly. +// +// fn main() { +// let mut i = 10; +// let (a, b) = copy(&mut i); +// println!("{:?} {:?}", a, b); +// } + +#![feature(auto_traits)] +#![feature(negative_impls)] + +auto trait Magic: Copy {} //~ ERROR E0568 +impl<T:Magic> Magic for T {} + +fn copy<T: Magic>(x: T) -> (T, T) { (x, x) } + +#[derive(Debug)] +struct NoClone; + +fn main() { + let (a, b) = copy(NoClone); + println!("{:?} {:?}", a, b); +} diff --git a/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr new file mode 100644 index 000000000..d7716f4b6 --- /dev/null +++ b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr @@ -0,0 +1,11 @@ +error[E0568]: auto traits cannot have super traits or lifetime bounds + --> $DIR/typeck-auto-trait-no-supertraits.rs:28:17 + | +LL | auto trait Magic: Copy {} + | -----^^^^^^ help: remove the super traits or lifetime bounds + | | + | auto trait cannot have super traits or lifetime bounds + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0568`. diff --git a/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.rs b/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.rs new file mode 100644 index 000000000..f2fb67f11 --- /dev/null +++ b/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.rs @@ -0,0 +1,19 @@ +#![feature(auto_traits)] +#![feature(negative_impls)] + +auto trait MyTrait {} + +struct MyS; + +struct MyS2; + +impl !MyTrait for MyS2 {} + +fn is_mytrait<T: MyTrait>() {} + +fn main() { + is_mytrait::<MyS>(); + + is_mytrait::<(MyS2, MyS)>(); + //~^ ERROR `MyS2: MyTrait` is not satisfied +} diff --git a/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.stderr b/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.stderr new file mode 100644 index 000000000..7d6bf58f5 --- /dev/null +++ b/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.stderr @@ -0,0 +1,16 @@ +error[E0277]: the trait bound `MyS2: MyTrait` is not satisfied in `(MyS2, MyS)` + --> $DIR/typeck-default-trait-impl-constituent-types-2.rs:17:5 + | +LL | is_mytrait::<(MyS2, MyS)>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ within `(MyS2, MyS)`, the trait `MyTrait` is not implemented for `MyS2` + | + = note: required because it appears within the type `(MyS2, MyS)` +note: required by a bound in `is_mytrait` + --> $DIR/typeck-default-trait-impl-constituent-types-2.rs:12:18 + | +LL | fn is_mytrait<T: MyTrait>() {} + | ^^^^^^^ required by this bound in `is_mytrait` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types.rs b/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types.rs new file mode 100644 index 000000000..73ff46d05 --- /dev/null +++ b/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types.rs @@ -0,0 +1,23 @@ +#![feature(auto_traits)] +#![feature(negative_impls)] + +auto trait MyTrait {} + +impl<T> !MyTrait for *mut T {} + +struct MyS; + +struct MyS2; + +impl !MyTrait for MyS2 {} + +struct MyS3; + +fn is_mytrait<T: MyTrait>() {} + +fn main() { + is_mytrait::<MyS>(); + + is_mytrait::<MyS2>(); + //~^ ERROR `MyS2: MyTrait` is not satisfied +} diff --git a/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types.stderr b/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types.stderr new file mode 100644 index 000000000..c575c485a --- /dev/null +++ b/src/test/ui/auto-traits/typeck-default-trait-impl-constituent-types.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `MyS2: MyTrait` is not satisfied + --> $DIR/typeck-default-trait-impl-constituent-types.rs:21:18 + | +LL | is_mytrait::<MyS2>(); + | ^^^^ the trait `MyTrait` is not implemented for `MyS2` + | +note: required by a bound in `is_mytrait` + --> $DIR/typeck-default-trait-impl-constituent-types.rs:16:18 + | +LL | fn is_mytrait<T: MyTrait>() {} + | ^^^^^^^ required by this bound in `is_mytrait` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/auto-traits/typeck-default-trait-impl-negation.rs b/src/test/ui/auto-traits/typeck-default-trait-impl-negation.rs new file mode 100644 index 000000000..f7f56f97f --- /dev/null +++ b/src/test/ui/auto-traits/typeck-default-trait-impl-negation.rs @@ -0,0 +1,29 @@ +#![feature(auto_traits)] +#![feature(negative_impls)] + +auto trait MyTrait {} + +unsafe auto trait MyUnsafeTrait {} + +struct ThisImplsTrait; + +impl !MyUnsafeTrait for ThisImplsTrait {} + + +struct ThisImplsUnsafeTrait; + +impl !MyTrait for ThisImplsUnsafeTrait {} + +fn is_my_trait<T: MyTrait>() {} +fn is_my_unsafe_trait<T: MyUnsafeTrait>() {} + +fn main() { + is_my_trait::<ThisImplsTrait>(); + is_my_trait::<ThisImplsUnsafeTrait>(); + //~^ ERROR `ThisImplsUnsafeTrait: MyTrait` is not satisfied + + is_my_unsafe_trait::<ThisImplsTrait>(); + //~^ ERROR `ThisImplsTrait: MyUnsafeTrait` is not satisfied + + is_my_unsafe_trait::<ThisImplsUnsafeTrait>(); +} diff --git a/src/test/ui/auto-traits/typeck-default-trait-impl-negation.stderr b/src/test/ui/auto-traits/typeck-default-trait-impl-negation.stderr new file mode 100644 index 000000000..fa8dd41da --- /dev/null +++ b/src/test/ui/auto-traits/typeck-default-trait-impl-negation.stderr @@ -0,0 +1,27 @@ +error[E0277]: the trait bound `ThisImplsUnsafeTrait: MyTrait` is not satisfied + --> $DIR/typeck-default-trait-impl-negation.rs:22:19 + | +LL | is_my_trait::<ThisImplsUnsafeTrait>(); + | ^^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `ThisImplsUnsafeTrait` + | +note: required by a bound in `is_my_trait` + --> $DIR/typeck-default-trait-impl-negation.rs:17:19 + | +LL | fn is_my_trait<T: MyTrait>() {} + | ^^^^^^^ required by this bound in `is_my_trait` + +error[E0277]: the trait bound `ThisImplsTrait: MyUnsafeTrait` is not satisfied + --> $DIR/typeck-default-trait-impl-negation.rs:25:26 + | +LL | is_my_unsafe_trait::<ThisImplsTrait>(); + | ^^^^^^^^^^^^^^ the trait `MyUnsafeTrait` is not implemented for `ThisImplsTrait` + | +note: required by a bound in `is_my_unsafe_trait` + --> $DIR/typeck-default-trait-impl-negation.rs:18:26 + | +LL | fn is_my_unsafe_trait<T: MyUnsafeTrait>() {} + | ^^^^^^^^^^^^^ required by this bound in `is_my_unsafe_trait` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.rs b/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.rs new file mode 100644 index 000000000..2bbe82270 --- /dev/null +++ b/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.rs @@ -0,0 +1,21 @@ +// Test that declaring that `&T` is `Defaulted` if `T:Signed` implies +// that other `&T` is NOT `Defaulted` if `T:Signed` does not hold. In +// other words, the auto impl only applies if there are no existing +// impls whose types unify. + +#![feature(auto_traits)] +#![feature(negative_impls)] + +auto trait Defaulted { } +impl<'a,T:Signed> Defaulted for &'a T { } +impl<'a,T:Signed> Defaulted for &'a mut T { } +fn is_defaulted<T:Defaulted>() { } + +trait Signed { } +impl Signed for i32 { } + +fn main() { + is_defaulted::<&'static i32>(); + is_defaulted::<&'static u32>(); + //~^ ERROR `u32: Signed` is not satisfied +} diff --git a/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr b/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr new file mode 100644 index 000000000..985cdce12 --- /dev/null +++ b/src/test/ui/auto-traits/typeck-default-trait-impl-precedence.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `u32: Signed` is not satisfied + --> $DIR/typeck-default-trait-impl-precedence.rs:19:5 + | +LL | is_defaulted::<&'static u32>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32` + | + = help: the trait `Signed` is implemented for `i32` +note: required because of the requirements on the impl of `Defaulted` for `&'static u32` + --> $DIR/typeck-default-trait-impl-precedence.rs:10:19 + | +LL | impl<'a,T:Signed> Defaulted for &'a T { } + | ^^^^^^^^^ ^^^^^ +note: required by a bound in `is_defaulted` + --> $DIR/typeck-default-trait-impl-precedence.rs:12:19 + | +LL | fn is_defaulted<T:Defaulted>() { } + | ^^^^^^^^^ required by this bound in `is_defaulted` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. |