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/coherence | |
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/coherence')
232 files changed, 4275 insertions, 0 deletions
diff --git a/src/test/ui/coherence/auxiliary/coherence_copy_like_lib.rs b/src/test/ui/coherence/auxiliary/coherence_copy_like_lib.rs new file mode 100644 index 000000000..b5b4802c1 --- /dev/null +++ b/src/test/ui/coherence/auxiliary/coherence_copy_like_lib.rs @@ -0,0 +1,10 @@ +#![crate_type = "rlib"] +#![feature(fundamental)] + +pub trait MyCopy { } +impl MyCopy for i32 { } + +pub struct MyStruct<T>(T); + +#[fundamental] +pub struct MyFundamentalStruct<T>(T); diff --git a/src/test/ui/coherence/auxiliary/coherence_fundamental_trait_lib.rs b/src/test/ui/coherence/auxiliary/coherence_fundamental_trait_lib.rs new file mode 100644 index 000000000..21aaea479 --- /dev/null +++ b/src/test/ui/coherence/auxiliary/coherence_fundamental_trait_lib.rs @@ -0,0 +1,7 @@ +#![crate_type = "rlib"] +#![feature(fundamental)] + +pub trait Misc {} + +#[fundamental] +pub trait Fundamental<T> {} diff --git a/src/test/ui/coherence/auxiliary/coherence_inherent_cc_lib.rs b/src/test/ui/coherence/auxiliary/coherence_inherent_cc_lib.rs new file mode 100644 index 000000000..08d22fbed --- /dev/null +++ b/src/test/ui/coherence/auxiliary/coherence_inherent_cc_lib.rs @@ -0,0 +1,11 @@ +// See coherence_inherent_cc.rs + +pub trait TheTrait { + fn the_fn(&self); +} + +pub struct TheStruct; + +impl TheTrait for TheStruct { + fn the_fn(&self) {} +} diff --git a/src/test/ui/coherence/auxiliary/coherence_lib.rs b/src/test/ui/coherence/auxiliary/coherence_lib.rs new file mode 100644 index 000000000..c22819831 --- /dev/null +++ b/src/test/ui/coherence/auxiliary/coherence_lib.rs @@ -0,0 +1,15 @@ +#![crate_type="lib"] + +pub trait Remote { + fn foo(&self) { } +} + +pub trait Remote1<T> { + fn foo(&self, _t: T) { } +} + +pub trait Remote2<T, U> { + fn foo(&self, _t: T, _u: U) { } +} + +pub struct Pair<T,U>(T,U); diff --git a/src/test/ui/coherence/auxiliary/coherence_orphan_lib.rs b/src/test/ui/coherence/auxiliary/coherence_orphan_lib.rs new file mode 100644 index 000000000..2664ef550 --- /dev/null +++ b/src/test/ui/coherence/auxiliary/coherence_orphan_lib.rs @@ -0,0 +1,3 @@ +pub trait TheTrait<T> { + fn the_fn(&self); +} diff --git a/src/test/ui/coherence/auxiliary/error_lib.rs b/src/test/ui/coherence/auxiliary/error_lib.rs new file mode 100644 index 000000000..19ff9ae62 --- /dev/null +++ b/src/test/ui/coherence/auxiliary/error_lib.rs @@ -0,0 +1,6 @@ +#![crate_type = "lib"] +#![feature(negative_impls)] +#![feature(with_negative_coherence)] + +pub trait Error {} +impl !Error for &str {} diff --git a/src/test/ui/coherence/auxiliary/go_trait.rs b/src/test/ui/coherence/auxiliary/go_trait.rs new file mode 100644 index 000000000..aa0ec2289 --- /dev/null +++ b/src/test/ui/coherence/auxiliary/go_trait.rs @@ -0,0 +1,43 @@ +#![feature(specialization)] + +// Common code used for tests that model the Fn/FnMut/FnOnce hierarchy. + +pub trait Go { + fn go(&self, arg: isize); +} + +pub fn go<G:Go>(this: &G, arg: isize) { + this.go(arg) +} + +pub trait GoMut { + fn go_mut(&mut self, arg: isize); +} + +pub fn go_mut<G:GoMut>(this: &mut G, arg: isize) { + this.go_mut(arg) +} + +pub trait GoOnce { + fn go_once(self, arg: isize); +} + +pub fn go_once<G:GoOnce>(this: G, arg: isize) { + this.go_once(arg) +} + +impl<G> GoMut for G + where G : Go +{ + default fn go_mut(&mut self, arg: isize) { + go(&*self, arg) + } +} + +impl<G> GoOnce for G + where G : GoMut +{ + default fn go_once(mut self, arg: isize) { + go_mut(&mut self, arg) + } +} diff --git a/src/test/ui/coherence/auxiliary/option_future.rs b/src/test/ui/coherence/auxiliary/option_future.rs new file mode 100644 index 000000000..067de1cd8 --- /dev/null +++ b/src/test/ui/coherence/auxiliary/option_future.rs @@ -0,0 +1,8 @@ +#![crate_type = "lib"] +#![feature(negative_impls)] +#![feature(rustc_attrs)] +#![feature(with_negative_coherence)] + +pub trait Future {} + +impl<E> !Future for Option<E> where E: Sized {} diff --git a/src/test/ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs b/src/test/ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs new file mode 100644 index 000000000..9a191bad8 --- /dev/null +++ b/src/test/ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs @@ -0,0 +1,31 @@ +pub trait Backend {} +pub trait SupportsDefaultKeyword {} + +impl SupportsDefaultKeyword for Postgres {} + +pub struct Postgres; + +impl Backend for Postgres {} + +pub struct AstPass<DB>(::std::marker::PhantomData<DB>); + +pub trait QueryFragment<DB: Backend> {} + + +#[derive(Debug, Clone, Copy)] +pub struct BatchInsert<'a, T: 'a, Tab> { + _marker: ::std::marker::PhantomData<(&'a T, Tab)>, +} + +impl<'a, T:'a, Tab, DB> QueryFragment<DB> for BatchInsert<'a, T, Tab> +where DB: SupportsDefaultKeyword + Backend, +{} + +pub trait LibToOwned { + type Owned; +} + +pub struct LibCow<T: LibToOwned, Owned = <T as LibToOwned>::Owned> { + pub t: T, + pub o: Owned, +} diff --git a/src/test/ui/coherence/auxiliary/re_rebalance_coherence_lib.rs b/src/test/ui/coherence/auxiliary/re_rebalance_coherence_lib.rs new file mode 100644 index 000000000..41b9d64d5 --- /dev/null +++ b/src/test/ui/coherence/auxiliary/re_rebalance_coherence_lib.rs @@ -0,0 +1,22 @@ +pub trait Backend {} +pub trait SupportsDefaultKeyword {} + +impl SupportsDefaultKeyword for Postgres {} + +pub struct Postgres; + +impl Backend for Postgres {} + +pub struct AstPass<DB>(::std::marker::PhantomData<DB>); + +pub trait QueryFragment<DB: Backend> {} + + +#[derive(Debug, Clone, Copy)] +pub struct BatchInsert<'a, T: 'a, Tab> { + _marker: ::std::marker::PhantomData<(&'a T, Tab)>, +} + +impl<'a, T:'a, Tab, DB> QueryFragment<DB> for BatchInsert<'a, T, Tab> +where DB: SupportsDefaultKeyword + Backend, +{} diff --git a/src/test/ui/coherence/auxiliary/trait_impl_conflict.rs b/src/test/ui/coherence/auxiliary/trait_impl_conflict.rs new file mode 100644 index 000000000..5e5f017ed --- /dev/null +++ b/src/test/ui/coherence/auxiliary/trait_impl_conflict.rs @@ -0,0 +1,6 @@ +pub trait Foo { + fn foo() {} +} + +impl Foo for isize { +} diff --git a/src/test/ui/coherence/coherence-all-remote.rs b/src/test/ui/coherence/coherence-all-remote.rs new file mode 100644 index 000000000..5c3bfee82 --- /dev/null +++ b/src/test/ui/coherence/coherence-all-remote.rs @@ -0,0 +1,9 @@ +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::Remote1; + +impl<T> Remote1<T> for isize { } +//~^ ERROR E0210 + +fn main() { } diff --git a/src/test/ui/coherence/coherence-all-remote.stderr b/src/test/ui/coherence/coherence-all-remote.stderr new file mode 100644 index 000000000..7eca41753 --- /dev/null +++ b/src/test/ui/coherence/coherence-all-remote.stderr @@ -0,0 +1,12 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`) + --> $DIR/coherence-all-remote.rs:6:6 + | +LL | impl<T> Remote1<T> for isize { } + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/coherence-bigint-int.rs b/src/test/ui/coherence/coherence-bigint-int.rs new file mode 100644 index 000000000..02945e9da --- /dev/null +++ b/src/test/ui/coherence/coherence-bigint-int.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:coherence_lib.rs + +// pretty-expanded FIXME #23616 + +extern crate coherence_lib as lib; +use lib::Remote1; + +pub struct BigInt; + +impl Remote1<BigInt> for isize { } + +fn main() { } diff --git a/src/test/ui/coherence/coherence-bigint-param.rs b/src/test/ui/coherence/coherence-bigint-param.rs new file mode 100644 index 000000000..c6543aaf6 --- /dev/null +++ b/src/test/ui/coherence/coherence-bigint-param.rs @@ -0,0 +1,11 @@ +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::Remote1; + +pub struct BigInt; + +impl<T> Remote1<BigInt> for T { } +//~^ ERROR E0210 + +fn main() { } diff --git a/src/test/ui/coherence/coherence-bigint-param.stderr b/src/test/ui/coherence/coherence-bigint-param.stderr new file mode 100644 index 000000000..e8d74c917 --- /dev/null +++ b/src/test/ui/coherence/coherence-bigint-param.stderr @@ -0,0 +1,12 @@ +error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`BigInt`) + --> $DIR/coherence-bigint-param.rs:8:6 + | +LL | impl<T> Remote1<BigInt> for T { } + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`BigInt`) + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/coherence-bigint-vecint.rs b/src/test/ui/coherence/coherence-bigint-vecint.rs new file mode 100644 index 000000000..a5dba90be --- /dev/null +++ b/src/test/ui/coherence/coherence-bigint-vecint.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:coherence_lib.rs + +// pretty-expanded FIXME #23616 + +extern crate coherence_lib as lib; +use lib::Remote1; + +pub struct BigInt; + +impl Remote1<BigInt> for Vec<isize> { } + +fn main() { } diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.rs b/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.rs new file mode 100644 index 000000000..93a4bc5fe --- /dev/null +++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.rs @@ -0,0 +1,30 @@ +use std::fmt::Debug; +use std::default::Default; + +// Test that two blanket impls conflict (at least without negative +// bounds). After all, some other crate could implement Even or Odd +// for the same type (though this crate doesn't). + +trait MyTrait { + fn get(&self) -> usize; +} + +trait Even { } + +trait Odd { } + +impl Even for isize { } + +impl Odd for usize { } + +impl<T:Even> MyTrait for T { + fn get(&self) -> usize { 0 } +} + +impl<T:Odd> MyTrait for T { +//~^ ERROR E0119 + + fn get(&self) -> usize { 0 } +} + +fn main() { } diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.stderr new file mode 100644 index 000000000..9156972a1 --- /dev/null +++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `MyTrait` + --> $DIR/coherence-blanket-conflicts-with-blanket-implemented.rs:24:1 + | +LL | impl<T:Even> MyTrait for T { + | -------------------------- first implementation here +... +LL | impl<T:Odd> MyTrait for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.rs b/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.rs new file mode 100644 index 000000000..950a08ff2 --- /dev/null +++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.rs @@ -0,0 +1,25 @@ +use std::fmt::Debug; +use std::default::Default; + +// Test that two blanket impls conflict (at least without negative +// bounds). After all, some other crate could implement Even or Odd +// for the same type (though this crate doesn't implement them at all). + +trait MyTrait { + fn get(&self) -> usize; +} + +trait Even {} + +trait Odd {} + +impl<T:Even> MyTrait for T { + fn get(&self) -> usize { 0 } +} + +impl<T:Odd> MyTrait for T { +//~^ ERROR E0119 + fn get(&self) -> usize { 0 } +} + +fn main() { } diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.stderr new file mode 100644 index 000000000..8400968e1 --- /dev/null +++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `MyTrait` + --> $DIR/coherence-blanket-conflicts-with-blanket-unimplemented.rs:20:1 + | +LL | impl<T:Even> MyTrait for T { + | -------------------------- first implementation here +... +LL | impl<T:Odd> MyTrait for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.rs b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.rs new file mode 100644 index 000000000..bccbac2ff --- /dev/null +++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.rs @@ -0,0 +1,20 @@ +// aux-build:go_trait.rs + +extern crate go_trait; + +use go_trait::{Go,GoMut}; +use std::fmt::Debug; +use std::default::Default; + +struct MyThingy; + +impl Go for MyThingy { + fn go(&self, arg: isize) { } +} + +impl GoMut for MyThingy { +//~^ ERROR E0119 + fn go_mut(&mut self, arg: isize) { } +} + +fn main() { } diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr new file mode 100644 index 000000000..c25c43692 --- /dev/null +++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr @@ -0,0 +1,13 @@ +error[E0119]: conflicting implementations of trait `go_trait::GoMut` for type `MyThingy` + --> $DIR/coherence-blanket-conflicts-with-specific-cross-crate.rs:15:1 + | +LL | impl GoMut for MyThingy { + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `go_trait`: + - impl<G> GoMut for G + where G: Go; + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs new file mode 100644 index 000000000..6a9db2173 --- /dev/null +++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs @@ -0,0 +1,27 @@ +use std::fmt::Debug; +use std::default::Default; + +// Test that a blank impl for all T conflicts with an impl for some +// specific T, even when there are multiple type parameters involved. + +trait MyTrait<T> { + fn get(&self) -> T; +} + +impl<T> MyTrait<T> for T { + fn get(&self) -> T { + panic!() + } +} + +#[derive(Clone)] +struct MyType { + dummy: usize +} + +impl MyTrait<MyType> for MyType { +//~^ ERROR E0119 + fn get(&self) -> usize { (*self).clone() } +} + +fn main() { } diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr new file mode 100644 index 000000000..c2a925213 --- /dev/null +++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `MyTrait<MyType>` for type `MyType` + --> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:22:1 + | +LL | impl<T> MyTrait<T> for T { + | ------------------------ first implementation here +... +LL | impl MyTrait<MyType> for MyType { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyType` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.rs b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.rs new file mode 100644 index 000000000..02f9217da --- /dev/null +++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.rs @@ -0,0 +1,29 @@ +// Test that a blank impl for all T:PartialEq conflicts with an impl for some +// specific T when T:PartialEq. + +trait OtherTrait { + fn noop(&self); +} + +trait MyTrait { + fn get(&self) -> usize; +} + +impl<T:OtherTrait> MyTrait for T { + fn get(&self) -> usize { 0 } +} + +struct MyType { + dummy: usize +} + +impl MyTrait for MyType { +//~^ ERROR E0119 + fn get(&self) -> usize { self.dummy } +} + +impl OtherTrait for MyType { + fn noop(&self) { } +} + +fn main() { } diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.stderr new file mode 100644 index 000000000..e1a5dffeb --- /dev/null +++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `MyTrait` for type `MyType` + --> $DIR/coherence-blanket-conflicts-with-specific-trait.rs:20:1 + | +LL | impl<T:OtherTrait> MyTrait for T { + | -------------------------------- first implementation here +... +LL | impl MyTrait for MyType { + | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyType` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific.rs b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific.rs new file mode 100644 index 000000000..5a562ff6a --- /dev/null +++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific.rs @@ -0,0 +1,24 @@ +use std::fmt::Debug; +use std::default::Default; + +// Test that a blank impl for all T conflicts with an impl for some +// specific T. + +trait MyTrait { + fn get(&self) -> usize; +} + +impl<T> MyTrait for T { + fn get(&self) -> usize { 0 } +} + +struct MyType { + dummy: usize +} + +impl MyTrait for MyType { +//~^ ERROR E0119 + fn get(&self) -> usize { self.dummy } +} + +fn main() { } diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific.stderr new file mode 100644 index 000000000..ba60a2ea9 --- /dev/null +++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `MyTrait` for type `MyType` + --> $DIR/coherence-blanket-conflicts-with-specific.rs:19:1 + | +LL | impl<T> MyTrait for T { + | --------------------- first implementation here +... +LL | impl MyTrait for MyType { + | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyType` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-blanket.rs b/src/test/ui/coherence/coherence-blanket.rs new file mode 100644 index 000000000..55fa89d75 --- /dev/null +++ b/src/test/ui/coherence/coherence-blanket.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(unused_imports)] +// aux-build:coherence_lib.rs + +// pretty-expanded FIXME #23616 + +extern crate coherence_lib as lib; +use lib::Remote1; + +pub trait Local { + fn foo(&self) { } +} + +impl<T> Local for T { } + +fn main() { } diff --git a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.rs b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.rs new file mode 100644 index 000000000..24b878927 --- /dev/null +++ b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.rs @@ -0,0 +1,17 @@ +#![feature(negative_impls)] +#![feature(marker_trait_attr)] + +#[marker] +trait MyTrait {} + +struct TestType<T>(::std::marker::PhantomData<T>); + +unsafe impl<T: MyTrait + 'static> Send for TestType<T> {} + +impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR found both positive and negative implementation + +unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations + +impl !Send for TestType<i32> {} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr new file mode 100644 index 000000000..111019773 --- /dev/null +++ b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr @@ -0,0 +1,22 @@ +error[E0751]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`: + --> $DIR/coherence-conflicting-negative-trait-impl.rs:11:1 + | +LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {} + | ------------------------------------------------------ positive implementation here +LL | +LL | impl<T: MyTrait> !Send for TestType<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here + +error[E0119]: conflicting implementations of trait `std::marker::Send` for type `TestType<_>` + --> $DIR/coherence-conflicting-negative-trait-impl.rs:13:1 + | +LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {} + | ------------------------------------------------------ first implementation here +... +LL | unsafe impl<T: 'static> Send for TestType<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0119, E0751. +For more information about an error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-covered-type-parameter.rs b/src/test/ui/coherence/coherence-covered-type-parameter.rs new file mode 100644 index 000000000..bb95c59d1 --- /dev/null +++ b/src/test/ui/coherence/coherence-covered-type-parameter.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +// aux-build:coherence_lib.rs + +// pretty-expanded FIXME #23616 + +extern crate coherence_lib as lib; +use lib::Remote; + +struct Foo<T>(T); + +impl<T> Remote for Foo<T> { } + +fn main() { } diff --git a/src/test/ui/coherence/coherence-cow.re_a.stderr b/src/test/ui/coherence/coherence-cow.re_a.stderr new file mode 100644 index 000000000..fe4b5b410 --- /dev/null +++ b/src/test/ui/coherence/coherence-cow.re_a.stderr @@ -0,0 +1,14 @@ +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate + --> $DIR/coherence-cow.rs:18:1 + | +LL | impl<T> Remote for Pair<T,Cover<T>> { } + | ^^^^^^^^^^^^^^^^^^^---------------- + | | | + | | `Pair` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-cow.re_b.stderr b/src/test/ui/coherence/coherence-cow.re_b.stderr new file mode 100644 index 000000000..da4ede325 --- /dev/null +++ b/src/test/ui/coherence/coherence-cow.re_b.stderr @@ -0,0 +1,14 @@ +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate + --> $DIR/coherence-cow.rs:22:1 + | +LL | impl<T> Remote for Pair<Cover<T>,T> { } + | ^^^^^^^^^^^^^^^^^^^---------------- + | | | + | | `Pair` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-cow.re_c.stderr b/src/test/ui/coherence/coherence-cow.re_c.stderr new file mode 100644 index 000000000..d1a20c0ca --- /dev/null +++ b/src/test/ui/coherence/coherence-cow.re_c.stderr @@ -0,0 +1,14 @@ +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate + --> $DIR/coherence-cow.rs:26:1 + | +LL | impl<T,U> Remote for Pair<Cover<T>,U> { } + | ^^^^^^^^^^^^^^^^^^^^^---------------- + | | | + | | `Pair` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-cow.rs b/src/test/ui/coherence/coherence-cow.rs new file mode 100644 index 000000000..86a8d0963 --- /dev/null +++ b/src/test/ui/coherence/coherence-cow.rs @@ -0,0 +1,29 @@ +// revisions: re_a re_b re_c + +#![cfg_attr(any(), re_a, re_b, re_c)] + +// aux-build:coherence_lib.rs + +// Test that the `Pair` type reports an error if it contains type +// parameters, even when they are covered by local types. This test +// was originally intended to test the opposite, but the rules changed +// with RFC 1023 and this became illegal. + +extern crate coherence_lib as lib; +use lib::{Remote,Pair}; + +pub struct Cover<T>(T); + +#[cfg(any(re_a))] +impl<T> Remote for Pair<T,Cover<T>> { } +//[re_a]~^ ERROR E0117 + +#[cfg(any(re_b))] +impl<T> Remote for Pair<Cover<T>,T> { } +//[re_b]~^ ERROR E0117 + +#[cfg(any(re_c))] +impl<T,U> Remote for Pair<Cover<T>,U> { } +//[re_c]~^ ERROR E0117 + +fn main() { } diff --git a/src/test/ui/coherence/coherence-cross-crate-conflict.rs b/src/test/ui/coherence/coherence-cross-crate-conflict.rs new file mode 100644 index 000000000..588630957 --- /dev/null +++ b/src/test/ui/coherence/coherence-cross-crate-conflict.rs @@ -0,0 +1,13 @@ +// The error here is strictly due to orphan rules; the impl here +// generalizes the one upstream + +// aux-build:trait_impl_conflict.rs + +extern crate trait_impl_conflict; +use trait_impl_conflict::Foo; + +impl<A> Foo for A { //~ ERROR E0210 +} + +fn main() { +} diff --git a/src/test/ui/coherence/coherence-cross-crate-conflict.stderr b/src/test/ui/coherence/coherence-cross-crate-conflict.stderr new file mode 100644 index 000000000..3d253d56a --- /dev/null +++ b/src/test/ui/coherence/coherence-cross-crate-conflict.stderr @@ -0,0 +1,12 @@ +error[E0210]: type parameter `A` must be used as the type parameter for some local type (e.g., `MyStruct<A>`) + --> $DIR/coherence-cross-crate-conflict.rs:9:6 + | +LL | impl<A> Foo for A { + | ^ type parameter `A` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/coherence-default-trait-impl.rs b/src/test/ui/coherence/coherence-default-trait-impl.rs new file mode 100644 index 000000000..d57fb4777 --- /dev/null +++ b/src/test/ui/coherence/coherence-default-trait-impl.rs @@ -0,0 +1,16 @@ +#![feature(auto_traits)] +#![feature(negative_impls)] + +auto trait MySafeTrait {} + +struct Foo; + +unsafe impl MySafeTrait for Foo {} +//~^ ERROR E0199 + +unsafe auto trait MyUnsafeTrait {} + +impl MyUnsafeTrait for Foo {} +//~^ ERROR E0200 + +fn main() {} diff --git a/src/test/ui/coherence/coherence-default-trait-impl.stderr b/src/test/ui/coherence/coherence-default-trait-impl.stderr new file mode 100644 index 000000000..b08ccb087 --- /dev/null +++ b/src/test/ui/coherence/coherence-default-trait-impl.stderr @@ -0,0 +1,16 @@ +error[E0199]: implementing the trait `MySafeTrait` is not unsafe + --> $DIR/coherence-default-trait-impl.rs:8:1 + | +LL | unsafe impl MySafeTrait for Foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0200]: the trait `MyUnsafeTrait` requires an `unsafe impl` declaration + --> $DIR/coherence-default-trait-impl.rs:13:1 + | +LL | impl MyUnsafeTrait for Foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0199, E0200. +For more information about an error, try `rustc --explain E0199`. diff --git a/src/test/ui/coherence/coherence-error-suppression.rs b/src/test/ui/coherence/coherence-error-suppression.rs new file mode 100644 index 000000000..909214c1b --- /dev/null +++ b/src/test/ui/coherence/coherence-error-suppression.rs @@ -0,0 +1,16 @@ +// check that error types in coherence do not cause error cascades. + +trait Foo {} + +impl Foo for i8 {} +impl Foo for i16 {} +impl Foo for i32 {} +impl Foo for i64 {} +impl Foo for DoesNotExist {} +//~^ ERROR E0412 +impl Foo for u8 {} +impl Foo for u16 {} +impl Foo for u32 {} +impl Foo for u64 {} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-error-suppression.stderr b/src/test/ui/coherence/coherence-error-suppression.stderr new file mode 100644 index 000000000..aadc80cb1 --- /dev/null +++ b/src/test/ui/coherence/coherence-error-suppression.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `DoesNotExist` in this scope + --> $DIR/coherence-error-suppression.rs:9:14 + | +LL | impl Foo for DoesNotExist {} + | ^^^^^^^^^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.rs b/src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.rs new file mode 100644 index 000000000..99f805f7f --- /dev/null +++ b/src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.rs @@ -0,0 +1,26 @@ +// Test that impls for these two types are considered ovelapping: +// +// * `for<'r> fn(fn(&'r u32))` +// * `fn(fn(&'a u32)` where `'a` is free +// +// This is because, for `'a = 'static`, the two types overlap. +// Effectively for them to be equal to you get: +// +// * `for<'r> fn(fn(&'r u32)) <: fn(fn(&'static u32))` +// * true if `exists<'r> { 'r: 'static }` (obviously true) +// * `fn(fn(&'static u32)) <: for<'r> fn(fn(&'r u32))` +// * true if `forall<'r> { 'static: 'r }` (also true) + +trait Trait {} + +impl Trait for for<'r> fn(fn(&'r ())) {} +impl<'a> Trait for fn(fn(&'a ())) {} +//~^ ERROR conflicting implementations +// +// Note in particular that we do NOT get a future-compatibility warning +// here. This is because the new leak-check proposed in [MCP 295] does not +// "error" when these two types are equated. +// +// [MCP 295]: https://github.com/rust-lang/compiler-team/issues/295 + +fn main() {} diff --git a/src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr b/src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr new file mode 100644 index 000000000..cfcef9699 --- /dev/null +++ b/src/test/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr @@ -0,0 +1,13 @@ +error[E0119]: conflicting implementations of trait `Trait` for type `for<'r> fn(for<'r> fn(&'r ()))` + --> $DIR/coherence-fn-covariant-bound-vs-static.rs:17:1 + | +LL | impl Trait for for<'r> fn(fn(&'r ())) {} + | ------------------------------------- first implementation here +LL | impl<'a> Trait for fn(fn(&'a ())) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'r> fn(for<'r> fn(&'r ()))` + | + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-fn-implied-bounds.rs b/src/test/ui/coherence/coherence-fn-implied-bounds.rs new file mode 100644 index 000000000..4539af9a3 --- /dev/null +++ b/src/test/ui/coherence/coherence-fn-implied-bounds.rs @@ -0,0 +1,26 @@ +// Test that our leak-check is not smart enough to take implied bounds +// into account (yet). Here we have two types that look like they +// should not be equivalent, but because of the rules on implied +// bounds we ought to know that, in fact, `'a = 'b` must always hold, +// and hence they are. +// +// Rustc can't figure this out and hence it accepts the impls but +// gives a future-compatibility warning (because we'd like to make +// this an error someday). +// +// Note that while we would like to make this a hard error, we also +// give the same warning for `coherence-wasm-bindgen.rs`, which ought +// to be accepted. + +#![deny(coherence_leak_check)] + +trait Trait {} + +impl Trait for for<'a, 'b> fn(&'a &'b u32, &'b &'a u32) -> &'b u32 {} + +impl Trait for for<'c> fn(&'c &'c u32, &'c &'c u32) -> &'c u32 { + //~^ ERROR conflicting implementations + //~| WARNING this was previously accepted by the compiler +} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-fn-implied-bounds.stderr b/src/test/ui/coherence/coherence-fn-implied-bounds.stderr new file mode 100644 index 000000000..8612ce60d --- /dev/null +++ b/src/test/ui/coherence/coherence-fn-implied-bounds.stderr @@ -0,0 +1,20 @@ +error: conflicting implementations of trait `Trait` for type `for<'a, 'b> fn(&'a &'b u32, &'b &'a u32) -> &'b u32` + --> $DIR/coherence-fn-implied-bounds.rs:21:1 + | +LL | impl Trait for for<'a, 'b> fn(&'a &'b u32, &'b &'a u32) -> &'b u32 {} + | ------------------------------------------------------------------ first implementation here +LL | +LL | impl Trait for for<'c> fn(&'c &'c u32, &'c &'c u32) -> &'c u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a &'b u32, &'b &'a u32) -> &'b u32` + | +note: the lint level is defined here + --> $DIR/coherence-fn-implied-bounds.rs:15:9 + | +LL | #![deny(coherence_leak_check)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105> + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + +error: aborting due to previous error + diff --git a/src/test/ui/coherence/coherence-fn-inputs.rs b/src/test/ui/coherence/coherence-fn-inputs.rs new file mode 100644 index 000000000..3afec5c54 --- /dev/null +++ b/src/test/ui/coherence/coherence-fn-inputs.rs @@ -0,0 +1,25 @@ +// Test that we consider these two types completely equal: +// +// * `for<'a, 'b> fn(&'a u32, &'b u32)` +// * `for<'c> fn(&'c u32, &'c u32)` +// +// For a long time we considered these to be distinct types. But in fact they +// are equivalent, if you work through the implications of subtyping -- this is +// because: +// +// * `'c` can be the intersection of `'a` and `'b` (and there is always an intersection) +// * `'a` and `'b` can both be equal to `'c` + +trait Trait {} +impl Trait for for<'a, 'b> fn(&'a u32, &'b u32) {} +impl Trait for for<'c> fn(&'c u32, &'c u32) { + //~^ ERROR conflicting implementations + // + // Note in particular that we do NOT get a future-compatibility warning + // here. This is because the new leak-check proposed in [MCP 295] does not + // "error" when these two types are equated. + // + // [MCP 295]: https://github.com/rust-lang/compiler-team/issues/295 +} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-fn-inputs.stderr b/src/test/ui/coherence/coherence-fn-inputs.stderr new file mode 100644 index 000000000..82bd8a35f --- /dev/null +++ b/src/test/ui/coherence/coherence-fn-inputs.stderr @@ -0,0 +1,13 @@ +error[E0119]: conflicting implementations of trait `Trait` for type `for<'a, 'b> fn(&'a u32, &'b u32)` + --> $DIR/coherence-fn-inputs.rs:15:1 + | +LL | impl Trait for for<'a, 'b> fn(&'a u32, &'b u32) {} + | ----------------------------------------------- first implementation here +LL | impl Trait for for<'c> fn(&'c u32, &'c u32) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u32, &'b u32)` + | + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-free-vs-bound-region.rs b/src/test/ui/coherence/coherence-free-vs-bound-region.rs new file mode 100644 index 000000000..2f5c49d29 --- /dev/null +++ b/src/test/ui/coherence/coherence-free-vs-bound-region.rs @@ -0,0 +1,21 @@ +// Capture a coherence pattern from wasm-bindgen that we discovered as part of +// future-compatibility warning #56105. This pattern currently receives a lint +// warning but we probably want to support it long term. +// +// Key distinction: we are implementing once for `A` (take ownership) and one +// for `&A` (borrow). +// +// c.f. #56105 + +#![deny(coherence_leak_check)] + +trait TheTrait {} + +impl<'a> TheTrait for fn(&'a u8) {} + +impl TheTrait for fn(&u8) { + //~^ ERROR conflicting implementations of trait + //~| WARNING this was previously accepted by the compiler +} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-free-vs-bound-region.stderr b/src/test/ui/coherence/coherence-free-vs-bound-region.stderr new file mode 100644 index 000000000..af18655b0 --- /dev/null +++ b/src/test/ui/coherence/coherence-free-vs-bound-region.stderr @@ -0,0 +1,20 @@ +error: conflicting implementations of trait `TheTrait` for type `fn(&u8)` + --> $DIR/coherence-free-vs-bound-region.rs:16:1 + | +LL | impl<'a> TheTrait for fn(&'a u8) {} + | -------------------------------- first implementation here +LL | +LL | impl TheTrait for fn(&u8) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(&u8)` + | +note: the lint level is defined here + --> $DIR/coherence-free-vs-bound-region.rs:10:9 + | +LL | #![deny(coherence_leak_check)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105> + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + +error: aborting due to previous error + diff --git a/src/test/ui/coherence/coherence-fundamental-trait-objects.rs b/src/test/ui/coherence/coherence-fundamental-trait-objects.rs new file mode 100644 index 000000000..dd127bf7f --- /dev/null +++ b/src/test/ui/coherence/coherence-fundamental-trait-objects.rs @@ -0,0 +1,15 @@ +// Check that trait objects from #[fundamental] traits are not +// treated as #[fundamental] types - the 2 meanings of #[fundamental] +// are distinct. + +// aux-build:coherence_fundamental_trait_lib.rs + +extern crate coherence_fundamental_trait_lib; + +use coherence_fundamental_trait_lib::{Fundamental, Misc}; + +pub struct Local; +impl Misc for dyn Fundamental<Local> {} +//~^ ERROR E0117 + +fn main() {} diff --git a/src/test/ui/coherence/coherence-fundamental-trait-objects.stderr b/src/test/ui/coherence/coherence-fundamental-trait-objects.stderr new file mode 100644 index 000000000..a35a95ef4 --- /dev/null +++ b/src/test/ui/coherence/coherence-fundamental-trait-objects.stderr @@ -0,0 +1,14 @@ +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/coherence-fundamental-trait-objects.rs:12:1 + | +LL | impl Misc for dyn Fundamental<Local> {} + | ^^^^^^^^^^^^^^---------------------- + | | | + | | `dyn Fundamental<Local>` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-impl-in-fn.rs b/src/test/ui/coherence/coherence-impl-in-fn.rs new file mode 100644 index 000000000..b97197317 --- /dev/null +++ b/src/test/ui/coherence/coherence-impl-in-fn.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +pub fn main() { + #[derive(Copy, Clone)] + enum x { foo } + impl ::std::cmp::PartialEq for x { + fn eq(&self, other: &x) -> bool { + (*self) as isize == (*other) as isize + } + fn ne(&self, other: &x) -> bool { !(*self).eq(other) } + } +} diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs new file mode 100644 index 000000000..50d9a480a --- /dev/null +++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs @@ -0,0 +1,30 @@ +#![feature(auto_traits)] +#![feature(negative_impls)] + +// Test for issue #56934 - that it is impossible to redundantly +// implement an auto-trait for a trait object type that contains it. + +// Negative impl variant. + +auto trait Marker1 {} +auto trait Marker2 {} + +trait Object: Marker1 {} + +// A supertrait marker is illegal... +impl !Marker1 for dyn Object + Marker2 { } //~ ERROR E0371 +// ...and also a direct component. +impl !Marker2 for dyn Object + Marker2 { } //~ ERROR E0371 + +// But implementing a marker if it is not present is OK. +impl !Marker2 for dyn Object {} // OK + +// A non-principal trait-object type is orphan even in its crate. +impl !Send for dyn Marker2 {} //~ ERROR E0117 + +// And impl'ing a remote marker for a local trait object is forbidden +// by one of these special orphan-like rules. +impl !Send for dyn Object {} //~ ERROR E0321 +impl !Send for dyn Object + Marker2 {} //~ ERROR E0321 + +fn main() { } diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr new file mode 100644 index 000000000..c364c707f --- /dev/null +++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr @@ -0,0 +1,39 @@ +error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1` + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1 + | +LL | impl !Marker1 for dyn Object + Marker2 { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1` + +error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2` + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:17:1 + | +LL | impl !Marker2 for dyn Object + Marker2 { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2` + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:23:1 + | +LL | impl !Send for dyn Marker2 {} + | ^^^^^^^^^^^^^^^----------- + | | | + | | `dyn Marker2` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0321]: cross-crate traits with a default impl, like `Send`, can only be implemented for a struct/enum type, not `(dyn Object + 'static)` + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:27:1 + | +LL | impl !Send for dyn Object {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type + +error[E0321]: cross-crate traits with a default impl, like `Send`, can only be implemented for a struct/enum type, not `(dyn Object + Marker2 + 'static)` + --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:28:1 + | +LL | impl !Send for dyn Object + Marker2 {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0117, E0321, E0371. +For more information about an error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs new file mode 100644 index 000000000..faac6d983 --- /dev/null +++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs @@ -0,0 +1,30 @@ +#![feature(auto_traits)] +#![feature(negative_impls)] + +// Test for issue #56934 - that it is impossible to redundantly +// implement an auto-trait for a trait object type that contains it. + +// Positive impl variant. + +auto trait Marker1 {} +auto trait Marker2 {} + +trait Object: Marker1 {} + +// A supertrait marker is illegal... +impl Marker1 for dyn Object + Marker2 { } //~ ERROR E0371 +// ...and also a direct component. +impl Marker2 for dyn Object + Marker2 { } //~ ERROR E0371 + +// But implementing a marker if it is not present is OK. +impl Marker2 for dyn Object {} // OK + +// A non-principal trait-object type is orphan even in its crate. +unsafe impl Send for dyn Marker2 {} //~ ERROR E0117 + +// And impl'ing a remote marker for a local trait object is forbidden +// by one of these special orphan-like rules. +unsafe impl Send for dyn Object {} //~ ERROR E0321 +unsafe impl Send for dyn Object + Marker2 {} //~ ERROR E0321 + +fn main() { } diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr new file mode 100644 index 000000000..b80429794 --- /dev/null +++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr @@ -0,0 +1,39 @@ +error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1` + --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:15:1 + | +LL | impl Marker1 for dyn Object + Marker2 { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1` + +error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2` + --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:17:1 + | +LL | impl Marker2 for dyn Object + Marker2 { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2` + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:23:1 + | +LL | unsafe impl Send for dyn Marker2 {} + | ^^^^^^^^^^^^^^^^^^^^^----------- + | | | + | | `dyn Marker2` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0321]: cross-crate traits with a default impl, like `Send`, can only be implemented for a struct/enum type, not `(dyn Object + 'static)` + --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:27:1 + | +LL | unsafe impl Send for dyn Object {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type + +error[E0321]: cross-crate traits with a default impl, like `Send`, can only be implemented for a struct/enum type, not `(dyn Object + Marker2 + 'static)` + --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:28:1 + | +LL | unsafe impl Send for dyn Object + Marker2 {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0117, E0321, E0371. +For more information about an error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.rs b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.rs new file mode 100644 index 000000000..20ff87549 --- /dev/null +++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.rs @@ -0,0 +1,10 @@ +// Test that we give suitable error messages when the user attempts to +// impl a trait `Trait` for its own object type. + +// If the trait is not object-safe, we give a more tailored message +// because we're such schnuckels: +trait NotObjectSafe { fn eq(&self, other: Self); } +impl NotObjectSafe for dyn NotObjectSafe { } +//~^ ERROR E0038 + +fn main() { } diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr new file mode 100644 index 000000000..e9090c1b6 --- /dev/null +++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr @@ -0,0 +1,18 @@ +error[E0038]: the trait `NotObjectSafe` cannot be made into an object + --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:7:24 + | +LL | impl NotObjectSafe for dyn NotObjectSafe { } + | ^^^^^^^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:6:43 + | +LL | trait NotObjectSafe { fn eq(&self, other: Self); } + | ------------- ^^^^ ...because method `eq` references the `Self` type in this parameter + | | + | this trait cannot be made into an object... + = help: consider moving `eq` to another trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait.rs b/src/test/ui/coherence/coherence-impl-trait-for-trait.rs new file mode 100644 index 000000000..195a37f15 --- /dev/null +++ b/src/test/ui/coherence/coherence-impl-trait-for-trait.rs @@ -0,0 +1,20 @@ +// Test that we give suitable error messages when the user attempts to +// impl a trait `Trait` for its own object type. + +trait Foo { fn dummy(&self) { } } +trait Bar: Foo { } +trait Baz: Bar { } + +// Supertraits of Baz are not legal: +impl Foo for dyn Baz { } +//~^ ERROR E0371 +impl Bar for dyn Baz { } +//~^ ERROR E0371 +impl Baz for dyn Baz { } +//~^ ERROR E0371 + +// But other random traits are: +trait Other { } +impl Other for dyn Baz { } // OK, Other not a supertrait of Baz + +fn main() { } diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait.stderr new file mode 100644 index 000000000..cf0b38c5b --- /dev/null +++ b/src/test/ui/coherence/coherence-impl-trait-for-trait.stderr @@ -0,0 +1,21 @@ +error[E0371]: the object type `(dyn Baz + 'static)` automatically implements the trait `Foo` + --> $DIR/coherence-impl-trait-for-trait.rs:9:1 + | +LL | impl Foo for dyn Baz { } + | ^^^^^^^^^^^^^^^^^^^^ `(dyn Baz + 'static)` automatically implements trait `Foo` + +error[E0371]: the object type `(dyn Baz + 'static)` automatically implements the trait `Bar` + --> $DIR/coherence-impl-trait-for-trait.rs:11:1 + | +LL | impl Bar for dyn Baz { } + | ^^^^^^^^^^^^^^^^^^^^ `(dyn Baz + 'static)` automatically implements trait `Bar` + +error[E0371]: the object type `(dyn Baz + 'static)` automatically implements the trait `Baz` + --> $DIR/coherence-impl-trait-for-trait.rs:13:1 + | +LL | impl Baz for dyn Baz { } + | ^^^^^^^^^^^^^^^^^^^^ `(dyn Baz + 'static)` automatically implements trait `Baz` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0371`. diff --git a/src/test/ui/coherence/coherence-impls-copy.rs b/src/test/ui/coherence/coherence-impls-copy.rs new file mode 100644 index 000000000..4204fecc3 --- /dev/null +++ b/src/test/ui/coherence/coherence-impls-copy.rs @@ -0,0 +1,36 @@ +#![feature(negative_impls)] + +use std::marker::Copy; + +impl Copy for i32 {} +//~^ ERROR E0117 +enum TestE { + A +} + +struct MyType; + +struct NotSync; +impl !Sync for NotSync {} + +impl Copy for TestE {} +impl Clone for TestE { fn clone(&self) -> Self { *self } } + +impl Copy for MyType {} + +impl Copy for &'static mut MyType {} +//~^ ERROR E0206 +impl Clone for MyType { fn clone(&self) -> Self { *self } } + +impl Copy for (MyType, MyType) {} +//~^ ERROR E0206 +//~| ERROR E0117 +impl Copy for &'static NotSync {} +//~^ ERROR E0119 +impl Copy for [MyType] {} +//~^ ERROR E0206 +//~| ERROR E0117 +impl Copy for &'static [NotSync] {} +//~^ ERROR E0117 +fn main() { +} diff --git a/src/test/ui/coherence/coherence-impls-copy.stderr b/src/test/ui/coherence/coherence-impls-copy.stderr new file mode 100644 index 000000000..86356af25 --- /dev/null +++ b/src/test/ui/coherence/coherence-impls-copy.stderr @@ -0,0 +1,76 @@ +error[E0117]: only traits defined in the current crate can be implemented for primitive types + --> $DIR/coherence-impls-copy.rs:5:1 + | +LL | impl Copy for i32 {} + | ^^^^^^^^^^^^^^--- + | | | + | | `i32` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&NotSync` + --> $DIR/coherence-impls-copy.rs:28:1 + | +LL | impl Copy for &'static NotSync {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `core`: + - impl<T> Copy for &T + where T: ?Sized; + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/coherence-impls-copy.rs:33:1 + | +LL | impl Copy for &'static [NotSync] {} + | ^^^^^^^^^^^^^^------------------ + | | | + | | this is not defined in the current crate because slices are always foreign + | impl doesn't use only types from inside the current crate + | + = 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/coherence-impls-copy.rs:25:1 + | +LL | impl Copy for (MyType, MyType) {} + | ^^^^^^^^^^^^^^---------------- + | | | + | | this is not defined in the current crate because tuples are always foreign + | impl doesn't use only types from inside the current crate + | + = 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/coherence-impls-copy.rs:30:1 + | +LL | impl Copy for [MyType] {} + | ^^^^^^^^^^^^^^-------- + | | | + | | this is not defined in the current crate because slices are always foreign + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0206]: the trait `Copy` may not be implemented for this type + --> $DIR/coherence-impls-copy.rs:21:15 + | +LL | impl Copy for &'static mut MyType {} + | ^^^^^^^^^^^^^^^^^^^ type is not a structure or enumeration + +error[E0206]: the trait `Copy` may not be implemented for this type + --> $DIR/coherence-impls-copy.rs:25:15 + | +LL | impl Copy for (MyType, MyType) {} + | ^^^^^^^^^^^^^^^^ type is not a structure or enumeration + +error[E0206]: the trait `Copy` may not be implemented for this type + --> $DIR/coherence-impls-copy.rs:30:15 + | +LL | impl Copy for [MyType] {} + | ^^^^^^^^ type is not a structure or enumeration + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0117, E0119, E0206. +For more information about an error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-impls-send.rs b/src/test/ui/coherence/coherence-impls-send.rs new file mode 100644 index 000000000..b7b57c602 --- /dev/null +++ b/src/test/ui/coherence/coherence-impls-send.rs @@ -0,0 +1,28 @@ +#![feature(negative_impls)] + +use std::marker::Copy; + +enum TestE { + A, +} + +struct MyType; + +struct NotSync; +impl !Sync for NotSync {} + +unsafe impl Send for TestE {} +unsafe impl Send for MyType {} +unsafe impl Send for (MyType, MyType) {} +//~^ ERROR E0117 + +unsafe impl Send for &'static NotSync {} +//~^ ERROR E0321 + +unsafe impl Send for [MyType] {} +//~^ ERROR E0117 + +unsafe impl Send for &'static [NotSync] {} +//~^ ERROR only traits defined in the current crate + +fn main() {} diff --git a/src/test/ui/coherence/coherence-impls-send.stderr b/src/test/ui/coherence/coherence-impls-send.stderr new file mode 100644 index 000000000..e1071846e --- /dev/null +++ b/src/test/ui/coherence/coherence-impls-send.stderr @@ -0,0 +1,43 @@ +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/coherence-impls-send.rs:25:1 + | +LL | unsafe impl Send for &'static [NotSync] {} + | ^^^^^^^^^^^^^^^^^^^^^------------------ + | | | + | | this is not defined in the current crate because slices are always foreign + | impl doesn't use only types from inside the current crate + | + = 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/coherence-impls-send.rs:16:1 + | +LL | unsafe impl Send for (MyType, MyType) {} + | ^^^^^^^^^^^^^^^^^^^^^---------------- + | | | + | | this is not defined in the current crate because tuples are always foreign + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0321]: cross-crate traits with a default impl, like `Send`, can only be implemented for a struct/enum type, not `&'static NotSync` + --> $DIR/coherence-impls-send.rs:19:1 + | +LL | unsafe impl Send for &'static NotSync {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/coherence-impls-send.rs:22:1 + | +LL | unsafe impl Send for [MyType] {} + | ^^^^^^^^^^^^^^^^^^^^^-------- + | | | + | | this is not defined in the current crate because slices are always foreign + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0117, E0321. +For more information about an error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-impls-sized.rs b/src/test/ui/coherence/coherence-impls-sized.rs new file mode 100644 index 000000000..231b96ad4 --- /dev/null +++ b/src/test/ui/coherence/coherence-impls-sized.rs @@ -0,0 +1,36 @@ +#![feature(negative_impls)] + +use std::marker::Copy; + +enum TestE { + A +} + +struct MyType; + +struct NotSync; +impl !Sync for NotSync {} + +impl Sized for TestE {} +//~^ ERROR E0322 + +impl Sized for MyType {} +//~^ ERROR E0322 + +impl Sized for (MyType, MyType) {} +//~^ ERROR E0322 +//~| ERROR E0117 + +impl Sized for &'static NotSync {} +//~^ ERROR E0322 + +impl Sized for [MyType] {} +//~^ ERROR E0322 +//~| ERROR E0117 + +impl Sized for &'static [NotSync] {} +//~^ ERROR E0322 +//~| ERROR E0117 + +fn main() { +} diff --git a/src/test/ui/coherence/coherence-impls-sized.stderr b/src/test/ui/coherence/coherence-impls-sized.stderr new file mode 100644 index 000000000..17a754452 --- /dev/null +++ b/src/test/ui/coherence/coherence-impls-sized.stderr @@ -0,0 +1,73 @@ +error[E0322]: explicit impls for the `Sized` trait are not permitted + --> $DIR/coherence-impls-sized.rs:14:1 + | +LL | impl Sized for TestE {} + | ^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed + +error[E0322]: explicit impls for the `Sized` trait are not permitted + --> $DIR/coherence-impls-sized.rs:17:1 + | +LL | impl Sized for MyType {} + | ^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed + +error[E0322]: explicit impls for the `Sized` trait are not permitted + --> $DIR/coherence-impls-sized.rs:20:1 + | +LL | impl Sized for (MyType, MyType) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/coherence-impls-sized.rs:20:1 + | +LL | impl Sized for (MyType, MyType) {} + | ^^^^^^^^^^^^^^^---------------- + | | | + | | this is not defined in the current crate because tuples are always foreign + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0322]: explicit impls for the `Sized` trait are not permitted + --> $DIR/coherence-impls-sized.rs:24:1 + | +LL | impl Sized for &'static NotSync {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed + +error[E0322]: explicit impls for the `Sized` trait are not permitted + --> $DIR/coherence-impls-sized.rs:27:1 + | +LL | impl Sized for [MyType] {} + | ^^^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/coherence-impls-sized.rs:27:1 + | +LL | impl Sized for [MyType] {} + | ^^^^^^^^^^^^^^^-------- + | | | + | | this is not defined in the current crate because slices are always foreign + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0322]: explicit impls for the `Sized` trait are not permitted + --> $DIR/coherence-impls-sized.rs:31:1 + | +LL | impl Sized for &'static [NotSync] {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/coherence-impls-sized.rs:31:1 + | +LL | impl Sized for &'static [NotSync] {} + | ^^^^^^^^^^^^^^^------------------ + | | | + | | this is not defined in the current crate because slices are always foreign + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to 9 previous errors + +Some errors have detailed explanations: E0117, E0322. +For more information about an error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs b/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs new file mode 100644 index 000000000..d74d3a2a5 --- /dev/null +++ b/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs @@ -0,0 +1,24 @@ +// Formerly this ICEd with the following message: +// Tried to project an inherited associated type during coherence checking, +// which is currently not supported. +// +// No we expect to run into a more user-friendly cycle error instead. +#![feature(specialization)] +//~^ WARN the feature `specialization` is incomplete + +trait Trait<T> { type Assoc; } +//~^ ERROR E0391 + +impl<T> Trait<T> for Vec<T> { + type Assoc = (); +} + +impl Trait<u8> for Vec<u8> {} + +impl<T> Trait<T> for String { + type Assoc = (); +} + +impl Trait<<Vec<u8> as Trait<u8>>::Assoc> for String {} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr b/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr new file mode 100644 index 000000000..97f3c7593 --- /dev/null +++ b/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr @@ -0,0 +1,26 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:6:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information + = help: consider using `min_specialization` instead, which is more stable and complete + +error[E0391]: cycle detected when building specialization graph of trait `Trait` + --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:9:1 + | +LL | trait Trait<T> { type Assoc; } + | ^^^^^^^^^^^^^^ + | + = note: ...which immediately requires building specialization graph of trait `Trait` again +note: cycle used when coherence checking all impls of trait `Trait` + --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:9:1 + | +LL | trait Trait<T> { type Assoc; } + | ^^^^^^^^^^^^^^ + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/coherence/coherence-inherited-subtyping.old.stderr b/src/test/ui/coherence/coherence-inherited-subtyping.old.stderr new file mode 100644 index 000000000..4701bc0b1 --- /dev/null +++ b/src/test/ui/coherence/coherence-inherited-subtyping.old.stderr @@ -0,0 +1,14 @@ +error[E0592]: duplicate definitions with name `method1` + --> $DIR/coherence-inherited-subtyping.rs:14:5 + | +LL | fn method1(&self) {} + | ^^^^^^^^^^^^^^^^^ duplicate definitions for `method1` +... +LL | fn method1(&self) {} + | ----------------- other definition for `method1` + | + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0592`. diff --git a/src/test/ui/coherence/coherence-inherited-subtyping.re.stderr b/src/test/ui/coherence/coherence-inherited-subtyping.re.stderr new file mode 100644 index 000000000..4701bc0b1 --- /dev/null +++ b/src/test/ui/coherence/coherence-inherited-subtyping.re.stderr @@ -0,0 +1,14 @@ +error[E0592]: duplicate definitions with name `method1` + --> $DIR/coherence-inherited-subtyping.rs:14:5 + | +LL | fn method1(&self) {} + | ^^^^^^^^^^^^^^^^^ duplicate definitions for `method1` +... +LL | fn method1(&self) {} + | ----------------- other definition for `method1` + | + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0592`. diff --git a/src/test/ui/coherence/coherence-inherited-subtyping.rs b/src/test/ui/coherence/coherence-inherited-subtyping.rs new file mode 100644 index 000000000..8587eb779 --- /dev/null +++ b/src/test/ui/coherence/coherence-inherited-subtyping.rs @@ -0,0 +1,21 @@ +// Test that two distinct impls which match subtypes of one another +// yield coherence errors (or not) depending on the variance. +// +// Note: This scenario is currently accepted, but as part of the +// universe transition (#56105) may eventually become an error. + +// revisions: old re + +struct Foo<T> { + t: T, +} + +impl Foo<for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8> { + fn method1(&self) {} //~ ERROR duplicate definitions with name `method1` +} + +impl Foo<for<'a> fn(&'a u8, &'a u8) -> &'a u8> { + fn method1(&self) {} +} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-iterator-vec-any-elem.rs b/src/test/ui/coherence/coherence-iterator-vec-any-elem.rs new file mode 100644 index 000000000..43a0a5c42 --- /dev/null +++ b/src/test/ui/coherence/coherence-iterator-vec-any-elem.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +// aux-build:coherence_lib.rs + +// pretty-expanded FIXME #23616 + +extern crate coherence_lib as lib; +use lib::Remote1; + +struct Foo<T>(T); + +impl<T,U> Remote1<U> for Foo<T> { } + +fn main() { } diff --git a/src/test/ui/coherence/coherence-iterator-vec.rs b/src/test/ui/coherence/coherence-iterator-vec.rs new file mode 100644 index 000000000..386fe40ac --- /dev/null +++ b/src/test/ui/coherence/coherence-iterator-vec.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +// aux-build:coherence_lib.rs + +// pretty-expanded FIXME #23616 + +extern crate coherence_lib as lib; +use lib::Remote1; + +struct Foo<T>(T); + +impl<T> Remote1<T> for Foo<T> { } + +fn main() { } diff --git a/src/test/ui/coherence/coherence-lone-type-parameter.rs b/src/test/ui/coherence/coherence-lone-type-parameter.rs new file mode 100644 index 000000000..5368fef76 --- /dev/null +++ b/src/test/ui/coherence/coherence-lone-type-parameter.rs @@ -0,0 +1,10 @@ +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::Remote; + +impl<T> Remote for T { } +//~^ ERROR E0210 + + +fn main() { } diff --git a/src/test/ui/coherence/coherence-lone-type-parameter.stderr b/src/test/ui/coherence/coherence-lone-type-parameter.stderr new file mode 100644 index 000000000..ef5b08836 --- /dev/null +++ b/src/test/ui/coherence/coherence-lone-type-parameter.stderr @@ -0,0 +1,12 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`) + --> $DIR/coherence-lone-type-parameter.rs:6:6 + | +LL | impl<T> Remote for T { } + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/coherence-multidispatch-tuple.rs b/src/test/ui/coherence/coherence-multidispatch-tuple.rs new file mode 100644 index 000000000..fa1d4bbb4 --- /dev/null +++ b/src/test/ui/coherence/coherence-multidispatch-tuple.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(unused_imports)] +// pretty-expanded FIXME #23616 + +use std::fmt::Debug; +use std::default::Default; + +// Test that an impl for homogeneous pairs does not conflict with a +// heterogeneous pair. + +trait MyTrait { + fn get(&self) -> usize; +} + +impl<T> MyTrait for (T,T) { + fn get(&self) -> usize { 0 } +} + +impl MyTrait for (usize,isize) { + fn get(&self) -> usize { 0 } +} + +fn main() { +} diff --git a/src/test/ui/coherence/coherence-negative-impls-safe-rpass.rs b/src/test/ui/coherence/coherence-negative-impls-safe-rpass.rs new file mode 100644 index 000000000..b87e162ac --- /dev/null +++ b/src/test/ui/coherence/coherence-negative-impls-safe-rpass.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +#![feature(negative_impls)] + +use std::marker::Send; + +struct TestType; + +impl !Send for TestType {} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-negative-impls-safe.rs b/src/test/ui/coherence/coherence-negative-impls-safe.rs new file mode 100644 index 000000000..4821aa6b5 --- /dev/null +++ b/src/test/ui/coherence/coherence-negative-impls-safe.rs @@ -0,0 +1,10 @@ +#![feature(negative_impls)] + +use std::marker::Send; + +struct TestType; + +unsafe impl !Send for TestType {} +//~^ ERROR E0198 + +fn main() {} diff --git a/src/test/ui/coherence/coherence-negative-impls-safe.stderr b/src/test/ui/coherence/coherence-negative-impls-safe.stderr new file mode 100644 index 000000000..1bd37f395 --- /dev/null +++ b/src/test/ui/coherence/coherence-negative-impls-safe.stderr @@ -0,0 +1,12 @@ +error[E0198]: negative impls cannot be unsafe + --> $DIR/coherence-negative-impls-safe.rs:7:13 + | +LL | unsafe impl !Send for TestType {} + | ------ -^^^^ + | | | + | | negative because of this + | unsafe because of this + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0198`. diff --git a/src/test/ui/coherence/coherence-negative-inherent-where-bounds.rs b/src/test/ui/coherence/coherence-negative-inherent-where-bounds.rs new file mode 100644 index 000000000..39ccaa6ac --- /dev/null +++ b/src/test/ui/coherence/coherence-negative-inherent-where-bounds.rs @@ -0,0 +1,25 @@ +// check-pass + +#![feature(negative_impls)] +#![feature(rustc_attrs)] +#![feature(with_negative_coherence)] + +trait Foo {} + +impl !Foo for u32 {} + +#[rustc_strict_coherence] +struct MyStruct<T>(T); + +impl MyStruct<u32> { + fn method(&self) {} +} + +impl<T> MyStruct<T> +where + T: Foo, +{ + fn method(&self) {} +} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-negative-inherent.rs b/src/test/ui/coherence/coherence-negative-inherent.rs new file mode 100644 index 000000000..a9e1acc80 --- /dev/null +++ b/src/test/ui/coherence/coherence-negative-inherent.rs @@ -0,0 +1,22 @@ +// check-pass + +#![feature(negative_impls)] +#![feature(rustc_attrs)] +#![feature(with_negative_coherence)] + +#[rustc_strict_coherence] +trait Foo {} + +impl !Foo for u32 {} + +struct MyStruct<T>(T); + +impl<T: Foo> MyStruct<T> { + fn method(&self) {} +} + +impl MyStruct<u32> { + fn method(&self) {} +} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs new file mode 100644 index 000000000..159788b1b --- /dev/null +++ b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs @@ -0,0 +1,12 @@ +#![feature(negative_impls)] + +// FIXME: this should compile + +trait MyPredicate<'a> {} +impl<'a, T> !MyPredicate<'a> for &T where T: 'a {} +trait MyTrait<'a> {} +impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {} +impl<'a, T> MyTrait<'a> for &'a T {} +//~^ ERROR: conflicting implementations of trait `MyTrait<'_>` for type `&_` + +fn main() {} diff --git a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stderr b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stderr new file mode 100644 index 000000000..263bd19b4 --- /dev/null +++ b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stderr @@ -0,0 +1,11 @@ +error[E0119]: conflicting implementations of trait `MyTrait<'_>` for type `&_` + --> $DIR/coherence-negative-outlives-lifetimes.rs:9:1 + | +LL | impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {} + | ---------------------------------------------- first implementation here +LL | impl<'a, T> MyTrait<'a> for &'a T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.rs b/src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.rs new file mode 100644 index 000000000..d466dcac1 --- /dev/null +++ b/src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.rs @@ -0,0 +1,9 @@ +// Test that you cannot *directly* dispatch on lifetime requirements + +trait MyTrait { fn foo() {} } + +impl<T> MyTrait for T {} +impl<T: 'static> MyTrait for T {} +//~^ ERROR E0119 + +fn main() {} diff --git a/src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.stderr b/src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.stderr new file mode 100644 index 000000000..8a43ad7b7 --- /dev/null +++ b/src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.stderr @@ -0,0 +1,11 @@ +error[E0119]: conflicting implementations of trait `MyTrait` + --> $DIR/coherence-no-direct-lifetime-dispatch.rs:6:1 + | +LL | impl<T> MyTrait for T {} + | --------------------- first implementation here +LL | impl<T: 'static> MyTrait for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-orphan.rs b/src/test/ui/coherence/coherence-orphan.rs new file mode 100644 index 000000000..3beac04c7 --- /dev/null +++ b/src/test/ui/coherence/coherence-orphan.rs @@ -0,0 +1,20 @@ +// aux-build:coherence_orphan_lib.rs +#![feature(negative_impls)] + +extern crate coherence_orphan_lib as lib; + +use lib::TheTrait; + +struct TheType; + +impl TheTrait<usize> for isize { } +//~^ ERROR E0117 + +impl TheTrait<TheType> for isize { } + +impl TheTrait<isize> for TheType { } + +impl !Send for Vec<isize> { } +//~^ ERROR E0117 + +fn main() { } diff --git a/src/test/ui/coherence/coherence-orphan.stderr b/src/test/ui/coherence/coherence-orphan.stderr new file mode 100644 index 000000000..01f166a21 --- /dev/null +++ b/src/test/ui/coherence/coherence-orphan.stderr @@ -0,0 +1,26 @@ +error[E0117]: only traits defined in the current crate can be implemented for primitive types + --> $DIR/coherence-orphan.rs:10:1 + | +LL | impl TheTrait<usize> for isize { } + | ^^^^^---------------^^^^^----- + | | | | + | | | `isize` is not defined in the current crate + | | `usize` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate + --> $DIR/coherence-orphan.rs:17:1 + | +LL | impl !Send for Vec<isize> { } + | ^^^^^^^^^^^^^^^---------- + | | | + | | `Vec` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-overlap-all-t-and-tuple.rs b/src/test/ui/coherence/coherence-overlap-all-t-and-tuple.rs new file mode 100644 index 000000000..574a16a19 --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-all-t-and-tuple.rs @@ -0,0 +1,20 @@ +// Check that we detect an overlap here in the case where: +// +// for some type X: +// T = (X,) +// T11 = X, U11 = X +// +// Seems pretty basic, but then there was issue #24241. :) + +trait From<U> { + fn foo() {} +} + +impl <T> From<T> for T { +} + +impl <T11, U11> From<(U11,)> for (T11,) { +//~^ ERROR E0119 +} + +fn main() { } diff --git a/src/test/ui/coherence/coherence-overlap-all-t-and-tuple.stderr b/src/test/ui/coherence/coherence-overlap-all-t-and-tuple.stderr new file mode 100644 index 000000000..6a0880334 --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-all-t-and-tuple.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `From<(_,)>` for type `(_,)` + --> $DIR/coherence-overlap-all-t-and-tuple.rs:16:1 + | +LL | impl <T> From<T> for T { + | ---------------------- first implementation here +... +LL | impl <T11, U11> From<(U11,)> for (T11,) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(_,)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-overlap-double-negative.rs b/src/test/ui/coherence/coherence-overlap-double-negative.rs new file mode 100644 index 000000000..1ea0ddc74 --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-double-negative.rs @@ -0,0 +1,12 @@ +// check-pass + +#![feature(negative_impls)] +#![feature(with_negative_coherence)] + +trait A {} +trait B: A {} + +impl !A for u32 {} +impl !B for u32 {} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-overlap-downstream-inherent.rs b/src/test/ui/coherence/coherence-overlap-downstream-inherent.rs new file mode 100644 index 000000000..5dea33e33 --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-downstream-inherent.rs @@ -0,0 +1,17 @@ +// Tests that we consider `T: Sugar + Fruit` to be ambiguous, even +// though no impls are found. + +struct Sweet<X>(X); +pub trait Sugar {} +pub trait Fruit {} +impl<T:Sugar> Sweet<T> { fn dummy(&self) { } } +//~^ ERROR E0592 +impl<T:Fruit> Sweet<T> { fn dummy(&self) { } } + +trait Bar<X> {} +struct A<T, X>(T, X); +impl<X, T> A<T, X> where T: Bar<X> { fn f(&self) {} } +//~^ ERROR E0592 +impl<X> A<i32, X> { fn f(&self) {} } + +fn main() {} diff --git a/src/test/ui/coherence/coherence-overlap-downstream-inherent.stderr b/src/test/ui/coherence/coherence-overlap-downstream-inherent.stderr new file mode 100644 index 000000000..bbce4b530 --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-downstream-inherent.stderr @@ -0,0 +1,23 @@ +error[E0592]: duplicate definitions with name `dummy` + --> $DIR/coherence-overlap-downstream-inherent.rs:7:26 + | +LL | impl<T:Sugar> Sweet<T> { fn dummy(&self) { } } + | ^^^^^^^^^^^^^^^ duplicate definitions for `dummy` +LL | +LL | impl<T:Fruit> Sweet<T> { fn dummy(&self) { } } + | --------------- other definition for `dummy` + +error[E0592]: duplicate definitions with name `f` + --> $DIR/coherence-overlap-downstream-inherent.rs:13:38 + | +LL | impl<X, T> A<T, X> where T: Bar<X> { fn f(&self) {} } + | ^^^^^^^^^^^ duplicate definitions for `f` +LL | +LL | impl<X> A<i32, X> { fn f(&self) {} } + | ----------- other definition for `f` + | + = note: downstream crates may implement trait `Bar<_>` for type `i32` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0592`. diff --git a/src/test/ui/coherence/coherence-overlap-downstream.rs b/src/test/ui/coherence/coherence-overlap-downstream.rs new file mode 100644 index 000000000..738ec0e3d --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-downstream.rs @@ -0,0 +1,17 @@ +// Tests that we consider `T: Sugar + Fruit` to be ambiguous, even +// though no impls are found. + +pub trait Sugar {} +pub trait Fruit {} +pub trait Sweet {} +impl<T:Sugar> Sweet for T { } +impl<T:Fruit> Sweet for T { } +//~^ ERROR E0119 + +pub trait Foo<X> {} +pub trait Bar<X> {} +impl<X, T> Foo<X> for T where T: Bar<X> {} +impl<X> Foo<X> for i32 {} +//~^ ERROR E0119 + +fn main() { } diff --git a/src/test/ui/coherence/coherence-overlap-downstream.stderr b/src/test/ui/coherence/coherence-overlap-downstream.stderr new file mode 100644 index 000000000..7f373e595 --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-downstream.stderr @@ -0,0 +1,21 @@ +error[E0119]: conflicting implementations of trait `Sweet` + --> $DIR/coherence-overlap-downstream.rs:8:1 + | +LL | impl<T:Sugar> Sweet for T { } + | ------------------------- first implementation here +LL | impl<T:Fruit> Sweet for T { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + +error[E0119]: conflicting implementations of trait `Foo<_>` for type `i32` + --> $DIR/coherence-overlap-downstream.rs:14:1 + | +LL | impl<X, T> Foo<X> for T where T: Bar<X> {} + | ----------------------- first implementation here +LL | impl<X> Foo<X> for i32 {} + | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32` + | + = note: downstream crates may implement trait `Bar<_>` for type `i32` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-overlap-issue-23516-inherent.rs b/src/test/ui/coherence/coherence-overlap-issue-23516-inherent.rs new file mode 100644 index 000000000..a272e620f --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-issue-23516-inherent.rs @@ -0,0 +1,13 @@ +// Tests that we consider `Box<U>: !Sugar` to be ambiguous, even +// though we see no impl of `Sugar` for `Box`. Therefore, an overlap +// error is reported for the following pair of impls (#23516). + +pub trait Sugar {} + +struct Cake<X>(X); + +impl<T:Sugar> Cake<T> { fn dummy(&self) { } } +//~^ ERROR E0592 +impl<U:Sugar> Cake<Box<U>> { fn dummy(&self) { } } + +fn main() { } diff --git a/src/test/ui/coherence/coherence-overlap-issue-23516-inherent.stderr b/src/test/ui/coherence/coherence-overlap-issue-23516-inherent.stderr new file mode 100644 index 000000000..3ad818cbc --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-issue-23516-inherent.stderr @@ -0,0 +1,14 @@ +error[E0592]: duplicate definitions with name `dummy` + --> $DIR/coherence-overlap-issue-23516-inherent.rs:9:25 + | +LL | impl<T:Sugar> Cake<T> { fn dummy(&self) { } } + | ^^^^^^^^^^^^^^^ duplicate definitions for `dummy` +LL | +LL | impl<U:Sugar> Cake<Box<U>> { fn dummy(&self) { } } + | --------------- other definition for `dummy` + | + = note: downstream crates may implement trait `Sugar` for type `std::boxed::Box<_>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0592`. diff --git a/src/test/ui/coherence/coherence-overlap-issue-23516.rs b/src/test/ui/coherence/coherence-overlap-issue-23516.rs new file mode 100644 index 000000000..63e42e8f4 --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-issue-23516.rs @@ -0,0 +1,11 @@ +// Tests that we consider `Box<U>: !Sugar` to be ambiguous, even +// though we see no impl of `Sugar` for `Box`. Therefore, an overlap +// error is reported for the following pair of impls (#23516). + +pub trait Sugar { fn dummy(&self) { } } +pub trait Sweet { fn dummy(&self) { } } +impl<T:Sugar> Sweet for T { } +impl<U:Sugar> Sweet for Box<U> { } +//~^ ERROR E0119 + +fn main() { } diff --git a/src/test/ui/coherence/coherence-overlap-issue-23516.stderr b/src/test/ui/coherence/coherence-overlap-issue-23516.stderr new file mode 100644 index 000000000..85eb189e1 --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-issue-23516.stderr @@ -0,0 +1,13 @@ +error[E0119]: conflicting implementations of trait `Sweet` for type `std::boxed::Box<_>` + --> $DIR/coherence-overlap-issue-23516.rs:8:1 + | +LL | impl<T:Sugar> Sweet for T { } + | ------------------------- first implementation here +LL | impl<U:Sugar> Sweet for Box<U> { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::boxed::Box<_>` + | + = note: downstream crates may implement trait `Sugar` for type `std::boxed::Box<_>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-overlap-messages.rs b/src/test/ui/coherence/coherence-overlap-messages.rs new file mode 100644 index 000000000..1258a2371 --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-messages.rs @@ -0,0 +1,28 @@ +trait Foo { fn foo() {} } + +impl<T> Foo for T {} +impl<U> Foo for U {} +//~^ ERROR E0119 + + +trait Bar { fn bar() {} } + +impl<T> Bar for (T, u8) {} +impl<T> Bar for (u8, T) {} +//~^ ERROR E0119 + +trait Baz<T> { fn baz() {} } + +impl<T> Baz<u8> for T {} +impl<T> Baz<T> for u8 {} +//~^ ERROR E0119 + +trait Quux<U, V> { fn quux() {} } + +impl<T, U, V> Quux<U, V> for T {} +impl<T, U> Quux<U, U> for T {} +//~^ ERROR E0119 +impl<T, V> Quux<T, V> for T {} +//~^ ERROR E0119 + +fn main() {} diff --git a/src/test/ui/coherence/coherence-overlap-messages.stderr b/src/test/ui/coherence/coherence-overlap-messages.stderr new file mode 100644 index 000000000..5a97296ee --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-messages.stderr @@ -0,0 +1,44 @@ +error[E0119]: conflicting implementations of trait `Foo` + --> $DIR/coherence-overlap-messages.rs:4:1 + | +LL | impl<T> Foo for T {} + | ----------------- first implementation here +LL | impl<U> Foo for U {} + | ^^^^^^^^^^^^^^^^^ conflicting implementation + +error[E0119]: conflicting implementations of trait `Bar` for type `(u8, u8)` + --> $DIR/coherence-overlap-messages.rs:11:1 + | +LL | impl<T> Bar for (T, u8) {} + | ----------------------- first implementation here +LL | impl<T> Bar for (u8, T) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(u8, u8)` + +error[E0119]: conflicting implementations of trait `Baz<u8>` for type `u8` + --> $DIR/coherence-overlap-messages.rs:17:1 + | +LL | impl<T> Baz<u8> for T {} + | --------------------- first implementation here +LL | impl<T> Baz<T> for u8 {} + | ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u8` + +error[E0119]: conflicting implementations of trait `Quux<_, _>` + --> $DIR/coherence-overlap-messages.rs:23:1 + | +LL | impl<T, U, V> Quux<U, V> for T {} + | ------------------------------ first implementation here +LL | impl<T, U> Quux<U, U> for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + +error[E0119]: conflicting implementations of trait `Quux<_, _>` + --> $DIR/coherence-overlap-messages.rs:25:1 + | +LL | impl<T, U, V> Quux<U, V> for T {} + | ------------------------------ first implementation here +... +LL | impl<T, V> Quux<T, V> for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-overlap-negate-alias-strict.rs b/src/test/ui/coherence/coherence-overlap-negate-alias-strict.rs new file mode 100644 index 000000000..48dffc921 --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-negate-alias-strict.rs @@ -0,0 +1,19 @@ +// check-pass + +#![feature(negative_impls)] +#![feature(rustc_attrs)] +#![feature(trait_alias)] +#![feature(with_negative_coherence)] + +trait A {} +trait B {} +trait AB = A + B; + +impl !A for u32 {} + +#[rustc_strict_coherence] +trait C {} +impl<T: AB> C for T {} +impl C for u32 {} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-overlap-negate-not-use-feature-gate.rs b/src/test/ui/coherence/coherence-overlap-negate-not-use-feature-gate.rs new file mode 100644 index 000000000..a067736f6 --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-negate-not-use-feature-gate.rs @@ -0,0 +1,8 @@ +use std::ops::DerefMut; + +trait Foo {} +impl<T: DerefMut> Foo for T {} +impl<U> Foo for &U {} +//~^ ERROR: conflicting implementations of trait `Foo` for type `&_` [E0119] + +fn main() {} diff --git a/src/test/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr b/src/test/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr new file mode 100644 index 000000000..4b55001ec --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr @@ -0,0 +1,11 @@ +error[E0119]: conflicting implementations of trait `Foo` for type `&_` + --> $DIR/coherence-overlap-negate-not-use-feature-gate.rs:5:1 + | +LL | impl<T: DerefMut> Foo for T {} + | --------------------------- first implementation here +LL | impl<U> Foo for &U {} + | ^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-overlap-negate-strict.rs b/src/test/ui/coherence/coherence-overlap-negate-strict.rs new file mode 100644 index 000000000..1021d87ca --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-negate-strict.rs @@ -0,0 +1,18 @@ +// check-pass + +#![feature(negative_impls)] +#![feature(rustc_attrs)] +#![feature(trait_alias)] +#![feature(with_negative_coherence)] + +trait A {} +trait B {} + +impl !A for u32 {} + +#[rustc_strict_coherence] +trait C {} +impl<T: A + B> C for T {} +impl C for u32 {} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-overlap-negate-use-feature-gate.rs b/src/test/ui/coherence/coherence-overlap-negate-use-feature-gate.rs new file mode 100644 index 000000000..a0dd881d1 --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-negate-use-feature-gate.rs @@ -0,0 +1,11 @@ +// check-pass + +#![feature(with_negative_coherence)] + +use std::ops::DerefMut; + +trait Foo {} +impl<T: DerefMut> Foo for T {} +impl<U> Foo for &U {} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-overlap-negative-trait.rs b/src/test/ui/coherence/coherence-overlap-negative-trait.rs new file mode 100644 index 000000000..8059d23ff --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-negative-trait.rs @@ -0,0 +1,16 @@ +// check-pass +// aux-build:error_lib.rs +// +// Check that if we promise to not impl what would overlap it doesn't actually overlap + +#![feature(with_negative_coherence)] + +extern crate error_lib as lib; +use lib::Error; + +trait From<T> {} + +impl From<&str> for Box<dyn Error> {} +impl<E> From<E> for Box<dyn Error> where E: Error {} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-overlap-negative-trait2.rs b/src/test/ui/coherence/coherence-overlap-negative-trait2.rs new file mode 100644 index 000000000..cc8c463b8 --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-negative-trait2.rs @@ -0,0 +1,17 @@ +// check-pass +// aux-build:option_future.rs +// +// Check that if we promise to not impl what would overlap it doesn't actually overlap + +#![feature(rustc_attrs)] +#![feature(with_negative_coherence)] + +extern crate option_future as lib; +use lib::Future; + +trait Termination {} + +impl<E> Termination for Option<E> where E: Sized {} +impl<F> Termination for F where F: Future + Sized {} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-overlap-super-negative.rs b/src/test/ui/coherence/coherence-overlap-super-negative.rs new file mode 100644 index 000000000..d296a094a --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-super-negative.rs @@ -0,0 +1,18 @@ +// check-pass + +#![feature(negative_impls)] +#![feature(rustc_attrs)] +#![feature(with_negative_coherence)] + +trait Trait1: Trait2 {} +trait Trait2 {} + +struct MyType {} +impl !Trait2 for MyType {} + +#[rustc_strict_coherence] +trait Foo {} +impl<T: Trait1> Foo for T {} +impl Foo for MyType {} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-overlap-trait-alias.rs b/src/test/ui/coherence/coherence-overlap-trait-alias.rs new file mode 100644 index 000000000..9d9c76af9 --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-trait-alias.rs @@ -0,0 +1,20 @@ +#![feature(rustc_attrs)] +#![feature(trait_alias)] +#![feature(with_negative_coherence)] + +trait A {} +trait B {} +trait AB = A + B; + +impl A for u32 {} +impl B for u32 {} + +#[rustc_strict_coherence] +trait C {} +impl<T: AB> C for T {} +impl C for u32 {} +//~^ ERROR +// FIXME it's giving an ungreat error but unsure if we care given that it's using an internal rustc +// attribute and an artificial code path for testing purposes + +fn main() {} diff --git a/src/test/ui/coherence/coherence-overlap-trait-alias.stderr b/src/test/ui/coherence/coherence-overlap-trait-alias.stderr new file mode 100644 index 000000000..e324c1e79 --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-trait-alias.stderr @@ -0,0 +1,17 @@ +error[E0283]: type annotations needed: cannot satisfy `u32: C` + --> $DIR/coherence-overlap-trait-alias.rs:15:6 + | +LL | impl C for u32 {} + | ^ + | +note: multiple `impl`s satisfying `u32: C` found + --> $DIR/coherence-overlap-trait-alias.rs:14:1 + | +LL | impl<T: AB> C for T {} + | ^^^^^^^^^^^^^^^^^^^ +LL | impl C for u32 {} + | ^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/coherence/coherence-overlap-upstream-inherent.rs b/src/test/ui/coherence/coherence-overlap-upstream-inherent.rs new file mode 100644 index 000000000..082d753de --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-upstream-inherent.rs @@ -0,0 +1,16 @@ +// Tests that we consider `i16: Remote` to be ambiguous, even +// though the upstream crate doesn't implement it for now. + +// aux-build:coherence_lib.rs + + +extern crate coherence_lib; + +use coherence_lib::Remote; + +struct A<X>(X); +impl<T> A<T> where T: Remote { fn dummy(&self) { } } +//~^ ERROR E0592 +impl A<i16> { fn dummy(&self) { } } + +fn main() {} diff --git a/src/test/ui/coherence/coherence-overlap-upstream-inherent.stderr b/src/test/ui/coherence/coherence-overlap-upstream-inherent.stderr new file mode 100644 index 000000000..f355c6e85 --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-upstream-inherent.stderr @@ -0,0 +1,14 @@ +error[E0592]: duplicate definitions with name `dummy` + --> $DIR/coherence-overlap-upstream-inherent.rs:12:32 + | +LL | impl<T> A<T> where T: Remote { fn dummy(&self) { } } + | ^^^^^^^^^^^^^^^ duplicate definitions for `dummy` +LL | +LL | impl A<i16> { fn dummy(&self) { } } + | --------------- other definition for `dummy` + | + = note: upstream crates may add a new impl of trait `coherence_lib::Remote` for type `i16` in future versions + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0592`. diff --git a/src/test/ui/coherence/coherence-overlap-upstream.rs b/src/test/ui/coherence/coherence-overlap-upstream.rs new file mode 100644 index 000000000..8f1e6558b --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-upstream.rs @@ -0,0 +1,16 @@ +// Tests that we consider `i16: Remote` to be ambiguous, even +// though the upstream crate doesn't implement it for now. + +// aux-build:coherence_lib.rs + + +extern crate coherence_lib; + +use coherence_lib::Remote; + +trait Foo {} +impl<T> Foo for T where T: Remote {} +impl Foo for i16 {} +//~^ ERROR E0119 + +fn main() {} diff --git a/src/test/ui/coherence/coherence-overlap-upstream.stderr b/src/test/ui/coherence/coherence-overlap-upstream.stderr new file mode 100644 index 000000000..f6145c188 --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-upstream.stderr @@ -0,0 +1,13 @@ +error[E0119]: conflicting implementations of trait `Foo` for type `i16` + --> $DIR/coherence-overlap-upstream.rs:13:1 + | +LL | impl<T> Foo for T where T: Remote {} + | ----------------- first implementation here +LL | impl Foo for i16 {} + | ^^^^^^^^^^^^^^^^ conflicting implementation for `i16` + | + = note: upstream crates may add a new impl of trait `coherence_lib::Remote` for type `i16` in future versions + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-overlap-with-regions.rs b/src/test/ui/coherence/coherence-overlap-with-regions.rs new file mode 100644 index 000000000..32f01f418 --- /dev/null +++ b/src/test/ui/coherence/coherence-overlap-with-regions.rs @@ -0,0 +1,16 @@ +// check-pass + +#![feature(negative_impls)] +#![feature(rustc_attrs)] +#![feature(with_negative_coherence)] + +#[rustc_strict_coherence] +trait Foo {} +impl<T> !Foo for &T where T: 'static {} + +#[rustc_strict_coherence] +trait Bar {} +impl<T: Foo> Bar for T {} +impl<T> Bar for &T where T: 'static {} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-overlapping-pairs.rs b/src/test/ui/coherence/coherence-overlapping-pairs.rs new file mode 100644 index 000000000..d5d18217b --- /dev/null +++ b/src/test/ui/coherence/coherence-overlapping-pairs.rs @@ -0,0 +1,11 @@ +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::Remote; + +struct Foo; + +impl<T> Remote for lib::Pair<T,Foo> { } +//~^ ERROR E0117 + +fn main() { } diff --git a/src/test/ui/coherence/coherence-overlapping-pairs.stderr b/src/test/ui/coherence/coherence-overlapping-pairs.stderr new file mode 100644 index 000000000..15c92dfeb --- /dev/null +++ b/src/test/ui/coherence/coherence-overlapping-pairs.stderr @@ -0,0 +1,14 @@ +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate + --> $DIR/coherence-overlapping-pairs.rs:8:1 + | +LL | impl<T> Remote for lib::Pair<T,Foo> { } + | ^^^^^^^^^^^^^^^^^^^---------------- + | | | + | | `Pair` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-pair-covered-uncovered-1.rs b/src/test/ui/coherence/coherence-pair-covered-uncovered-1.rs new file mode 100644 index 000000000..15868ca86 --- /dev/null +++ b/src/test/ui/coherence/coherence-pair-covered-uncovered-1.rs @@ -0,0 +1,15 @@ +// Test that the same coverage rules apply even if the local type appears in the +// list of type parameters, not the self type. + +// aux-build:coherence_lib.rs + + +extern crate coherence_lib as lib; +use lib::{Remote1, Pair}; + +pub struct Local<T>(T); + +impl<T, U> Remote1<Pair<T, Local<U>>> for i32 { } +//~^ ERROR E0117 + +fn main() { } diff --git a/src/test/ui/coherence/coherence-pair-covered-uncovered-1.stderr b/src/test/ui/coherence/coherence-pair-covered-uncovered-1.stderr new file mode 100644 index 000000000..03d787123 --- /dev/null +++ b/src/test/ui/coherence/coherence-pair-covered-uncovered-1.stderr @@ -0,0 +1,15 @@ +error[E0117]: only traits defined in the current crate can be implemented for primitive types + --> $DIR/coherence-pair-covered-uncovered-1.rs:12:1 + | +LL | impl<T, U> Remote1<Pair<T, Local<U>>> for i32 { } + | ^^^^^^^^^^^--------------------------^^^^^--- + | | | | + | | | `i32` is not defined in the current crate + | | `Pair` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-pair-covered-uncovered.rs b/src/test/ui/coherence/coherence-pair-covered-uncovered.rs new file mode 100644 index 000000000..da970572f --- /dev/null +++ b/src/test/ui/coherence/coherence-pair-covered-uncovered.rs @@ -0,0 +1,11 @@ +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::{Remote, Pair}; + +struct Local<T>(T); + +impl<T,U> Remote for Pair<T,Local<U>> { } +//~^ ERROR E0117 + +fn main() { } diff --git a/src/test/ui/coherence/coherence-pair-covered-uncovered.stderr b/src/test/ui/coherence/coherence-pair-covered-uncovered.stderr new file mode 100644 index 000000000..73dfe2f57 --- /dev/null +++ b/src/test/ui/coherence/coherence-pair-covered-uncovered.stderr @@ -0,0 +1,14 @@ +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate + --> $DIR/coherence-pair-covered-uncovered.rs:8:1 + | +LL | impl<T,U> Remote for Pair<T,Local<U>> { } + | ^^^^^^^^^^^^^^^^^^^^^---------------- + | | | + | | `Pair` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-projection-conflict-orphan.rs b/src/test/ui/coherence/coherence-projection-conflict-orphan.rs new file mode 100644 index 000000000..637dd2506 --- /dev/null +++ b/src/test/ui/coherence/coherence-projection-conflict-orphan.rs @@ -0,0 +1,19 @@ +#![feature(rustc_attrs)] + +// Here we expect a coherence conflict because, even though `i32` does +// not implement `Iterator`, we cannot rely on that negative reasoning +// due to the orphan rules. Therefore, `A::Item` may yet turn out to +// be `i32`. + +pub trait Foo<P> { fn foo() {} } + +pub trait Bar { + type Output: 'static; +} + +impl Foo<i32> for i32 { } + +impl<A:Iterator> Foo<A::Item> for A { } +//~^ ERROR E0119 + +fn main() {} diff --git a/src/test/ui/coherence/coherence-projection-conflict-orphan.stderr b/src/test/ui/coherence/coherence-projection-conflict-orphan.stderr new file mode 100644 index 000000000..b1ee0795b --- /dev/null +++ b/src/test/ui/coherence/coherence-projection-conflict-orphan.stderr @@ -0,0 +1,14 @@ +error[E0119]: conflicting implementations of trait `Foo<i32>` for type `i32` + --> $DIR/coherence-projection-conflict-orphan.rs:16:1 + | +LL | impl Foo<i32> for i32 { } + | --------------------- first implementation here +LL | +LL | impl<A:Iterator> Foo<A::Item> for A { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32` + | + = note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `i32` in future versions + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-projection-conflict-ty-param.rs b/src/test/ui/coherence/coherence-projection-conflict-ty-param.rs new file mode 100644 index 000000000..3e4141fa8 --- /dev/null +++ b/src/test/ui/coherence/coherence-projection-conflict-ty-param.rs @@ -0,0 +1,13 @@ +// Coherence error results because we do not know whether `T: Foo<P>` or not +// for the second impl. + +use std::marker::PhantomData; + +pub trait Foo<P> { fn foo() {} } + +impl <P, T: Foo<P>> Foo<P> for Option<T> {} + +impl<T, U> Foo<T> for Option<U> { } +//~^ ERROR E0119 + +fn main() {} diff --git a/src/test/ui/coherence/coherence-projection-conflict-ty-param.stderr b/src/test/ui/coherence/coherence-projection-conflict-ty-param.stderr new file mode 100644 index 000000000..6492747bb --- /dev/null +++ b/src/test/ui/coherence/coherence-projection-conflict-ty-param.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `Foo<_>` for type `std::option::Option<_>` + --> $DIR/coherence-projection-conflict-ty-param.rs:10:1 + | +LL | impl <P, T: Foo<P>> Foo<P> for Option<T> {} + | ---------------------------------------- first implementation here +LL | +LL | impl<T, U> Foo<T> for Option<U> { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::option::Option<_>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-projection-conflict.rs b/src/test/ui/coherence/coherence-projection-conflict.rs new file mode 100644 index 000000000..daab2a2f8 --- /dev/null +++ b/src/test/ui/coherence/coherence-projection-conflict.rs @@ -0,0 +1,18 @@ +use std::marker::PhantomData; + +pub trait Foo<P> { fn foo() {} } + +pub trait Bar { + type Output: 'static; +} + +impl Foo<i32> for i32 { } + +impl<A:Bar> Foo<A::Output> for A { } +//~^ ERROR E0119 + +impl Bar for i32 { + type Output = i32; +} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-projection-conflict.stderr b/src/test/ui/coherence/coherence-projection-conflict.stderr new file mode 100644 index 000000000..7d2c584c3 --- /dev/null +++ b/src/test/ui/coherence/coherence-projection-conflict.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `Foo<i32>` for type `i32` + --> $DIR/coherence-projection-conflict.rs:11:1 + | +LL | impl Foo<i32> for i32 { } + | --------------------- first implementation here +LL | +LL | impl<A:Bar> Foo<A::Output> for A { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-projection-ok-orphan.rs b/src/test/ui/coherence/coherence-projection-ok-orphan.rs new file mode 100644 index 000000000..42b4b1912 --- /dev/null +++ b/src/test/ui/coherence/coherence-projection-ok-orphan.rs @@ -0,0 +1,17 @@ +// Here we do not get a coherence conflict because `Baz: Iterator` +// does not hold and (due to the orphan rules), we can rely on that. + +// check-pass + +pub trait Foo<P> {} + +pub trait Bar { + type Output: 'static; +} + +struct Baz; +impl Foo<i32> for Baz { } + +impl<A:Iterator> Foo<A::Item> for A { } + +fn main() {} diff --git a/src/test/ui/coherence/coherence-projection-ok.rs b/src/test/ui/coherence/coherence-projection-ok.rs new file mode 100644 index 000000000..44fc02a5c --- /dev/null +++ b/src/test/ui/coherence/coherence-projection-ok.rs @@ -0,0 +1,17 @@ +// check-pass + +pub trait Foo<P> {} + +pub trait Bar { + type Output: 'static; +} + +impl Foo<i32> for i32 { } + +impl<A:Bar> Foo<A::Output> for A { } + +impl Bar for i32 { + type Output = u32; +} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-rfc447-constrained.rs b/src/test/ui/coherence/coherence-rfc447-constrained.rs new file mode 100644 index 000000000..9d1d86883 --- /dev/null +++ b/src/test/ui/coherence/coherence-rfc447-constrained.rs @@ -0,0 +1,22 @@ +// run-pass +// check that trait matching can handle impls whose types are only +// constrained by a projection. + +trait IsU32 {} +impl IsU32 for u32 {} + +trait Mirror { type Image: ?Sized; } +impl<T: ?Sized> Mirror for T { type Image = T; } + +trait Bar {} +impl<U: Mirror, V: Mirror<Image=L>, L: Mirror<Image=U>> Bar for V + where U::Image: IsU32 {} + +trait Foo { fn name() -> &'static str; } +impl Foo for u64 { fn name() -> &'static str { "u64" } } +impl<T: Bar> Foo for T { fn name() -> &'static str { "Bar" }} + +fn main() { + assert_eq!(<u64 as Foo>::name(), "u64"); + assert_eq!(<u32 as Foo>::name(), "Bar"); +} diff --git a/src/test/ui/coherence/coherence-subtyping.rs b/src/test/ui/coherence/coherence-subtyping.rs new file mode 100644 index 000000000..b3ed728a8 --- /dev/null +++ b/src/test/ui/coherence/coherence-subtyping.rs @@ -0,0 +1,20 @@ +// Test that two distinct impls which match subtypes of one another +// yield coherence errors (or not) depending on the variance. +// +// Note: This scenario is currently accepted, but as part of the +// universe transition (#56105) may eventually become an error. + +// check-pass + +trait TheTrait { + fn foo(&self) {} +} + +impl TheTrait for for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {} + +impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { + //~^ WARNING conflicting implementation + //~^^ WARNING this was previously accepted by the compiler but is being phased out +} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-subtyping.stderr b/src/test/ui/coherence/coherence-subtyping.stderr new file mode 100644 index 000000000..25d8c8756 --- /dev/null +++ b/src/test/ui/coherence/coherence-subtyping.stderr @@ -0,0 +1,16 @@ +warning: conflicting implementations of trait `TheTrait` for type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` + --> $DIR/coherence-subtyping.rs:15:1 + | +LL | impl TheTrait for for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {} + | ---------------------------------------------------------- first implementation here +LL | +LL | impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` + | + = note: `#[warn(coherence_leak_check)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105> + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + +warning: 1 warning emitted + diff --git a/src/test/ui/coherence/coherence-tuple-conflict.rs b/src/test/ui/coherence/coherence-tuple-conflict.rs new file mode 100644 index 000000000..8cc829726 --- /dev/null +++ b/src/test/ui/coherence/coherence-tuple-conflict.rs @@ -0,0 +1,20 @@ +use std::fmt::Debug; +use std::default::Default; + +// Test that a blank impl for all T conflicts with an impl for some +// specific T. + +trait MyTrait { + fn get(&self) -> usize; +} + +impl<T> MyTrait for (T,T) { + fn get(&self) -> usize { 0 } +} + +impl<A,B> MyTrait for (A,B) { +//~^ ERROR E0119 + fn get(&self) -> usize { self.dummy } +} + +fn main() { } diff --git a/src/test/ui/coherence/coherence-tuple-conflict.stderr b/src/test/ui/coherence/coherence-tuple-conflict.stderr new file mode 100644 index 000000000..09ad5e5b2 --- /dev/null +++ b/src/test/ui/coherence/coherence-tuple-conflict.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `MyTrait` for type `(_, _)` + --> $DIR/coherence-tuple-conflict.rs:15:1 + | +LL | impl<T> MyTrait for (T,T) { + | ------------------------- first implementation here +... +LL | impl<A,B> MyTrait for (A,B) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(_, _)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-unsafe-trait-object-impl.rs b/src/test/ui/coherence/coherence-unsafe-trait-object-impl.rs new file mode 100644 index 000000000..9859a226e --- /dev/null +++ b/src/test/ui/coherence/coherence-unsafe-trait-object-impl.rs @@ -0,0 +1,18 @@ +// Check that unsafe trait object do not implement themselves +// automatically + +#![feature(object_safe_for_dispatch)] + +trait Trait: Sized { + fn call(&self); +} + +fn takes_t<S: Trait>(s: S) { + s.call(); +} + +fn takes_t_obj(t: &dyn Trait) { + takes_t(t); //~ ERROR E0277 +} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-unsafe-trait-object-impl.stderr b/src/test/ui/coherence/coherence-unsafe-trait-object-impl.stderr new file mode 100644 index 000000000..2e2dac288 --- /dev/null +++ b/src/test/ui/coherence/coherence-unsafe-trait-object-impl.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `&dyn Trait: Trait` is not satisfied + --> $DIR/coherence-unsafe-trait-object-impl.rs:15:13 + | +LL | takes_t(t); + | ------- ^ the trait `Trait` is not implemented for `&dyn Trait` + | | + | required by a bound introduced by this call + | +note: required by a bound in `takes_t` + --> $DIR/coherence-unsafe-trait-object-impl.rs:10:15 + | +LL | fn takes_t<S: Trait>(s: S) { + | ^^^^^ required by this bound in `takes_t` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/coherence/coherence-vec-local-2.rs b/src/test/ui/coherence/coherence-vec-local-2.rs new file mode 100644 index 000000000..47df06bac --- /dev/null +++ b/src/test/ui/coherence/coherence-vec-local-2.rs @@ -0,0 +1,14 @@ +// Test that a local, generic type appearing within a +// *non-fundamental* remote type like `Vec` is not considered local. + +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::Remote; + +struct Local<T>(T); + +impl<T> Remote for Vec<Local<T>> { } +//~^ ERROR E0117 + +fn main() { } diff --git a/src/test/ui/coherence/coherence-vec-local-2.stderr b/src/test/ui/coherence/coherence-vec-local-2.stderr new file mode 100644 index 000000000..95fdf172e --- /dev/null +++ b/src/test/ui/coherence/coherence-vec-local-2.stderr @@ -0,0 +1,14 @@ +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate + --> $DIR/coherence-vec-local-2.rs:11:1 + | +LL | impl<T> Remote for Vec<Local<T>> { } + | ^^^^^^^^^^^^^^^^^^^------------- + | | | + | | `Vec` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-vec-local.rs b/src/test/ui/coherence/coherence-vec-local.rs new file mode 100644 index 000000000..130cc39d0 --- /dev/null +++ b/src/test/ui/coherence/coherence-vec-local.rs @@ -0,0 +1,14 @@ +// Test that a local type (with no type parameters) appearing within a +// *non-fundamental* remote type like `Vec` is not considered local. + +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::Remote; + +struct Local; + +impl Remote for Vec<Local> { } +//~^ ERROR E0117 + +fn main() { } diff --git a/src/test/ui/coherence/coherence-vec-local.stderr b/src/test/ui/coherence/coherence-vec-local.stderr new file mode 100644 index 000000000..4835e771a --- /dev/null +++ b/src/test/ui/coherence/coherence-vec-local.stderr @@ -0,0 +1,14 @@ +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate + --> $DIR/coherence-vec-local.rs:11:1 + | +LL | impl Remote for Vec<Local> { } + | ^^^^^^^^^^^^^^^^---------- + | | | + | | `Vec` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-wasm-bindgen.rs b/src/test/ui/coherence/coherence-wasm-bindgen.rs new file mode 100644 index 000000000..ee09a7244 --- /dev/null +++ b/src/test/ui/coherence/coherence-wasm-bindgen.rs @@ -0,0 +1,37 @@ +// Capture a coherence pattern from wasm-bindgen that we discovered as part of +// future-compatibility warning #56105. This pattern currently receives a lint +// warning but we probably want to support it long term. +// +// Key distinction: we are implementing once for `A` (take ownership) and one +// for `&A` (borrow). +// +// c.f. #56105 + +#![deny(coherence_leak_check)] + +trait IntoWasmAbi { + fn some_method(&self) {} +} + +trait FromWasmAbi {} +trait RefFromWasmAbi {} +trait ReturnWasmAbi {} + +impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn Fn(A) -> R + 'b) +where + A: FromWasmAbi, + R: ReturnWasmAbi, +{ +} + +// Explicitly writing the bound lifetime. +impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn for<'x> Fn(&'x A) -> R + 'b) +where + A: RefFromWasmAbi, + R: ReturnWasmAbi, +{ + //~^^^^^ ERROR conflicting implementation + //~| WARNING this was previously accepted +} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-wasm-bindgen.stderr b/src/test/ui/coherence/coherence-wasm-bindgen.stderr new file mode 100644 index 000000000..aa74e2315 --- /dev/null +++ b/src/test/ui/coherence/coherence-wasm-bindgen.stderr @@ -0,0 +1,21 @@ +error: conflicting implementations of trait `IntoWasmAbi` for type `&dyn std::ops::Fn(&_) -> _` + --> $DIR/coherence-wasm-bindgen.rs:28:1 + | +LL | impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn Fn(A) -> R + 'b) + | ------------------------------------------------------------ first implementation here +... +LL | impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn for<'x> Fn(&'x A) -> R + 'b) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&dyn std::ops::Fn(&_) -> _` + | +note: the lint level is defined here + --> $DIR/coherence-wasm-bindgen.rs:10:9 + | +LL | #![deny(coherence_leak_check)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105> + = note: downstream crates may implement trait `FromWasmAbi` for type `&_` + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + +error: aborting due to previous error + diff --git a/src/test/ui/coherence/coherence-where-clause.rs b/src/test/ui/coherence/coherence-where-clause.rs new file mode 100644 index 000000000..5c40def86 --- /dev/null +++ b/src/test/ui/coherence/coherence-where-clause.rs @@ -0,0 +1,38 @@ +// run-pass + +use std::fmt::Debug; +use std::default::Default; + +trait MyTrait { + fn get(&self) -> Self; +} + +impl<T> MyTrait for T + where T : Default +{ + fn get(&self) -> T { + Default::default() + } +} + +#[derive(Clone, Copy, Debug, PartialEq)] +struct MyType { + dummy: usize +} + +impl MyTrait for MyType { + fn get(&self) -> MyType { (*self).clone() } +} + +fn test_eq<M>(m: M, n: M) +where M : MyTrait + Debug + PartialEq +{ + assert_eq!(m.get(), n); +} + +pub fn main() { + test_eq(0_usize, 0_usize); + + let value = MyType { dummy: 256 + 22 }; + test_eq(value, value); +} diff --git a/src/test/ui/coherence/coherence-with-closure.rs b/src/test/ui/coherence/coherence-with-closure.rs new file mode 100644 index 000000000..6e3281d85 --- /dev/null +++ b/src/test/ui/coherence/coherence-with-closure.rs @@ -0,0 +1,15 @@ +// Test that encountering closures during coherence does not cause issues. +#![feature(type_alias_impl_trait)] +type OpaqueClosure = impl Sized; +fn defining_use() -> OpaqueClosure { + || () +} + +struct Wrapper<T>(T); +trait Trait {} +impl Trait for Wrapper<OpaqueClosure> {} +//~^ ERROR cannot implement trait on type alias impl trait +impl<T: Sync> Trait for Wrapper<T> {} +//~^ ERROR conflicting implementations of trait `Trait` for type `Wrapper<OpaqueClosure>` + +fn main() {} diff --git a/src/test/ui/coherence/coherence-with-closure.stderr b/src/test/ui/coherence/coherence-with-closure.stderr new file mode 100644 index 000000000..d2ca63fa1 --- /dev/null +++ b/src/test/ui/coherence/coherence-with-closure.stderr @@ -0,0 +1,24 @@ +error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueClosure>` + --> $DIR/coherence-with-closure.rs:12:1 + | +LL | impl Trait for Wrapper<OpaqueClosure> {} + | ------------------------------------- first implementation here +LL | +LL | impl<T: Sync> Trait for Wrapper<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueClosure>` + +error: cannot implement trait on type alias impl trait + --> $DIR/coherence-with-closure.rs:10:24 + | +LL | impl Trait for Wrapper<OpaqueClosure> {} + | ^^^^^^^^^^^^^ + | +note: type alias impl trait defined here + --> $DIR/coherence-with-closure.rs:3:22 + | +LL | type OpaqueClosure = impl Sized; + | ^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence-with-generator.rs b/src/test/ui/coherence/coherence-with-generator.rs new file mode 100644 index 000000000..d34c391db --- /dev/null +++ b/src/test/ui/coherence/coherence-with-generator.rs @@ -0,0 +1,19 @@ +// Test that encountering closures during coherence does not cause issues. +#![feature(type_alias_impl_trait, generators)] +type OpaqueGenerator = impl Sized; +fn defining_use() -> OpaqueGenerator { + || { + for i in 0..10 { + yield i; + } + } +} + +struct Wrapper<T>(T); +trait Trait {} +impl Trait for Wrapper<OpaqueGenerator> {} +//~^ ERROR cannot implement trait on type alias impl trait +impl<T: Sync> Trait for Wrapper<T> {} +//~^ ERROR conflicting implementations of trait `Trait` for type `Wrapper<OpaqueGenerator>` + +fn main() {} diff --git a/src/test/ui/coherence/coherence-with-generator.stderr b/src/test/ui/coherence/coherence-with-generator.stderr new file mode 100644 index 000000000..804bc1c3a --- /dev/null +++ b/src/test/ui/coherence/coherence-with-generator.stderr @@ -0,0 +1,24 @@ +error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueGenerator>` + --> $DIR/coherence-with-generator.rs:16:1 + | +LL | impl Trait for Wrapper<OpaqueGenerator> {} + | --------------------------------------- first implementation here +LL | +LL | impl<T: Sync> Trait for Wrapper<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueGenerator>` + +error: cannot implement trait on type alias impl trait + --> $DIR/coherence-with-generator.rs:14:24 + | +LL | impl Trait for Wrapper<OpaqueGenerator> {} + | ^^^^^^^^^^^^^^^ + | +note: type alias impl trait defined here + --> $DIR/coherence-with-generator.rs:3:24 + | +LL | type OpaqueGenerator = impl Sized; + | ^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence_copy_like.rs b/src/test/ui/coherence/coherence_copy_like.rs new file mode 100644 index 000000000..92af341cc --- /dev/null +++ b/src/test/ui/coherence/coherence_copy_like.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(dead_code)] +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +// aux-build:coherence_copy_like_lib.rs + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +trait MyTrait { } +impl<T: lib::MyCopy> MyTrait for T { } +impl MyTrait for MyType { } +impl<'a> MyTrait for &'a MyType { } +impl MyTrait for Box<MyType> { } +impl<'a> MyTrait for &'a Box<MyType> { } + +fn main() { } diff --git a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct.rs b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct.rs new file mode 100644 index 000000000..edee6cd7b --- /dev/null +++ b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct.rs @@ -0,0 +1,24 @@ +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +// aux-build:coherence_copy_like_lib.rs +// build-pass (FIXME(62277): could be check-pass?) +// skip-codgen +#![allow(dead_code)] + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +trait MyTrait { fn foo() {} } +impl<T: lib::MyCopy> MyTrait for T { } + +// `MyFundamentalStruct` is declared fundamental, so we can test that +// +// MyFundamentalStruct<MyTrait>: !MyTrait +// +// Huzzah. +impl MyTrait for lib::MyFundamentalStruct<MyType> { } + + +fn main() { } diff --git a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_ref.rs b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_ref.rs new file mode 100644 index 000000000..599c804d2 --- /dev/null +++ b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_ref.rs @@ -0,0 +1,21 @@ +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +// check-pass +// aux-build:coherence_copy_like_lib.rs + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +trait MyTrait { fn foo() {} } +impl<T: lib::MyCopy> MyTrait for T { } + +// `MyFundamentalStruct` is declared fundamental, so we can test that +// +// MyFundamentalStruct<&MyTrait>: !MyTrait +// +// Huzzah. +impl<'a> MyTrait for lib::MyFundamentalStruct<&'a MyType> { } + +fn main() { } diff --git a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.rs b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.rs new file mode 100644 index 000000000..7d851b528 --- /dev/null +++ b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.rs @@ -0,0 +1,20 @@ +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +// aux-build:coherence_copy_like_lib.rs + + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +trait MyTrait { fn foo() {} } + +impl<T: lib::MyCopy> MyTrait for T { } + +// Tuples are not fundamental. +impl MyTrait for lib::MyFundamentalStruct<(MyType,)> { } +//~^ ERROR E0119 + + +fn main() { } diff --git a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr new file mode 100644 index 000000000..db7306501 --- /dev/null +++ b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr @@ -0,0 +1,14 @@ +error[E0119]: conflicting implementations of trait `MyTrait` for type `lib::MyFundamentalStruct<(MyType,)>` + --> $DIR/coherence_copy_like_err_fundamental_struct_tuple.rs:16:1 + | +LL | impl<T: lib::MyCopy> MyTrait for T { } + | ---------------------------------- first implementation here +... +LL | impl MyTrait for lib::MyFundamentalStruct<(MyType,)> { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyFundamentalStruct<(MyType,)>` + | + = note: upstream crates may add a new impl of trait `lib::MyCopy` for type `lib::MyFundamentalStruct<(MyType,)>` in future versions + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence_copy_like_err_struct.rs b/src/test/ui/coherence/coherence_copy_like_err_struct.rs new file mode 100644 index 000000000..fe39370c9 --- /dev/null +++ b/src/test/ui/coherence/coherence_copy_like_err_struct.rs @@ -0,0 +1,22 @@ +// aux-build:coherence_copy_like_lib.rs + +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +trait MyTrait { fn foo() {} } +impl<T: lib::MyCopy> MyTrait for T { } + +// `MyStruct` is not declared fundamental, therefore this would +// require that +// +// MyStruct<MyType>: !MyTrait +// +// which we cannot approve. +impl MyTrait for lib::MyStruct<MyType> { } +//~^ ERROR E0119 + +fn main() { } diff --git a/src/test/ui/coherence/coherence_copy_like_err_struct.stderr b/src/test/ui/coherence/coherence_copy_like_err_struct.stderr new file mode 100644 index 000000000..3bc3dffda --- /dev/null +++ b/src/test/ui/coherence/coherence_copy_like_err_struct.stderr @@ -0,0 +1,14 @@ +error[E0119]: conflicting implementations of trait `MyTrait` for type `lib::MyStruct<MyType>` + --> $DIR/coherence_copy_like_err_struct.rs:19:1 + | +LL | impl<T: lib::MyCopy> MyTrait for T { } + | ---------------------------------- first implementation here +... +LL | impl MyTrait for lib::MyStruct<MyType> { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyStruct<MyType>` + | + = note: upstream crates may add a new impl of trait `lib::MyCopy` for type `lib::MyStruct<MyType>` in future versions + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence_copy_like_err_tuple.rs b/src/test/ui/coherence/coherence_copy_like_err_tuple.rs new file mode 100644 index 000000000..f63e205c9 --- /dev/null +++ b/src/test/ui/coherence/coherence_copy_like_err_tuple.rs @@ -0,0 +1,21 @@ +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +// aux-build:coherence_copy_like_lib.rs + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +trait MyTrait { fn foo() {} } +impl<T: lib::MyCopy> MyTrait for T { } + +// Tuples are not fundamental, therefore this would require that +// +// (MyType,): !MyTrait +// +// which we cannot approve. +impl MyTrait for (MyType,) { } +//~^ ERROR E0119 + +fn main() { } diff --git a/src/test/ui/coherence/coherence_copy_like_err_tuple.stderr b/src/test/ui/coherence/coherence_copy_like_err_tuple.stderr new file mode 100644 index 000000000..090497ec1 --- /dev/null +++ b/src/test/ui/coherence/coherence_copy_like_err_tuple.stderr @@ -0,0 +1,14 @@ +error[E0119]: conflicting implementations of trait `MyTrait` for type `(MyType,)` + --> $DIR/coherence_copy_like_err_tuple.rs:18:1 + | +LL | impl<T: lib::MyCopy> MyTrait for T { } + | ---------------------------------- first implementation here +... +LL | impl MyTrait for (MyType,) { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(MyType,)` + | + = note: upstream crates may add a new impl of trait `lib::MyCopy` for type `(MyType,)` in future versions + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/coherence_inherent.rs b/src/test/ui/coherence/coherence_inherent.rs new file mode 100644 index 000000000..f3ebf0003 --- /dev/null +++ b/src/test/ui/coherence/coherence_inherent.rs @@ -0,0 +1,36 @@ +// Tests that methods that implement a trait cannot be invoked +// unless the trait is imported. + +mod Lib { + pub trait TheTrait { + fn the_fn(&self); + } + + pub struct TheStruct; + + impl TheTrait for TheStruct { + fn the_fn(&self) {} + } +} + +mod Import { + // Trait is in scope here: + use Lib::TheStruct; + use Lib::TheTrait; + + fn call_the_fn(s: &TheStruct) { + s.the_fn(); + } +} + +mod NoImport { + // Trait is not in scope here: + use Lib::TheStruct; + + fn call_the_fn(s: &TheStruct) { + s.the_fn(); + //~^ ERROR E0599 + } +} + +fn main() {} diff --git a/src/test/ui/coherence/coherence_inherent.stderr b/src/test/ui/coherence/coherence_inherent.stderr new file mode 100644 index 000000000..46b128c08 --- /dev/null +++ b/src/test/ui/coherence/coherence_inherent.stderr @@ -0,0 +1,15 @@ +error[E0599]: no method named `the_fn` found for reference `&TheStruct` in the current scope + --> $DIR/coherence_inherent.rs:31:11 + | +LL | s.the_fn(); + | ^^^^^^ method not found in `&TheStruct` + | + = help: items from traits can only be used if the trait is in scope +help: the following trait is implemented but not in scope; perhaps add a `use` for it: + | +LL | use Lib::TheTrait; + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/coherence/coherence_inherent_cc.rs b/src/test/ui/coherence/coherence_inherent_cc.rs new file mode 100644 index 000000000..759ada248 --- /dev/null +++ b/src/test/ui/coherence/coherence_inherent_cc.rs @@ -0,0 +1,28 @@ +// aux-build:coherence_inherent_cc_lib.rs + +// Tests that methods that implement a trait cannot be invoked +// unless the trait is imported. + +extern crate coherence_inherent_cc_lib; + +mod Import { + // Trait is in scope here: + use coherence_inherent_cc_lib::TheStruct; + use coherence_inherent_cc_lib::TheTrait; + + fn call_the_fn(s: &TheStruct) { + s.the_fn(); + } +} + +mod NoImport { + // Trait is not in scope here: + use coherence_inherent_cc_lib::TheStruct; + + fn call_the_fn(s: &TheStruct) { + s.the_fn(); + //~^ ERROR E0599 + } +} + +fn main() {} diff --git a/src/test/ui/coherence/coherence_inherent_cc.stderr b/src/test/ui/coherence/coherence_inherent_cc.stderr new file mode 100644 index 000000000..af0ef3b69 --- /dev/null +++ b/src/test/ui/coherence/coherence_inherent_cc.stderr @@ -0,0 +1,15 @@ +error[E0599]: no method named `the_fn` found for reference `&TheStruct` in the current scope + --> $DIR/coherence_inherent_cc.rs:23:11 + | +LL | s.the_fn(); + | ^^^^^^ method not found in `&TheStruct` + | + = help: items from traits can only be used if the trait is in scope +help: the following trait is implemented but not in scope; perhaps add a `use` for it: + | +LL | use coherence_inherent_cc_lib::TheTrait; + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/coherence/coherence_local.rs b/src/test/ui/coherence/coherence_local.rs new file mode 100644 index 000000000..ea724ada7 --- /dev/null +++ b/src/test/ui/coherence/coherence_local.rs @@ -0,0 +1,20 @@ +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +// check-pass +// aux-build:coherence_copy_like_lib.rs + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +// These are all legal because they are all fundamental types: + +impl lib::MyCopy for MyType { } +impl<'a> lib::MyCopy for &'a MyType { } +impl<'a> lib::MyCopy for &'a Box<MyType> { } +impl lib::MyCopy for Box<MyType> { } +impl lib::MyCopy for lib::MyFundamentalStruct<MyType> { } +impl lib::MyCopy for lib::MyFundamentalStruct<Box<MyType>> { } + +fn main() {} diff --git a/src/test/ui/coherence/coherence_local_err_struct.rs b/src/test/ui/coherence/coherence_local_err_struct.rs new file mode 100644 index 000000000..a24038eb2 --- /dev/null +++ b/src/test/ui/coherence/coherence_local_err_struct.rs @@ -0,0 +1,18 @@ +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +// aux-build:coherence_copy_like_lib.rs +#![allow(dead_code)] + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +// These are all legal because they are all fundamental types: + +// MyStruct is not fundamental. +impl lib::MyCopy for lib::MyStruct<MyType> { } +//~^ ERROR E0117 + + +fn main() { } diff --git a/src/test/ui/coherence/coherence_local_err_struct.stderr b/src/test/ui/coherence/coherence_local_err_struct.stderr new file mode 100644 index 000000000..afc6fc45d --- /dev/null +++ b/src/test/ui/coherence/coherence_local_err_struct.stderr @@ -0,0 +1,14 @@ +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate + --> $DIR/coherence_local_err_struct.rs:14:1 + | +LL | impl lib::MyCopy for lib::MyStruct<MyType> { } + | ^^^^^^^^^^^^^^^^^^^^^--------------------- + | | | + | | `MyStruct` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence_local_err_tuple.rs b/src/test/ui/coherence/coherence_local_err_tuple.rs new file mode 100644 index 000000000..f4033862a --- /dev/null +++ b/src/test/ui/coherence/coherence_local_err_tuple.rs @@ -0,0 +1,18 @@ +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +// aux-build:coherence_copy_like_lib.rs +#![allow(dead_code)] + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +// These are all legal because they are all fundamental types: + +// Tuples are not fundamental, so this is not a local impl. +impl lib::MyCopy for (MyType,) { } +//~^ ERROR E0117 + + +fn main() { } diff --git a/src/test/ui/coherence/coherence_local_err_tuple.stderr b/src/test/ui/coherence/coherence_local_err_tuple.stderr new file mode 100644 index 000000000..a4953859f --- /dev/null +++ b/src/test/ui/coherence/coherence_local_err_tuple.stderr @@ -0,0 +1,14 @@ +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/coherence_local_err_tuple.rs:14:1 + | +LL | impl lib::MyCopy for (MyType,) { } + | ^^^^^^^^^^^^^^^^^^^^^--------- + | | | + | | this is not defined in the current crate because tuples are always foreign + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence_local_ref.rs b/src/test/ui/coherence/coherence_local_ref.rs new file mode 100644 index 000000000..2e28839c8 --- /dev/null +++ b/src/test/ui/coherence/coherence_local_ref.rs @@ -0,0 +1,14 @@ +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +// check-pass +// aux-build:coherence_copy_like_lib.rs + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +// naturally, legal +impl lib::MyCopy for MyType { } + +fn main() { } diff --git a/src/test/ui/coherence/conflicting-impl-with-err.rs b/src/test/ui/coherence/conflicting-impl-with-err.rs new file mode 100644 index 000000000..3e0234b87 --- /dev/null +++ b/src/test/ui/coherence/conflicting-impl-with-err.rs @@ -0,0 +1,16 @@ +struct ErrorKind; +struct Error(ErrorKind); + +impl From<nope::Thing> for Error { //~ ERROR failed to resolve + fn from(_: nope::Thing) -> Self { //~ ERROR failed to resolve + unimplemented!() + } +} + +impl From<ErrorKind> for Error { + fn from(_: ErrorKind) -> Self { + unimplemented!() + } +} + +fn main() {} diff --git a/src/test/ui/coherence/conflicting-impl-with-err.stderr b/src/test/ui/coherence/conflicting-impl-with-err.stderr new file mode 100644 index 000000000..3009b452d --- /dev/null +++ b/src/test/ui/coherence/conflicting-impl-with-err.stderr @@ -0,0 +1,15 @@ +error[E0433]: failed to resolve: use of undeclared crate or module `nope` + --> $DIR/conflicting-impl-with-err.rs:4:11 + | +LL | impl From<nope::Thing> for Error { + | ^^^^ use of undeclared crate or module `nope` + +error[E0433]: failed to resolve: use of undeclared crate or module `nope` + --> $DIR/conflicting-impl-with-err.rs:5:16 + | +LL | fn from(_: nope::Thing) -> Self { + | ^^^^ use of undeclared crate or module `nope` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/coherence/deep-bad-copy-reason.rs b/src/test/ui/coherence/deep-bad-copy-reason.rs new file mode 100644 index 000000000..80bbe387a --- /dev/null +++ b/src/test/ui/coherence/deep-bad-copy-reason.rs @@ -0,0 +1,40 @@ +#![feature(extern_types)] + +extern "Rust" { + type OpaqueListContents; +} + +pub struct ListS<T> { + len: usize, + data: [T; 0], + opaque: OpaqueListContents, +} + +pub struct Interned<'a, T>(&'a T); + +impl<'a, T> Clone for Interned<'a, T> { + fn clone(&self) -> Self { + *self + } +} + +impl<'a, T> Copy for Interned<'a, T> {} + +pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>); +//~^ NOTE this field does not implement `Copy` +//~| NOTE the `Copy` impl for `Interned<'tcx, ListS<T>>` requires that `OpaqueListContents: Sized` + +impl<'tcx, T> Clone for List<'tcx, T> { + fn clone(&self) -> Self { + *self + } +} + +impl<'tcx, T> Copy for List<'tcx, T> {} +//~^ ERROR the trait `Copy` may not be implemented for this type + +fn assert_is_copy<T: Copy>() {} + +fn main() { + assert_is_copy::<List<'static, ()>>(); +} diff --git a/src/test/ui/coherence/deep-bad-copy-reason.stderr b/src/test/ui/coherence/deep-bad-copy-reason.stderr new file mode 100644 index 000000000..295538cee --- /dev/null +++ b/src/test/ui/coherence/deep-bad-copy-reason.stderr @@ -0,0 +1,18 @@ +error[E0204]: the trait `Copy` may not be implemented for this type + --> $DIR/deep-bad-copy-reason.rs:33:15 + | +LL | pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>); + | ------------------------ this field does not implement `Copy` +... +LL | impl<'tcx, T> Copy for List<'tcx, T> {} + | ^^^^ + | +note: the `Copy` impl for `Interned<'tcx, ListS<T>>` requires that `OpaqueListContents: Sized` + --> $DIR/deep-bad-copy-reason.rs:23:26 + | +LL | pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0204`. diff --git a/src/test/ui/coherence/impl-foreign-for-foreign.rs b/src/test/ui/coherence/impl-foreign-for-foreign.rs new file mode 100644 index 000000000..4c0d46045 --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-foreign.rs @@ -0,0 +1,15 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote for i32 { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign-for-foreign.stderr b/src/test/ui/coherence/impl-foreign-for-foreign.stderr new file mode 100644 index 000000000..93f7a6fdc --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-foreign.stderr @@ -0,0 +1,14 @@ +error[E0117]: only traits defined in the current crate can be implemented for primitive types + --> $DIR/impl-foreign-for-foreign.rs:10:1 + | +LL | impl Remote for i32 { + | ^^^^^^^^^^^^^^^^--- + | | | + | | `i32` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/impl-foreign-for-foreign[foreign].rs b/src/test/ui/coherence/impl-foreign-for-foreign[foreign].rs new file mode 100644 index 000000000..e79f66c0e --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-foreign[foreign].rs @@ -0,0 +1,23 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1<Rc<i32>> for i32 { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} +impl Remote1<Rc<Local>> for f64 { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} +impl<T> Remote1<Rc<T>> for f32 { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign-for-foreign[foreign].stderr b/src/test/ui/coherence/impl-foreign-for-foreign[foreign].stderr new file mode 100644 index 000000000..e24537bce --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-foreign[foreign].stderr @@ -0,0 +1,39 @@ +error[E0117]: only traits defined in the current crate can be implemented for primitive types + --> $DIR/impl-foreign-for-foreign[foreign].rs:10:1 + | +LL | impl Remote1<Rc<i32>> for i32 { + | ^^^^^----------------^^^^^--- + | | | | + | | | `i32` is not defined in the current crate + | | `Rc` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for primitive types + --> $DIR/impl-foreign-for-foreign[foreign].rs:14:1 + | +LL | impl Remote1<Rc<Local>> for f64 { + | ^^^^^------------------^^^^^--- + | | | | + | | | `f64` is not defined in the current crate + | | `Rc` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for primitive types + --> $DIR/impl-foreign-for-foreign[foreign].rs:18:1 + | +LL | impl<T> Remote1<Rc<T>> for f32 { + | ^^^^^^^^--------------^^^^^--- + | | | | + | | | `f32` is not defined in the current crate + | | `Rc` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/impl-foreign-for-foreign[local].rs b/src/test/ui/coherence/impl-foreign-for-foreign[local].rs new file mode 100644 index 000000000..0b1413edf --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-foreign[local].rs @@ -0,0 +1,14 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local<T>(Rc<T>); + +impl Remote1<Local<i32>> for i32 {} +impl<T> Remote1<Local<T>> for f32 {} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].rs b/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].rs new file mode 100644 index 000000000..10bdf2db8 --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].rs @@ -0,0 +1,19 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote for Box<i32> { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} +impl<T> Remote for Box<Rc<T>> { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr b/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr new file mode 100644 index 000000000..55ea4409e --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr @@ -0,0 +1,27 @@ +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate + --> $DIR/impl-foreign-for-fundamental[foreign].rs:10:1 + | +LL | impl Remote for Box<i32> { + | ^^^^^------^^^^^-------- + | | | | + | | | `i32` is not defined in the current crate + | | `std::alloc::Global` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate + --> $DIR/impl-foreign-for-fundamental[foreign].rs:14:1 + | +LL | impl<T> Remote for Box<Rc<T>> { + | ^^^^^^^^------^^^^^---------- + | | | | + | | | `Rc` is not defined in the current crate + | | `std::alloc::Global` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/impl-foreign-for-fundamental[local].rs b/src/test/ui/coherence/impl-foreign-for-fundamental[local].rs new file mode 100644 index 000000000..c3fc0e6b8 --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-fundamental[local].rs @@ -0,0 +1,15 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local1<T>(Rc<T>); + +impl Remote for Box<Local> {} +impl<T> Remote for Box<Local1<T>> {} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign-for-local.rs b/src/test/ui/coherence/impl-foreign-for-local.rs new file mode 100644 index 000000000..04405bc46 --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-local.rs @@ -0,0 +1,13 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote for Local {} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign-for-locally-defined-fundamental.rs b/src/test/ui/coherence/impl-foreign-for-locally-defined-fundamental.rs new file mode 100644 index 000000000..bc1e18b65 --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-locally-defined-fundamental.rs @@ -0,0 +1,15 @@ +#![feature(fundamental)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; + +#[fundamental] +struct Local<T>(T); + +impl Remote for Local<()> {} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign-for-locally-defined-fundamental[foreign].rs b/src/test/ui/coherence/impl-foreign-for-locally-defined-fundamental[foreign].rs new file mode 100644 index 000000000..1e11789ef --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-locally-defined-fundamental[foreign].rs @@ -0,0 +1,15 @@ +#![feature(fundamental)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; + +#[fundamental] +struct MyBox<T>(T); + +impl<T> Remote for MyBox<T> {} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs new file mode 100644 index 000000000..99a399ddc --- /dev/null +++ b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs @@ -0,0 +1,15 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1<u32> for f64 { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr new file mode 100644 index 000000000..65b3aa394 --- /dev/null +++ b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr @@ -0,0 +1,15 @@ +error[E0117]: only traits defined in the current crate can be implemented for primitive types + --> $DIR/impl-foreign[foreign]-for-foreign.rs:10:1 + | +LL | impl Remote1<u32> for f64 { + | ^^^^^------------^^^^^--- + | | | | + | | | `f64` is not defined in the current crate + | | `u32` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/impl-foreign[foreign]-for-local.rs b/src/test/ui/coherence/impl-foreign[foreign]-for-local.rs new file mode 100644 index 000000000..bc6595bb3 --- /dev/null +++ b/src/test/ui/coherence/impl-foreign[foreign]-for-local.rs @@ -0,0 +1,14 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1<u32> for Local { +} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs b/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs new file mode 100644 index 000000000..0476cdaff --- /dev/null +++ b/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs @@ -0,0 +1,24 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local1<T>(Rc<T>); + +impl Remote1<Box<String>> for i32 { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} +impl Remote1<Box<Rc<i32>>> for f64 { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} +impl<T> Remote1<Box<Rc<T>>> for f32 { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr b/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr new file mode 100644 index 000000000..8e77c13e1 --- /dev/null +++ b/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr @@ -0,0 +1,42 @@ +error[E0117]: only traits defined in the current crate can be implemented for primitive types + --> $DIR/impl-foreign[fundemental[foreign]]-for-foreign.rs:11:1 + | +LL | impl Remote1<Box<String>> for i32 { + | ^^^^^--------------------^^^^^--- + | | | | + | | | `i32` is not defined in the current crate + | | `String` is not defined in the current crate + | | `std::alloc::Global` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for primitive types + --> $DIR/impl-foreign[fundemental[foreign]]-for-foreign.rs:15:1 + | +LL | impl Remote1<Box<Rc<i32>>> for f64 { + | ^^^^^---------------------^^^^^--- + | | | | + | | | `f64` is not defined in the current crate + | | `Rc` is not defined in the current crate + | | `std::alloc::Global` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for primitive types + --> $DIR/impl-foreign[fundemental[foreign]]-for-foreign.rs:19:1 + | +LL | impl<T> Remote1<Box<Rc<T>>> for f32 { + | ^^^^^^^^-------------------^^^^^--- + | | | | + | | | `f32` is not defined in the current crate + | | `Rc` is not defined in the current crate + | | `std::alloc::Global` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs b/src/test/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs new file mode 100644 index 000000000..7b83b0485 --- /dev/null +++ b/src/test/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs @@ -0,0 +1,16 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local1<T>(Rc<T>); + +impl Remote1<Box<Local>> for i32 {} +impl Remote1<Box<Local1<i32>>> for f64 {} +impl<T> Remote1<Box<Local1<T>>> for f32 {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].rs b/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].rs new file mode 100644 index 000000000..5282de4b2 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].rs @@ -0,0 +1,21 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; +use std::sync::Arc; + +struct Local; + +impl Remote for Rc<Local> { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} + +impl<T> Remote for Arc<T> { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].stderr b/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].stderr new file mode 100644 index 000000000..92346c291 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].stderr @@ -0,0 +1,25 @@ +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate + --> $DIR/impl[t]-foreign-for-foreign[t].rs:11:1 + | +LL | impl Remote for Rc<Local> { + | ^^^^^^^^^^^^^^^^--------- + | | | + | | `Rc` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate + --> $DIR/impl[t]-foreign-for-foreign[t].rs:16:1 + | +LL | impl<T> Remote for Arc<T> { + | ^^^^^^^^^^^^^^^^^^^------ + | | | + | | `Arc` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].rs new file mode 100644 index 000000000..6f5605a21 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].rs @@ -0,0 +1,15 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl<T> Remote for Box<T> { + //~^ ERROR type parameter `T` must be used as the type parameter for + // | some local type (e.g., `MyStruct<T>`) +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr new file mode 100644 index 000000000..249a5c44c --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr @@ -0,0 +1,12 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`) + --> $DIR/impl[t]-foreign-for-fundamental[t].rs:10:6 + | +LL | impl<T> Remote for Box<T> { + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign[t]_local]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[foreign[t]_local]-for-foreign.rs new file mode 100644 index 000000000..99f3ce447 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[foreign[t]_local]-for-foreign.rs @@ -0,0 +1,12 @@ +// check-pass +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +impl<T> Remote2<Rc<T>, Local> for usize { } + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs new file mode 100644 index 000000000..81044cd05 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs @@ -0,0 +1,18 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl<T> Remote1<u32> for Box<T> { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +impl<'a, T> Remote1<u32> for &'a T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr new file mode 100644 index 000000000..95a20cc5b --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr @@ -0,0 +1,21 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`) + --> $DIR/impl[t]-foreign[foreign]-for-fundamental[t].rs:10:6 + | +LL | impl<T> Remote1<u32> for Box<T> { + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`) + --> $DIR/impl[t]-foreign[foreign]-for-fundamental[t].rs:14:10 + | +LL | impl<'a, T> Remote1<u32> for &'a T { + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.rs b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.rs new file mode 100644 index 000000000..680ba9f22 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.rs @@ -0,0 +1,14 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl<T> Remote1<u32> for T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr new file mode 100644 index 000000000..aed184767 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr @@ -0,0 +1,12 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`) + --> $DIR/impl[t]-foreign[foreign]-for-t.rs:10:6 + | +LL | impl<T> Remote1<u32> for T { + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs new file mode 100644 index 000000000..fc7649085 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs @@ -0,0 +1,18 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl<T> Remote1<Box<T>> for u32 { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +impl<'a, T> Remote1<&'a T> for u32 { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr new file mode 100644 index 000000000..73b1e2c6e --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr @@ -0,0 +1,21 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`) + --> $DIR/impl[t]-foreign[fundamental[t]]-for-foreign.rs:10:6 + | +LL | impl<T> Remote1<Box<T>> for u32 { + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`) + --> $DIR/impl[t]-foreign[fundamental[t]]-for-foreign.rs:14:10 + | +LL | impl<'a, T> Remote1<&'a T> for u32 { + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs new file mode 100644 index 000000000..703f25dd6 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs @@ -0,0 +1,17 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl<'a, T> Remote1<Box<T>> for &'a T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} +impl<'a, T> Remote1<&'a T> for Box<T> { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr new file mode 100644 index 000000000..5f89a7aa4 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr @@ -0,0 +1,21 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`) + --> $DIR/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs:10:10 + | +LL | impl<'a, T> Remote1<Box<T>> for &'a T { + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`) + --> $DIR/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs:13:10 + | +LL | impl<'a, T> Remote1<&'a T> for Box<T> { + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs new file mode 100644 index 000000000..ec21fdd4e --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs @@ -0,0 +1,15 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl<T> Remote1<Box<T>> for Local {} + +impl<'a, T> Remote1<&'a T> for Local {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs new file mode 100644 index 000000000..5bdab87bf --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs @@ -0,0 +1,17 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl<T> Remote1<Box<T>> for T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} +impl<'a, T> Remote1<&'a T> for T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr new file mode 100644 index 000000000..45559d8b6 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr @@ -0,0 +1,21 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`) + --> $DIR/impl[t]-foreign[fundamental[t]]-for-t.rs:10:6 + | +LL | impl<T> Remote1<Box<T>> for T { + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`) + --> $DIR/impl[t]-foreign[fundamental[t]]-for-t.rs:13:10 + | +LL | impl<'a, T> Remote1<&'a T> for T { + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs new file mode 100644 index 000000000..c9e3594cd --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs @@ -0,0 +1,18 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl<T> Remote2<Box<T>, Local> for u32 { + //~^ ERROR type parameter `T` must be covered by another type +} + +impl<'a, T> Remote2<&'a T, Local> for u32 { + //~^ ERROR type parameter `T` must be covered by another type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.stderr new file mode 100644 index 000000000..f94f04c8d --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.stderr @@ -0,0 +1,21 @@ +error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + --> $DIR/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs:10:6 + | +LL | impl<T> Remote2<Box<T>, Local> for u32 { + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last + +error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + --> $DIR/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs:14:10 + | +LL | impl<'a, T> Remote2<&'a T, Local> for u32 { + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs b/src/test/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs new file mode 100644 index 000000000..62e69357e --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs @@ -0,0 +1,15 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local1<S>(Rc<S>); + +impl<T> Remote1<Box<Local>> for Rc<T> {} +impl<S, T> Remote1<Box<Local1<S>>> for Rc<T> {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign.rs new file mode 100644 index 000000000..1fec19bba --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign.rs @@ -0,0 +1,14 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl<T> Remote1<Local> for Rc<T> {} +impl<T> Remote1<Local> for Vec<Box<T>> {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs new file mode 100644 index 000000000..c8ed28be6 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs @@ -0,0 +1,15 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local1<S>(Rc<S>); + +impl<T> Remote1<Local> for Rc<T> {} +impl<T, S> Remote1<Local1<S>> for Rc<T> {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs new file mode 100644 index 000000000..f9b88c645 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs @@ -0,0 +1,17 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local1<S>(Rc<S>); + +impl<T> Remote1<Local> for Box<Rc<T>> {} +impl<T, S> Remote1<Local1<S>> for Box<Rc<T>> {} +impl<T> Remote1<Box<Local>> for Box<Rc<T>> {} +impl<T, S> Remote1<Box<Local1<S>>> for Box<Rc<T>> {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs new file mode 100644 index 000000000..7709bd9c8 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs @@ -0,0 +1,18 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl<T> Remote1<Local> for Box<T> { + //~^ ERROR type parameter `T` must be covered by another type +} + +impl<T> Remote1<Local> for &T { + //~^ ERROR type parameter `T` must be covered by another type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr new file mode 100644 index 000000000..e68f2fe58 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr @@ -0,0 +1,21 @@ +error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + --> $DIR/impl[t]-foreign[local]-for-fundamental[t].rs:10:6 + | +LL | impl<T> Remote1<Local> for Box<T> { + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last + +error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + --> $DIR/impl[t]-foreign[local]-for-fundamental[t].rs:14:6 + | +LL | impl<T> Remote1<Local> for &T { + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-local.rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-local.rs new file mode 100644 index 000000000..9c14eea1b --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-local.rs @@ -0,0 +1,13 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1<Local> for Local {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-t.rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-t.rs new file mode 100644 index 000000000..eed3a4b5c --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-t.rs @@ -0,0 +1,14 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl<T> Remote1<Local> for T { + //~^ ERROR type parameter `T` must be covered by another type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr new file mode 100644 index 000000000..d97e85dcb --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr @@ -0,0 +1,12 @@ +error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + --> $DIR/impl[t]-foreign[local]-for-t.rs:10:6 + | +LL | impl<T> Remote1<Local> for T { + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[local_fundamental[t]]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[local_fundamental[t]]-for-foreign.rs new file mode 100644 index 000000000..63c342b76 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local_fundamental[t]]-for-foreign.rs @@ -0,0 +1,17 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local2<T>(Rc<T>); + +impl<T> Remote2<Local, Box<T>> for u32 {} +impl<'a, T> Remote2<Local, &'a T> for u32 {} +impl<T> Remote2<Local2<T>, Box<T>> for u32 {} +impl<'a, T> Remote2<Local2<T>, &'a T> for u32 {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.rs new file mode 100644 index 000000000..9bb37c2ba --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.rs @@ -0,0 +1,14 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl<T> Remote1<T> for u32 { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr b/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr new file mode 100644 index 000000000..44e3b7eed --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr @@ -0,0 +1,12 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`) + --> $DIR/impl[t]-foreign[t]-for-foreign.rs:10:6 + | +LL | impl<T> Remote1<T> for u32 { + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs b/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs new file mode 100644 index 000000000..79b5aa3fc --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs @@ -0,0 +1,18 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl<T> Remote1<T> for Box<T> { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +impl<'a, A, B> Remote1<A> for &'a B { + //~^ ERROR type parameter `B` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr b/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr new file mode 100644 index 000000000..80fb5dbec --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr @@ -0,0 +1,21 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`) + --> $DIR/impl[t]-foreign[t]-for-fundamental.rs:10:6 + | +LL | impl<T> Remote1<T> for Box<T> { + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `B` must be used as the type parameter for some local type (e.g., `MyStruct<B>`) + --> $DIR/impl[t]-foreign[t]-for-fundamental.rs:14:13 + | +LL | impl<'a, A, B> Remote1<A> for &'a B { + | ^ type parameter `B` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-local.rs b/src/test/ui/coherence/impl[t]-foreign[t]-for-local.rs new file mode 100644 index 000000000..bc59721c0 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-local.rs @@ -0,0 +1,13 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl<T> Remote1<T> for Local {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-t.rs b/src/test/ui/coherence/impl[t]-foreign[t]-for-t.rs new file mode 100644 index 000000000..bcd6b269a --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-t.rs @@ -0,0 +1,14 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl<T> Remote1<T> for T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr new file mode 100644 index 000000000..ff72969dc --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr @@ -0,0 +1,12 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`) + --> $DIR/impl[t]-foreign[t]-for-t.rs:10:6 + | +LL | impl<T> Remote1<T> for T { + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/inter-crate-ambiguity-causes-notes.rs b/src/test/ui/coherence/inter-crate-ambiguity-causes-notes.rs new file mode 100644 index 000000000..5b11c78ab --- /dev/null +++ b/src/test/ui/coherence/inter-crate-ambiguity-causes-notes.rs @@ -0,0 +1,19 @@ +struct S; + +impl From<()> for S { + fn from(x: ()) -> Self { + S + } +} + +impl<I> From<I> for S +//~^ ERROR conflicting implementations of trait +where + I: Iterator<Item = ()>, +{ + fn from(x: I) -> Self { + S + } +} + +fn main() {} diff --git a/src/test/ui/coherence/inter-crate-ambiguity-causes-notes.stderr b/src/test/ui/coherence/inter-crate-ambiguity-causes-notes.stderr new file mode 100644 index 000000000..038a0199a --- /dev/null +++ b/src/test/ui/coherence/inter-crate-ambiguity-causes-notes.stderr @@ -0,0 +1,14 @@ +error[E0119]: conflicting implementations of trait `std::convert::From<()>` for type `S` + --> $DIR/inter-crate-ambiguity-causes-notes.rs:9:1 + | +LL | impl From<()> for S { + | ------------------- first implementation here +... +LL | impl<I> From<I> for S + | ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S` + | + = note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `()` in future versions + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence/issue-85026.rs b/src/test/ui/coherence/issue-85026.rs new file mode 100644 index 000000000..8b116545a --- /dev/null +++ b/src/test/ui/coherence/issue-85026.rs @@ -0,0 +1,10 @@ +#![feature(auto_traits)] +auto trait AutoTrait {} + +// You cannot impl your own `dyn AutoTrait`. +impl dyn AutoTrait {} //~ERROR E0785 + +// You cannot impl someone else's `dyn AutoTrait` +impl dyn Unpin {} //~ERROR E0785 + +fn main() {} diff --git a/src/test/ui/coherence/issue-85026.stderr b/src/test/ui/coherence/issue-85026.stderr new file mode 100644 index 000000000..a5da19bbf --- /dev/null +++ b/src/test/ui/coherence/issue-85026.stderr @@ -0,0 +1,19 @@ +error[E0785]: cannot define inherent `impl` for a dyn auto trait + --> $DIR/issue-85026.rs:5:6 + | +LL | impl dyn AutoTrait {} + | ^^^^^^^^^^^^^ impl requires at least one non-auto trait + | + = note: define and implement a new trait or type instead + +error[E0785]: cannot define inherent `impl` for a dyn auto trait + --> $DIR/issue-85026.rs:8:6 + | +LL | impl dyn Unpin {} + | ^^^^^^^^^ impl requires at least one non-auto trait + | + = note: define and implement a new trait or type instead + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0785`. diff --git a/src/test/ui/coherence/issue-99663-2.rs b/src/test/ui/coherence/issue-99663-2.rs new file mode 100644 index 000000000..10a0a5688 --- /dev/null +++ b/src/test/ui/coherence/issue-99663-2.rs @@ -0,0 +1,22 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +struct Outer<T: ?Sized> { + i: InnerSend<T>, +} + +type InnerSend<T: ?Sized> = impl Send; + +fn constrain<T: ?Sized>() -> InnerSend<T> { + () +} + +trait SendMustNotImplDrop {} + +#[allow(drop_bounds)] +impl<T: ?Sized + Send + Drop> SendMustNotImplDrop for T {} + +impl<T: ?Sized> SendMustNotImplDrop for Outer<T> {} + +fn main() {} diff --git a/src/test/ui/coherence/issue-99663.rs b/src/test/ui/coherence/issue-99663.rs new file mode 100644 index 000000000..a2d4d398c --- /dev/null +++ b/src/test/ui/coherence/issue-99663.rs @@ -0,0 +1,22 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +struct Send<T> { + i: InnerSend<T>, +} + +type InnerSend<T> = impl Sized; + +fn constrain<T>() -> InnerSend<T> { + () +} + +trait SendMustNotImplDrop {} + +#[allow(drop_bounds)] +impl<T: Drop> SendMustNotImplDrop for T {} + +impl<T> SendMustNotImplDrop for Send<T> {} + +fn main() {} diff --git a/src/test/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs b/src/test/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs new file mode 100644 index 000000000..d18e3f453 --- /dev/null +++ b/src/test/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs @@ -0,0 +1,26 @@ +// run-pass +// aux-build:re_rebalance_coherence_lib-rpass.rs + +#![allow(dead_code)] +// check that a generic type with a default value from an associated type can be used without +// specifying the value, and without invoking coherence errors. + +extern crate re_rebalance_coherence_lib_rpass as lib; +use lib::*; + +struct MyString {} + +impl LibToOwned for MyString { + type Owned = String; +} + +impl PartialEq<MyString> for LibCow<MyString> { + fn eq(&self, _other: &MyString) -> bool { + // Test that the default type is used. + let _s: &String = &self.o; + + false + } +} + +fn main() {} diff --git a/src/test/ui/coherence/re-rebalance-coherence.rs b/src/test/ui/coherence/re-rebalance-coherence.rs new file mode 100644 index 000000000..38d096b08 --- /dev/null +++ b/src/test/ui/coherence/re-rebalance-coherence.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:re_rebalance_coherence_lib.rs + +extern crate re_rebalance_coherence_lib as lib; +use lib::*; + +struct Oracle; +impl Backend for Oracle {} +impl<'a, T:'a, Tab> QueryFragment<Oracle> for BatchInsert<'a, T, Tab> {} + +fn main() {} |