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