--- /dev/null
+// check that the `for<T> T: From<!>` impl is reserved
+
+#![feature(never_type)]
+
+pub struct MyFoo;
+pub trait MyTrait {}
+
+impl MyTrait for MyFoo {}
+// This will conflict with the first impl if we impl `for<T> T: From<!>`.
+impl<T> MyTrait for T where T: From<!> {} //~ ERROR conflicting implementation
+
+fn main() {}
--- /dev/null
+error[E0119]: conflicting implementations of trait `MyTrait` for type `MyFoo`:
+ --> $DIR/never-from-impl-is-reserved.rs:10:1
+ |
+LL | impl MyTrait for MyFoo {}
+ | ---------------------- first implementation here
+LL | // This will conflict with the first impl if we impl `for<T> T: From<!>`.
+LL | impl<T> MyTrait for T where T: From<!> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyFoo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
+++ /dev/null
-// check that the `for<T> T: From<!>` impl is reserved
-
-#![feature(never_type)]
-
-pub struct MyFoo;
-pub trait MyTrait {}
-
-impl MyTrait for MyFoo {}
-// This will conflict with the first impl if we impl `for<T> T: From<!>`.
-impl<T> MyTrait for T where T: From<!> {} //~ ERROR conflicting implementation
-
-fn main() {}
+++ /dev/null
-error[E0119]: conflicting implementations of trait `MyTrait` for type `MyFoo`:
- --> $DIR/never-impl-is-reserved.rs:10:1
- |
-LL | impl MyTrait for MyFoo {}
- | ---------------------- first implementation here
-LL | // This will conflict with the first impl if we impl `for<T> T: From<!>`.
-LL | impl<T> MyTrait for T where T: From<!> {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyFoo`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
--- /dev/null
+// compile-fail
+
+// check that reservation impls are accounted for in negative reasoning.
+
+#![feature(rustc_attrs)]
+
+trait MyTrait {}
+#[rustc_reservation_impl]
+impl MyTrait for () {}
+
+trait OtherTrait {}
+impl OtherTrait for () {}
+impl<T: MyTrait> OtherTrait for T {}
+//~^ ERROR conflicting implementations
+
+fn main() {}
--- /dev/null
+error[E0119]: conflicting implementations of trait `OtherTrait` for type `()`:
+ --> $DIR/reservation-impl-coherence-conflict.rs:13:1
+ |
+LL | impl OtherTrait for () {}
+ | ---------------------- first implementation here
+LL | impl<T: MyTrait> OtherTrait for T {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
--- /dev/null
+// compile-fail
+
+// check that reservation impls can't be used as normal impls in positive reasoning.
+
+#![feature(rustc_attrs)]
+
+trait MyTrait { fn foo(&self); }
+#[rustc_reservation_impl]
+impl MyTrait for () { fn foo(&self) {} }
+
+fn main() {
+ <() as MyTrait>::foo(&());
+ //~^ ERROR the trait bound `(): MyTrait` is not satisfied
+}
--- /dev/null
+error[E0277]: the trait bound `(): MyTrait` is not satisfied
+ --> $DIR/reservation-impl-no-use.rs:12:5
+ |
+LL | trait MyTrait { fn foo(&self); }
+ | -------------- required by `MyTrait::foo`
+...
+LL | <() as MyTrait>::foo(&());
+ | ^^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `()`
+ |
+ = help: the following implementations were found:
+ <() as MyTrait>
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
--- /dev/null
+// run-pass
+
+// rpass test for reservation impls. Not 100% required because `From` uses them,
+// but still.
+
+#![feature(rustc_attrs)]
+
+use std::mem;
+
+trait MyTrait<S> {
+ fn foo(&self, s: S) -> usize;
+}
+
+#[rustc_reservation_impl]
+impl<T> MyTrait<u64> for T {
+ fn foo(&self, _x: u64) -> usize { 0 }
+}
+
+// reservation impls don't create coherence conflicts, even with
+// non-chain overlap.
+impl<S> MyTrait<S> for u32 {
+ fn foo(&self, _x: S) -> usize { mem::size_of::<S>() }
+}
+
+fn main() {
+ // ...and the non-reservation impl gets picked.XS
+ assert_eq!(0u32.foo(0u64), mem::size_of::<u64>());
+}