about summary refs log tree commit diff
path: root/tests/ui/coherence
diff options
context:
space:
mode:
authorAlbert Larsan <74931857+albertlarsan68@users.noreply.github.com>2023-01-05 09:13:28 +0100
committerAlbert Larsan <74931857+albertlarsan68@users.noreply.github.com>2023-01-11 09:32:08 +0000
commitcf2dff2b1e3fa55fa5415d524200070d0d7aacfe (patch)
tree40a88d9a46aaf3e8870676eb2538378b75a263eb /tests/ui/coherence
parentca855e6e42787ecd062d81d53336fe6788ef51a9 (diff)
downloadrust-cf2dff2b1e3fa55fa5415d524200070d0d7aacfe.tar.gz
rust-cf2dff2b1e3fa55fa5415d524200070d0d7aacfe.zip
Move /src/test to /tests
Diffstat (limited to 'tests/ui/coherence')
-rw-r--r--tests/ui/coherence/auxiliary/coherence_copy_like_lib.rs10
-rw-r--r--tests/ui/coherence/auxiliary/coherence_fundamental_trait_lib.rs7
-rw-r--r--tests/ui/coherence/auxiliary/coherence_inherent_cc_lib.rs11
-rw-r--r--tests/ui/coherence/auxiliary/coherence_lib.rs15
-rw-r--r--tests/ui/coherence/auxiliary/coherence_orphan_lib.rs3
-rw-r--r--tests/ui/coherence/auxiliary/error_lib.rs6
-rw-r--r--tests/ui/coherence/auxiliary/go_trait.rs43
-rw-r--r--tests/ui/coherence/auxiliary/option_future.rs8
-rw-r--r--tests/ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs31
-rw-r--r--tests/ui/coherence/auxiliary/re_rebalance_coherence_lib.rs22
-rw-r--r--tests/ui/coherence/auxiliary/trait-with-const-param.rs1
-rw-r--r--tests/ui/coherence/auxiliary/trait_impl_conflict.rs6
-rw-r--r--tests/ui/coherence/coherence-all-remote.rs9
-rw-r--r--tests/ui/coherence/coherence-all-remote.stderr12
-rw-r--r--tests/ui/coherence/coherence-bigint-int.rs13
-rw-r--r--tests/ui/coherence/coherence-bigint-param.rs11
-rw-r--r--tests/ui/coherence/coherence-bigint-param.stderr12
-rw-r--r--tests/ui/coherence/coherence-bigint-vecint.rs13
-rw-r--r--tests/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.rs30
-rw-r--r--tests/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.stderr12
-rw-r--r--tests/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.rs25
-rw-r--r--tests/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.stderr12
-rw-r--r--tests/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.rs20
-rw-r--r--tests/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr13
-rw-r--r--tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs27
-rw-r--r--tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr12
-rw-r--r--tests/ui/coherence/coherence-blanket-conflicts-with-specific-trait.rs29
-rw-r--r--tests/ui/coherence/coherence-blanket-conflicts-with-specific-trait.stderr12
-rw-r--r--tests/ui/coherence/coherence-blanket-conflicts-with-specific.rs24
-rw-r--r--tests/ui/coherence/coherence-blanket-conflicts-with-specific.stderr12
-rw-r--r--tests/ui/coherence/coherence-blanket.rs16
-rw-r--r--tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs17
-rw-r--r--tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr22
-rw-r--r--tests/ui/coherence/coherence-covered-type-parameter.rs14
-rw-r--r--tests/ui/coherence/coherence-cow.re_a.stderr14
-rw-r--r--tests/ui/coherence/coherence-cow.re_b.stderr14
-rw-r--r--tests/ui/coherence/coherence-cow.re_c.stderr14
-rw-r--r--tests/ui/coherence/coherence-cow.rs29
-rw-r--r--tests/ui/coherence/coherence-cross-crate-conflict.rs13
-rw-r--r--tests/ui/coherence/coherence-cross-crate-conflict.stderr12
-rw-r--r--tests/ui/coherence/coherence-default-trait-impl.rs16
-rw-r--r--tests/ui/coherence/coherence-default-trait-impl.stderr28
-rw-r--r--tests/ui/coherence/coherence-error-suppression.rs16
-rw-r--r--tests/ui/coherence/coherence-error-suppression.stderr9
-rw-r--r--tests/ui/coherence/coherence-fn-covariant-bound-vs-static.rs26
-rw-r--r--tests/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr13
-rw-r--r--tests/ui/coherence/coherence-fn-implied-bounds.rs26
-rw-r--r--tests/ui/coherence/coherence-fn-implied-bounds.stderr20
-rw-r--r--tests/ui/coherence/coherence-fn-inputs.rs25
-rw-r--r--tests/ui/coherence/coherence-fn-inputs.stderr13
-rw-r--r--tests/ui/coherence/coherence-free-vs-bound-region.rs21
-rw-r--r--tests/ui/coherence/coherence-free-vs-bound-region.stderr20
-rw-r--r--tests/ui/coherence/coherence-fundamental-trait-objects.rs15
-rw-r--r--tests/ui/coherence/coherence-fundamental-trait-objects.stderr14
-rw-r--r--tests/ui/coherence/coherence-impl-in-fn.rs14
-rw-r--r--tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs30
-rw-r--r--tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr39
-rw-r--r--tests/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs30
-rw-r--r--tests/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr39
-rw-r--r--tests/ui/coherence/coherence-impl-trait-for-trait-object-safe.rs10
-rw-r--r--tests/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr18
-rw-r--r--tests/ui/coherence/coherence-impl-trait-for-trait.rs20
-rw-r--r--tests/ui/coherence/coherence-impl-trait-for-trait.stderr21
-rw-r--r--tests/ui/coherence/coherence-impls-copy.rs36
-rw-r--r--tests/ui/coherence/coherence-impls-copy.stderr76
-rw-r--r--tests/ui/coherence/coherence-impls-send.rs28
-rw-r--r--tests/ui/coherence/coherence-impls-send.stderr43
-rw-r--r--tests/ui/coherence/coherence-impls-sized.rs36
-rw-r--r--tests/ui/coherence/coherence-impls-sized.stderr73
-rw-r--r--tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs24
-rw-r--r--tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr26
-rw-r--r--tests/ui/coherence/coherence-inherited-subtyping.old.stderr14
-rw-r--r--tests/ui/coherence/coherence-inherited-subtyping.re.stderr14
-rw-r--r--tests/ui/coherence/coherence-inherited-subtyping.rs21
-rw-r--r--tests/ui/coherence/coherence-iterator-vec-any-elem.rs14
-rw-r--r--tests/ui/coherence/coherence-iterator-vec.rs14
-rw-r--r--tests/ui/coherence/coherence-lone-type-parameter.rs10
-rw-r--r--tests/ui/coherence/coherence-lone-type-parameter.stderr12
-rw-r--r--tests/ui/coherence/coherence-multidispatch-tuple.rs24
-rw-r--r--tests/ui/coherence/coherence-negative-impls-copy-bad.rs11
-rw-r--r--tests/ui/coherence/coherence-negative-impls-copy-bad.stderr36
-rw-r--r--tests/ui/coherence/coherence-negative-impls-copy.rs29
-rw-r--r--tests/ui/coherence/coherence-negative-impls-safe-rpass.rs13
-rw-r--r--tests/ui/coherence/coherence-negative-impls-safe.rs10
-rw-r--r--tests/ui/coherence/coherence-negative-impls-safe.stderr12
-rw-r--r--tests/ui/coherence/coherence-negative-inherent-where-bounds.rs25
-rw-r--r--tests/ui/coherence/coherence-negative-inherent.rs22
-rw-r--r--tests/ui/coherence/coherence-negative-outlives-lifetimes.rs17
-rw-r--r--tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr11
-rw-r--r--tests/ui/coherence/coherence-no-direct-lifetime-dispatch.rs9
-rw-r--r--tests/ui/coherence/coherence-no-direct-lifetime-dispatch.stderr11
-rw-r--r--tests/ui/coherence/coherence-orphan.rs20
-rw-r--r--tests/ui/coherence/coherence-orphan.stderr26
-rw-r--r--tests/ui/coherence/coherence-overlap-all-t-and-tuple.rs20
-rw-r--r--tests/ui/coherence/coherence-overlap-all-t-and-tuple.stderr12
-rw-r--r--tests/ui/coherence/coherence-overlap-double-negative.rs12
-rw-r--r--tests/ui/coherence/coherence-overlap-downstream-inherent.rs17
-rw-r--r--tests/ui/coherence/coherence-overlap-downstream-inherent.stderr23
-rw-r--r--tests/ui/coherence/coherence-overlap-downstream.rs17
-rw-r--r--tests/ui/coherence/coherence-overlap-downstream.stderr21
-rw-r--r--tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs13
-rw-r--r--tests/ui/coherence/coherence-overlap-issue-23516-inherent.stderr14
-rw-r--r--tests/ui/coherence/coherence-overlap-issue-23516.rs11
-rw-r--r--tests/ui/coherence/coherence-overlap-issue-23516.stderr13
-rw-r--r--tests/ui/coherence/coherence-overlap-messages.rs28
-rw-r--r--tests/ui/coherence/coherence-overlap-messages.stderr44
-rw-r--r--tests/ui/coherence/coherence-overlap-negate-alias-strict.rs19
-rw-r--r--tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.rs8
-rw-r--r--tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr11
-rw-r--r--tests/ui/coherence/coherence-overlap-negate-strict.rs18
-rw-r--r--tests/ui/coherence/coherence-overlap-negate-use-feature-gate.rs11
-rw-r--r--tests/ui/coherence/coherence-overlap-negative-trait.rs16
-rw-r--r--tests/ui/coherence/coherence-overlap-negative-trait2.rs17
-rw-r--r--tests/ui/coherence/coherence-overlap-super-negative.rs18
-rw-r--r--tests/ui/coherence/coherence-overlap-trait-alias.rs20
-rw-r--r--tests/ui/coherence/coherence-overlap-trait-alias.stderr17
-rw-r--r--tests/ui/coherence/coherence-overlap-upstream-inherent.rs16
-rw-r--r--tests/ui/coherence/coherence-overlap-upstream-inherent.stderr14
-rw-r--r--tests/ui/coherence/coherence-overlap-upstream.rs16
-rw-r--r--tests/ui/coherence/coherence-overlap-upstream.stderr13
-rw-r--r--tests/ui/coherence/coherence-overlap-with-regions.rs16
-rw-r--r--tests/ui/coherence/coherence-overlapping-pairs.rs11
-rw-r--r--tests/ui/coherence/coherence-overlapping-pairs.stderr14
-rw-r--r--tests/ui/coherence/coherence-pair-covered-uncovered-1.rs15
-rw-r--r--tests/ui/coherence/coherence-pair-covered-uncovered-1.stderr15
-rw-r--r--tests/ui/coherence/coherence-pair-covered-uncovered.rs11
-rw-r--r--tests/ui/coherence/coherence-pair-covered-uncovered.stderr14
-rw-r--r--tests/ui/coherence/coherence-projection-conflict-orphan.rs19
-rw-r--r--tests/ui/coherence/coherence-projection-conflict-orphan.stderr14
-rw-r--r--tests/ui/coherence/coherence-projection-conflict-ty-param.rs13
-rw-r--r--tests/ui/coherence/coherence-projection-conflict-ty-param.stderr12
-rw-r--r--tests/ui/coherence/coherence-projection-conflict.rs18
-rw-r--r--tests/ui/coherence/coherence-projection-conflict.stderr12
-rw-r--r--tests/ui/coherence/coherence-projection-ok-orphan.rs17
-rw-r--r--tests/ui/coherence/coherence-projection-ok.rs17
-rw-r--r--tests/ui/coherence/coherence-rfc447-constrained.rs22
-rw-r--r--tests/ui/coherence/coherence-subtyping.rs20
-rw-r--r--tests/ui/coherence/coherence-subtyping.stderr16
-rw-r--r--tests/ui/coherence/coherence-tuple-conflict.rs20
-rw-r--r--tests/ui/coherence/coherence-tuple-conflict.stderr12
-rw-r--r--tests/ui/coherence/coherence-unsafe-trait-object-impl.rs18
-rw-r--r--tests/ui/coherence/coherence-unsafe-trait-object-impl.stderr17
-rw-r--r--tests/ui/coherence/coherence-vec-local-2.rs14
-rw-r--r--tests/ui/coherence/coherence-vec-local-2.stderr14
-rw-r--r--tests/ui/coherence/coherence-vec-local.rs14
-rw-r--r--tests/ui/coherence/coherence-vec-local.stderr14
-rw-r--r--tests/ui/coherence/coherence-wasm-bindgen.rs37
-rw-r--r--tests/ui/coherence/coherence-wasm-bindgen.stderr21
-rw-r--r--tests/ui/coherence/coherence-where-clause.rs38
-rw-r--r--tests/ui/coherence/coherence-with-closure.rs14
-rw-r--r--tests/ui/coherence/coherence-with-closure.stderr11
-rw-r--r--tests/ui/coherence/coherence-with-generator.rs18
-rw-r--r--tests/ui/coherence/coherence-with-generator.stderr11
-rw-r--r--tests/ui/coherence/coherence_copy_like.rs19
-rw-r--r--tests/ui/coherence/coherence_copy_like_err_fundamental_struct.rs24
-rw-r--r--tests/ui/coherence/coherence_copy_like_err_fundamental_struct_ref.rs21
-rw-r--r--tests/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.rs20
-rw-r--r--tests/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr14
-rw-r--r--tests/ui/coherence/coherence_copy_like_err_struct.rs22
-rw-r--r--tests/ui/coherence/coherence_copy_like_err_struct.stderr14
-rw-r--r--tests/ui/coherence/coherence_copy_like_err_tuple.rs21
-rw-r--r--tests/ui/coherence/coherence_copy_like_err_tuple.stderr14
-rw-r--r--tests/ui/coherence/coherence_inherent.rs36
-rw-r--r--tests/ui/coherence/coherence_inherent.stderr15
-rw-r--r--tests/ui/coherence/coherence_inherent_cc.rs28
-rw-r--r--tests/ui/coherence/coherence_inherent_cc.stderr15
-rw-r--r--tests/ui/coherence/coherence_local.rs20
-rw-r--r--tests/ui/coherence/coherence_local_err_struct.rs18
-rw-r--r--tests/ui/coherence/coherence_local_err_struct.stderr14
-rw-r--r--tests/ui/coherence/coherence_local_err_tuple.rs18
-rw-r--r--tests/ui/coherence/coherence_local_err_tuple.stderr14
-rw-r--r--tests/ui/coherence/coherence_local_ref.rs14
-rw-r--r--tests/ui/coherence/conflicting-impl-with-err.rs16
-rw-r--r--tests/ui/coherence/conflicting-impl-with-err.stderr15
-rw-r--r--tests/ui/coherence/const-generics-orphan-check-ok.rs28
-rw-r--r--tests/ui/coherence/deep-bad-copy-reason.rs40
-rw-r--r--tests/ui/coherence/deep-bad-copy-reason.stderr18
-rw-r--r--tests/ui/coherence/impl-foreign-for-foreign.rs15
-rw-r--r--tests/ui/coherence/impl-foreign-for-foreign.stderr14
-rw-r--r--tests/ui/coherence/impl-foreign-for-foreign[foreign].rs23
-rw-r--r--tests/ui/coherence/impl-foreign-for-foreign[foreign].stderr39
-rw-r--r--tests/ui/coherence/impl-foreign-for-foreign[local].rs14
-rw-r--r--tests/ui/coherence/impl-foreign-for-fundamental[foreign].rs19
-rw-r--r--tests/ui/coherence/impl-foreign-for-fundamental[foreign].stderr27
-rw-r--r--tests/ui/coherence/impl-foreign-for-fundamental[local].rs15
-rw-r--r--tests/ui/coherence/impl-foreign-for-local.rs13
-rw-r--r--tests/ui/coherence/impl-foreign-for-locally-defined-fundamental.rs15
-rw-r--r--tests/ui/coherence/impl-foreign-for-locally-defined-fundamental[foreign].rs15
-rw-r--r--tests/ui/coherence/impl-foreign[foreign]-for-foreign.rs15
-rw-r--r--tests/ui/coherence/impl-foreign[foreign]-for-foreign.stderr15
-rw-r--r--tests/ui/coherence/impl-foreign[foreign]-for-local.rs14
-rw-r--r--tests/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs24
-rw-r--r--tests/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr42
-rw-r--r--tests/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs16
-rw-r--r--tests/ui/coherence/impl[t]-foreign-for-foreign[t].rs21
-rw-r--r--tests/ui/coherence/impl[t]-foreign-for-foreign[t].stderr25
-rw-r--r--tests/ui/coherence/impl[t]-foreign-for-fundamental[t].rs15
-rw-r--r--tests/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr12
-rw-r--r--tests/ui/coherence/impl[t]-foreign[foreign[t]_local]-for-foreign.rs12
-rw-r--r--tests/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs18
-rw-r--r--tests/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr21
-rw-r--r--tests/ui/coherence/impl[t]-foreign[foreign]-for-t.rs14
-rw-r--r--tests/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr12
-rw-r--r--tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs18
-rw-r--r--tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr21
-rw-r--r--tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs17
-rw-r--r--tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr21
-rw-r--r--tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs15
-rw-r--r--tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs17
-rw-r--r--tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr21
-rw-r--r--tests/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs18
-rw-r--r--tests/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.stderr21
-rw-r--r--tests/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs15
-rw-r--r--tests/ui/coherence/impl[t]-foreign[local]-for-foreign.rs14
-rw-r--r--tests/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs15
-rw-r--r--tests/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs17
-rw-r--r--tests/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs18
-rw-r--r--tests/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr21
-rw-r--r--tests/ui/coherence/impl[t]-foreign[local]-for-local.rs13
-rw-r--r--tests/ui/coherence/impl[t]-foreign[local]-for-t.rs14
-rw-r--r--tests/ui/coherence/impl[t]-foreign[local]-for-t.stderr12
-rw-r--r--tests/ui/coherence/impl[t]-foreign[local_fundamental[t]]-for-foreign.rs17
-rw-r--r--tests/ui/coherence/impl[t]-foreign[t]-for-foreign.rs14
-rw-r--r--tests/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr12
-rw-r--r--tests/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs18
-rw-r--r--tests/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr21
-rw-r--r--tests/ui/coherence/impl[t]-foreign[t]-for-local.rs13
-rw-r--r--tests/ui/coherence/impl[t]-foreign[t]-for-t.rs14
-rw-r--r--tests/ui/coherence/impl[t]-foreign[t]-for-t.stderr12
-rw-r--r--tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs19
-rw-r--r--tests/ui/coherence/inter-crate-ambiguity-causes-notes.stderr14
-rw-r--r--tests/ui/coherence/issue-85026.rs10
-rw-r--r--tests/ui/coherence/issue-85026.stderr19
-rw-r--r--tests/ui/coherence/issue-99663-2.rs22
-rw-r--r--tests/ui/coherence/issue-99663.rs22
-rw-r--r--tests/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs26
-rw-r--r--tests/ui/coherence/re-rebalance-coherence.rs11
-rw-r--r--tests/ui/coherence/strict-coherence-needs-negative-coherence.rs7
-rw-r--r--tests/ui/coherence/strict-coherence-needs-negative-coherence.stderr10
239 files changed, 4386 insertions, 0 deletions
diff --git a/tests/ui/coherence/auxiliary/coherence_copy_like_lib.rs b/tests/ui/coherence/auxiliary/coherence_copy_like_lib.rs
new file mode 100644
index 00000000000..b5b4802c112
--- /dev/null
+++ b/tests/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/tests/ui/coherence/auxiliary/coherence_fundamental_trait_lib.rs b/tests/ui/coherence/auxiliary/coherence_fundamental_trait_lib.rs
new file mode 100644
index 00000000000..21aaea47963
--- /dev/null
+++ b/tests/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/tests/ui/coherence/auxiliary/coherence_inherent_cc_lib.rs b/tests/ui/coherence/auxiliary/coherence_inherent_cc_lib.rs
new file mode 100644
index 00000000000..08d22fbedf5
--- /dev/null
+++ b/tests/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/tests/ui/coherence/auxiliary/coherence_lib.rs b/tests/ui/coherence/auxiliary/coherence_lib.rs
new file mode 100644
index 00000000000..c22819831ab
--- /dev/null
+++ b/tests/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/tests/ui/coherence/auxiliary/coherence_orphan_lib.rs b/tests/ui/coherence/auxiliary/coherence_orphan_lib.rs
new file mode 100644
index 00000000000..2664ef55069
--- /dev/null
+++ b/tests/ui/coherence/auxiliary/coherence_orphan_lib.rs
@@ -0,0 +1,3 @@
+pub trait TheTrait<T> {
+    fn the_fn(&self);
+}
diff --git a/tests/ui/coherence/auxiliary/error_lib.rs b/tests/ui/coherence/auxiliary/error_lib.rs
new file mode 100644
index 00000000000..19ff9ae62fd
--- /dev/null
+++ b/tests/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/tests/ui/coherence/auxiliary/go_trait.rs b/tests/ui/coherence/auxiliary/go_trait.rs
new file mode 100644
index 00000000000..aa0ec22896d
--- /dev/null
+++ b/tests/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/tests/ui/coherence/auxiliary/option_future.rs b/tests/ui/coherence/auxiliary/option_future.rs
new file mode 100644
index 00000000000..067de1cd867
--- /dev/null
+++ b/tests/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/tests/ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs b/tests/ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs
new file mode 100644
index 00000000000..9a191bad8b0
--- /dev/null
+++ b/tests/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/tests/ui/coherence/auxiliary/re_rebalance_coherence_lib.rs b/tests/ui/coherence/auxiliary/re_rebalance_coherence_lib.rs
new file mode 100644
index 00000000000..41b9d64d5f7
--- /dev/null
+++ b/tests/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/tests/ui/coherence/auxiliary/trait-with-const-param.rs b/tests/ui/coherence/auxiliary/trait-with-const-param.rs
new file mode 100644
index 00000000000..a44eb14f8e4
--- /dev/null
+++ b/tests/ui/coherence/auxiliary/trait-with-const-param.rs
@@ -0,0 +1 @@
+pub trait Trait<const N: usize, T> {}
diff --git a/tests/ui/coherence/auxiliary/trait_impl_conflict.rs b/tests/ui/coherence/auxiliary/trait_impl_conflict.rs
new file mode 100644
index 00000000000..5e5f017ed45
--- /dev/null
+++ b/tests/ui/coherence/auxiliary/trait_impl_conflict.rs
@@ -0,0 +1,6 @@
+pub trait Foo {
+    fn foo() {}
+}
+
+impl Foo for isize {
+}
diff --git a/tests/ui/coherence/coherence-all-remote.rs b/tests/ui/coherence/coherence-all-remote.rs
new file mode 100644
index 00000000000..5c3bfee822f
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-all-remote.stderr b/tests/ui/coherence/coherence-all-remote.stderr
new file mode 100644
index 00000000000..7eca4175339
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-bigint-int.rs b/tests/ui/coherence/coherence-bigint-int.rs
new file mode 100644
index 00000000000..02945e9dade
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-bigint-param.rs b/tests/ui/coherence/coherence-bigint-param.rs
new file mode 100644
index 00000000000..c6543aaf67d
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-bigint-param.stderr b/tests/ui/coherence/coherence-bigint-param.stderr
new file mode 100644
index 00000000000..e8d74c917e4
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-bigint-vecint.rs b/tests/ui/coherence/coherence-bigint-vecint.rs
new file mode 100644
index 00000000000..a5dba90be5c
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.rs b/tests/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.rs
new file mode 100644
index 00000000000..93a4bc5fe78
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.stderr b/tests/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.stderr
new file mode 100644
index 00000000000..9156972a1df
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.rs b/tests/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.rs
new file mode 100644
index 00000000000..950a08ff224
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.stderr b/tests/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.stderr
new file mode 100644
index 00000000000..8400968e122
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.rs b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.rs
new file mode 100644
index 00000000000..bccbac2ff16
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr
new file mode 100644
index 00000000000..4d7872598b1
--- /dev/null
+++ b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr
@@ -0,0 +1,13 @@
+error[E0119]: conflicting implementations of 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/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs
new file mode 100644
index 00000000000..6a9db217373
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr
new file mode 100644
index 00000000000..c2a925213da
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-blanket-conflicts-with-specific-trait.rs b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-trait.rs
new file mode 100644
index 00000000000..02f9217da68
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-blanket-conflicts-with-specific-trait.stderr b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-trait.stderr
new file mode 100644
index 00000000000..e1a5dffebda
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-blanket-conflicts-with-specific.rs b/tests/ui/coherence/coherence-blanket-conflicts-with-specific.rs
new file mode 100644
index 00000000000..5a562ff6ab9
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-blanket-conflicts-with-specific.stderr b/tests/ui/coherence/coherence-blanket-conflicts-with-specific.stderr
new file mode 100644
index 00000000000..ba60a2ea929
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-blanket.rs b/tests/ui/coherence/coherence-blanket.rs
new file mode 100644
index 00000000000..55fa89d7507
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs
new file mode 100644
index 00000000000..24b87892753
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr
new file mode 100644
index 00000000000..2463f38a922
--- /dev/null
+++ b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr
@@ -0,0 +1,22 @@
+error[E0751]: found both positive and negative implementation of trait `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 `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/tests/ui/coherence/coherence-covered-type-parameter.rs b/tests/ui/coherence/coherence-covered-type-parameter.rs
new file mode 100644
index 00000000000..bb95c59d183
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-cow.re_a.stderr b/tests/ui/coherence/coherence-cow.re_a.stderr
new file mode 100644
index 00000000000..fe4b5b41078
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-cow.re_b.stderr b/tests/ui/coherence/coherence-cow.re_b.stderr
new file mode 100644
index 00000000000..da4ede3251e
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-cow.re_c.stderr b/tests/ui/coherence/coherence-cow.re_c.stderr
new file mode 100644
index 00000000000..d1a20c0ca10
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-cow.rs b/tests/ui/coherence/coherence-cow.rs
new file mode 100644
index 00000000000..86a8d0963b8
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-cross-crate-conflict.rs b/tests/ui/coherence/coherence-cross-crate-conflict.rs
new file mode 100644
index 00000000000..588630957c9
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-cross-crate-conflict.stderr b/tests/ui/coherence/coherence-cross-crate-conflict.stderr
new file mode 100644
index 00000000000..3d253d56a45
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-default-trait-impl.rs b/tests/ui/coherence/coherence-default-trait-impl.rs
new file mode 100644
index 00000000000..d57fb477754
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-default-trait-impl.stderr b/tests/ui/coherence/coherence-default-trait-impl.stderr
new file mode 100644
index 00000000000..7be5b92a7de
--- /dev/null
+++ b/tests/ui/coherence/coherence-default-trait-impl.stderr
@@ -0,0 +1,28 @@
+error[E0199]: implementing the trait `MySafeTrait` is not unsafe
+  --> $DIR/coherence-default-trait-impl.rs:8:1
+   |
+LL | unsafe impl MySafeTrait for Foo {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove `unsafe` from this trait implementation
+   |
+LL - unsafe impl MySafeTrait for Foo {}
+LL + 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 {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the trait `MyUnsafeTrait` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword
+help: add `unsafe` to this trait implementation
+   |
+LL | unsafe 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/tests/ui/coherence/coherence-error-suppression.rs b/tests/ui/coherence/coherence-error-suppression.rs
new file mode 100644
index 00000000000..909214c1b6e
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-error-suppression.stderr b/tests/ui/coherence/coherence-error-suppression.stderr
new file mode 100644
index 00000000000..aadc80cb1c3
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-fn-covariant-bound-vs-static.rs b/tests/ui/coherence/coherence-fn-covariant-bound-vs-static.rs
new file mode 100644
index 00000000000..99f805f7f0f
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr b/tests/ui/coherence/coherence-fn-covariant-bound-vs-static.stderr
new file mode 100644
index 00000000000..7dabd97b94e
--- /dev/null
+++ b/tests/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(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(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/tests/ui/coherence/coherence-fn-implied-bounds.rs b/tests/ui/coherence/coherence-fn-implied-bounds.rs
new file mode 100644
index 00000000000..4539af9a32e
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-fn-implied-bounds.stderr b/tests/ui/coherence/coherence-fn-implied-bounds.stderr
new file mode 100644
index 00000000000..2018712043e
--- /dev/null
+++ b/tests/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`
+   |
+   = 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
+note: the lint level is defined here
+  --> $DIR/coherence-fn-implied-bounds.rs:15:9
+   |
+LL | #![deny(coherence_leak_check)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/coherence/coherence-fn-inputs.rs b/tests/ui/coherence/coherence-fn-inputs.rs
new file mode 100644
index 00000000000..3afec5c5459
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-fn-inputs.stderr b/tests/ui/coherence/coherence-fn-inputs.stderr
new file mode 100644
index 00000000000..82bd8a35f45
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-free-vs-bound-region.rs b/tests/ui/coherence/coherence-free-vs-bound-region.rs
new file mode 100644
index 00000000000..2f5c49d293d
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-free-vs-bound-region.stderr b/tests/ui/coherence/coherence-free-vs-bound-region.stderr
new file mode 100644
index 00000000000..e2d84b83320
--- /dev/null
+++ b/tests/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)`
+   |
+   = 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
+note: the lint level is defined here
+  --> $DIR/coherence-free-vs-bound-region.rs:10:9
+   |
+LL | #![deny(coherence_leak_check)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/coherence/coherence-fundamental-trait-objects.rs b/tests/ui/coherence/coherence-fundamental-trait-objects.rs
new file mode 100644
index 00000000000..dd127bf7f4b
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-fundamental-trait-objects.stderr b/tests/ui/coherence/coherence-fundamental-trait-objects.stderr
new file mode 100644
index 00000000000..a35a95ef4bf
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-impl-in-fn.rs b/tests/ui/coherence/coherence-impl-in-fn.rs
new file mode 100644
index 00000000000..b9719731748
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs b/tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs
new file mode 100644
index 00000000000..50d9a480ad1
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr b/tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr
new file mode 100644
index 00000000000..c364c707ff9
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs b/tests/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs
new file mode 100644
index 00000000000..faac6d983f3
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr b/tests/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr
new file mode 100644
index 00000000000..b80429794f9
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-impl-trait-for-trait-object-safe.rs b/tests/ui/coherence/coherence-impl-trait-for-trait-object-safe.rs
new file mode 100644
index 00000000000..20ff875491f
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr b/tests/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr
new file mode 100644
index 00000000000..e9090c1b6bc
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-impl-trait-for-trait.rs b/tests/ui/coherence/coherence-impl-trait-for-trait.rs
new file mode 100644
index 00000000000..195a37f15a4
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-impl-trait-for-trait.stderr b/tests/ui/coherence/coherence-impl-trait-for-trait.stderr
new file mode 100644
index 00000000000..cf0b38c5bb8
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-impls-copy.rs b/tests/ui/coherence/coherence-impls-copy.rs
new file mode 100644
index 00000000000..4204fecc37e
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-impls-copy.stderr b/tests/ui/coherence/coherence-impls-copy.stderr
new file mode 100644
index 00000000000..d40ffc48a29
--- /dev/null
+++ b/tests/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 `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/tests/ui/coherence/coherence-impls-send.rs b/tests/ui/coherence/coherence-impls-send.rs
new file mode 100644
index 00000000000..b7b57c602b8
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-impls-send.stderr b/tests/ui/coherence/coherence-impls-send.stderr
new file mode 100644
index 00000000000..e1071846e14
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-impls-sized.rs b/tests/ui/coherence/coherence-impls-sized.rs
new file mode 100644
index 00000000000..231b96ad42e
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-impls-sized.stderr b/tests/ui/coherence/coherence-impls-sized.stderr
new file mode 100644
index 00000000000..17a7544521d
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs b/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs
new file mode 100644
index 00000000000..d74d3a2a523
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr b/tests/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr
new file mode 100644
index 00000000000..7bd50649d6d
--- /dev/null
+++ b/tests/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: 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
+   = note: `#[warn(incomplete_features)]` on by default
+
+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/tests/ui/coherence/coherence-inherited-subtyping.old.stderr b/tests/ui/coherence/coherence-inherited-subtyping.old.stderr
new file mode 100644
index 00000000000..4701bc0b139
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-inherited-subtyping.re.stderr b/tests/ui/coherence/coherence-inherited-subtyping.re.stderr
new file mode 100644
index 00000000000..4701bc0b139
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-inherited-subtyping.rs b/tests/ui/coherence/coherence-inherited-subtyping.rs
new file mode 100644
index 00000000000..8587eb77950
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-iterator-vec-any-elem.rs b/tests/ui/coherence/coherence-iterator-vec-any-elem.rs
new file mode 100644
index 00000000000..43a0a5c4277
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-iterator-vec.rs b/tests/ui/coherence/coherence-iterator-vec.rs
new file mode 100644
index 00000000000..386fe40ac3c
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-lone-type-parameter.rs b/tests/ui/coherence/coherence-lone-type-parameter.rs
new file mode 100644
index 00000000000..5368fef76d0
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-lone-type-parameter.stderr b/tests/ui/coherence/coherence-lone-type-parameter.stderr
new file mode 100644
index 00000000000..ef5b0883653
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-multidispatch-tuple.rs b/tests/ui/coherence/coherence-multidispatch-tuple.rs
new file mode 100644
index 00000000000..fa1d4bbb496
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-negative-impls-copy-bad.rs b/tests/ui/coherence/coherence-negative-impls-copy-bad.rs
new file mode 100644
index 00000000000..563f28e2291
--- /dev/null
+++ b/tests/ui/coherence/coherence-negative-impls-copy-bad.rs
@@ -0,0 +1,11 @@
+#![feature(negative_impls)]
+#![crate_type = "lib"]
+
+impl !Copy for str {}
+//~^ ERROR only traits defined in the current crate can be implemented
+
+impl !Copy for fn() {}
+//~^ ERROR only traits defined in the current crate can be implemented
+
+impl !Copy for () {}
+//~^ ERROR only traits defined in the current crate can be implemented
diff --git a/tests/ui/coherence/coherence-negative-impls-copy-bad.stderr b/tests/ui/coherence/coherence-negative-impls-copy-bad.stderr
new file mode 100644
index 00000000000..2295d6315d1
--- /dev/null
+++ b/tests/ui/coherence/coherence-negative-impls-copy-bad.stderr
@@ -0,0 +1,36 @@
+error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
+  --> $DIR/coherence-negative-impls-copy-bad.rs:4:1
+   |
+LL | impl !Copy for str {}
+   | ^^^^^^^^^^^^^^^---
+   | |              |
+   | |              `str` 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 arbitrary types
+  --> $DIR/coherence-negative-impls-copy-bad.rs:7:1
+   |
+LL | impl !Copy for fn() {}
+   | ^^^^^^^^^^^^^^^----
+   | |              |
+   | |              `fn()` 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 arbitrary types
+  --> $DIR/coherence-negative-impls-copy-bad.rs:10:1
+   |
+LL | impl !Copy for () {}
+   | ^^^^^^^^^^^^^^^--
+   | |              |
+   | |              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 3 previous errors
+
+For more information about this error, try `rustc --explain E0117`.
diff --git a/tests/ui/coherence/coherence-negative-impls-copy.rs b/tests/ui/coherence/coherence-negative-impls-copy.rs
new file mode 100644
index 00000000000..7b29aade413
--- /dev/null
+++ b/tests/ui/coherence/coherence-negative-impls-copy.rs
@@ -0,0 +1,29 @@
+// check-pass
+// regression test for issue #101836
+
+#![feature(negative_impls, extern_types)]
+#![crate_type = "lib"]
+
+struct NonCopy;
+struct NeverCopy(NonCopy);
+
+impl !Copy for NeverCopy {}
+
+
+struct WithDrop;
+impl Drop for WithDrop { fn drop(&mut self) {} }
+
+impl !Copy for WithDrop {}
+
+
+struct Type;
+trait Trait {}
+extern {
+    type ExternType;
+}
+
+impl !Copy for &mut Type {}
+
+impl !Copy for dyn Trait {}
+
+impl !Copy for ExternType {}
diff --git a/tests/ui/coherence/coherence-negative-impls-safe-rpass.rs b/tests/ui/coherence/coherence-negative-impls-safe-rpass.rs
new file mode 100644
index 00000000000..b87e162aca0
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-negative-impls-safe.rs b/tests/ui/coherence/coherence-negative-impls-safe.rs
new file mode 100644
index 00000000000..4821aa6b5ad
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-negative-impls-safe.stderr b/tests/ui/coherence/coherence-negative-impls-safe.stderr
new file mode 100644
index 00000000000..1bd37f39590
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-negative-inherent-where-bounds.rs b/tests/ui/coherence/coherence-negative-inherent-where-bounds.rs
new file mode 100644
index 00000000000..39ccaa6ac35
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-negative-inherent.rs b/tests/ui/coherence/coherence-negative-inherent.rs
new file mode 100644
index 00000000000..a9e1acc8044
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-negative-outlives-lifetimes.rs b/tests/ui/coherence/coherence-negative-outlives-lifetimes.rs
new file mode 100644
index 00000000000..3acf0d8d39a
--- /dev/null
+++ b/tests/ui/coherence/coherence-negative-outlives-lifetimes.rs
@@ -0,0 +1,17 @@
+// revisions: stock with_negative_coherence
+//[with_negative_coherence] check-pass
+
+#![feature(negative_impls)]
+#![cfg_attr(with_negative_coherence, feature(with_negative_coherence))]
+
+trait MyPredicate<'a> {}
+
+impl<'a, T> !MyPredicate<'a> for &'a T where T: 'a {}
+
+trait MyTrait<'a> {}
+
+impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {}
+impl<'a, T> MyTrait<'a> for &'a T {}
+//[stock]~^ ERROR: conflicting implementations of trait `MyTrait<'_>` for type `&_`
+
+fn main() {}
diff --git a/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr b/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr
new file mode 100644
index 00000000000..097cc4e0fe3
--- /dev/null
+++ b/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr
@@ -0,0 +1,11 @@
+error[E0119]: conflicting implementations of trait `MyTrait<'_>` for type `&_`
+  --> $DIR/coherence-negative-outlives-lifetimes.rs:14: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/tests/ui/coherence/coherence-no-direct-lifetime-dispatch.rs b/tests/ui/coherence/coherence-no-direct-lifetime-dispatch.rs
new file mode 100644
index 00000000000..d466dcac1c4
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-no-direct-lifetime-dispatch.stderr b/tests/ui/coherence/coherence-no-direct-lifetime-dispatch.stderr
new file mode 100644
index 00000000000..8a43ad7b7f0
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-orphan.rs b/tests/ui/coherence/coherence-orphan.rs
new file mode 100644
index 00000000000..3beac04c7e8
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-orphan.stderr b/tests/ui/coherence/coherence-orphan.stderr
new file mode 100644
index 00000000000..01f166a21f7
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-all-t-and-tuple.rs b/tests/ui/coherence/coherence-overlap-all-t-and-tuple.rs
new file mode 100644
index 00000000000..574a16a1911
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-all-t-and-tuple.stderr b/tests/ui/coherence/coherence-overlap-all-t-and-tuple.stderr
new file mode 100644
index 00000000000..6a0880334b6
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-double-negative.rs b/tests/ui/coherence/coherence-overlap-double-negative.rs
new file mode 100644
index 00000000000..1ea0ddc7430
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-downstream-inherent.rs b/tests/ui/coherence/coherence-overlap-downstream-inherent.rs
new file mode 100644
index 00000000000..5dea33e330b
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-downstream-inherent.stderr b/tests/ui/coherence/coherence-overlap-downstream-inherent.stderr
new file mode 100644
index 00000000000..bbce4b530b4
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-downstream.rs b/tests/ui/coherence/coherence-overlap-downstream.rs
new file mode 100644
index 00000000000..738ec0e3d45
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-downstream.stderr b/tests/ui/coherence/coherence-overlap-downstream.stderr
new file mode 100644
index 00000000000..7f373e595a3
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs b/tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs
new file mode 100644
index 00000000000..a272e620fca
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-issue-23516-inherent.stderr b/tests/ui/coherence/coherence-overlap-issue-23516-inherent.stderr
new file mode 100644
index 00000000000..3ad818cbc36
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-issue-23516.rs b/tests/ui/coherence/coherence-overlap-issue-23516.rs
new file mode 100644
index 00000000000..63e42e8f412
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-issue-23516.stderr b/tests/ui/coherence/coherence-overlap-issue-23516.stderr
new file mode 100644
index 00000000000..cd398426704
--- /dev/null
+++ b/tests/ui/coherence/coherence-overlap-issue-23516.stderr
@@ -0,0 +1,13 @@
+error[E0119]: conflicting implementations of trait `Sweet` for type `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 `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/tests/ui/coherence/coherence-overlap-messages.rs b/tests/ui/coherence/coherence-overlap-messages.rs
new file mode 100644
index 00000000000..1258a237114
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-messages.stderr b/tests/ui/coherence/coherence-overlap-messages.stderr
new file mode 100644
index 00000000000..5a97296eebd
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-negate-alias-strict.rs b/tests/ui/coherence/coherence-overlap-negate-alias-strict.rs
new file mode 100644
index 00000000000..48dffc921a3
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.rs b/tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.rs
new file mode 100644
index 00000000000..a067736f63a
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr b/tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr
new file mode 100644
index 00000000000..4b55001ecc0
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-negate-strict.rs b/tests/ui/coherence/coherence-overlap-negate-strict.rs
new file mode 100644
index 00000000000..1021d87ca1b
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-negate-use-feature-gate.rs b/tests/ui/coherence/coherence-overlap-negate-use-feature-gate.rs
new file mode 100644
index 00000000000..a0dd881d1aa
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-negative-trait.rs b/tests/ui/coherence/coherence-overlap-negative-trait.rs
new file mode 100644
index 00000000000..8059d23ffd2
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-negative-trait2.rs b/tests/ui/coherence/coherence-overlap-negative-trait2.rs
new file mode 100644
index 00000000000..cc8c463b822
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-super-negative.rs b/tests/ui/coherence/coherence-overlap-super-negative.rs
new file mode 100644
index 00000000000..d296a094a37
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-trait-alias.rs b/tests/ui/coherence/coherence-overlap-trait-alias.rs
new file mode 100644
index 00000000000..9d9c76af91d
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-trait-alias.stderr b/tests/ui/coherence/coherence-overlap-trait-alias.stderr
new file mode 100644
index 00000000000..e324c1e799f
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-upstream-inherent.rs b/tests/ui/coherence/coherence-overlap-upstream-inherent.rs
new file mode 100644
index 00000000000..082d753debb
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-upstream-inherent.stderr b/tests/ui/coherence/coherence-overlap-upstream-inherent.stderr
new file mode 100644
index 00000000000..f355c6e855c
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-upstream.rs b/tests/ui/coherence/coherence-overlap-upstream.rs
new file mode 100644
index 00000000000..8f1e6558b15
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-upstream.stderr b/tests/ui/coherence/coherence-overlap-upstream.stderr
new file mode 100644
index 00000000000..f6145c1883a
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlap-with-regions.rs b/tests/ui/coherence/coherence-overlap-with-regions.rs
new file mode 100644
index 00000000000..32f01f41801
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlapping-pairs.rs b/tests/ui/coherence/coherence-overlapping-pairs.rs
new file mode 100644
index 00000000000..d5d18217bd6
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-overlapping-pairs.stderr b/tests/ui/coherence/coherence-overlapping-pairs.stderr
new file mode 100644
index 00000000000..15c92dfeb07
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-pair-covered-uncovered-1.rs b/tests/ui/coherence/coherence-pair-covered-uncovered-1.rs
new file mode 100644
index 00000000000..15868ca8686
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-pair-covered-uncovered-1.stderr b/tests/ui/coherence/coherence-pair-covered-uncovered-1.stderr
new file mode 100644
index 00000000000..03d78712381
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-pair-covered-uncovered.rs b/tests/ui/coherence/coherence-pair-covered-uncovered.rs
new file mode 100644
index 00000000000..da970572fde
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-pair-covered-uncovered.stderr b/tests/ui/coherence/coherence-pair-covered-uncovered.stderr
new file mode 100644
index 00000000000..73dfe2f572a
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-projection-conflict-orphan.rs b/tests/ui/coherence/coherence-projection-conflict-orphan.rs
new file mode 100644
index 00000000000..637dd250638
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-projection-conflict-orphan.stderr b/tests/ui/coherence/coherence-projection-conflict-orphan.stderr
new file mode 100644
index 00000000000..b1ee0795b2e
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-projection-conflict-ty-param.rs b/tests/ui/coherence/coherence-projection-conflict-ty-param.rs
new file mode 100644
index 00000000000..3e4141fa8cb
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-projection-conflict-ty-param.stderr b/tests/ui/coherence/coherence-projection-conflict-ty-param.stderr
new file mode 100644
index 00000000000..94d242eaac4
--- /dev/null
+++ b/tests/ui/coherence/coherence-projection-conflict-ty-param.stderr
@@ -0,0 +1,12 @@
+error[E0119]: conflicting implementations of trait `Foo<_>` for type `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 `Option<_>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/coherence-projection-conflict.rs b/tests/ui/coherence/coherence-projection-conflict.rs
new file mode 100644
index 00000000000..daab2a2f8b4
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-projection-conflict.stderr b/tests/ui/coherence/coherence-projection-conflict.stderr
new file mode 100644
index 00000000000..7d2c584c370
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-projection-ok-orphan.rs b/tests/ui/coherence/coherence-projection-ok-orphan.rs
new file mode 100644
index 00000000000..42b4b1912e2
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-projection-ok.rs b/tests/ui/coherence/coherence-projection-ok.rs
new file mode 100644
index 00000000000..44fc02a5c20
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-rfc447-constrained.rs b/tests/ui/coherence/coherence-rfc447-constrained.rs
new file mode 100644
index 00000000000..9d1d8688325
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-subtyping.rs b/tests/ui/coherence/coherence-subtyping.rs
new file mode 100644
index 00000000000..b3ed728a81c
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-subtyping.stderr b/tests/ui/coherence/coherence-subtyping.stderr
new file mode 100644
index 00000000000..9d90019a50f
--- /dev/null
+++ b/tests/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`
+   |
+   = 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
+   = note: `#[warn(coherence_leak_check)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/coherence/coherence-tuple-conflict.rs b/tests/ui/coherence/coherence-tuple-conflict.rs
new file mode 100644
index 00000000000..8cc82972668
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-tuple-conflict.stderr b/tests/ui/coherence/coherence-tuple-conflict.stderr
new file mode 100644
index 00000000000..09ad5e5b224
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-unsafe-trait-object-impl.rs b/tests/ui/coherence/coherence-unsafe-trait-object-impl.rs
new file mode 100644
index 00000000000..9859a226efd
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-unsafe-trait-object-impl.stderr b/tests/ui/coherence/coherence-unsafe-trait-object-impl.stderr
new file mode 100644
index 00000000000..2e2dac288a1
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-vec-local-2.rs b/tests/ui/coherence/coherence-vec-local-2.rs
new file mode 100644
index 00000000000..47df06bac6c
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-vec-local-2.stderr b/tests/ui/coherence/coherence-vec-local-2.stderr
new file mode 100644
index 00000000000..95fdf172ec2
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-vec-local.rs b/tests/ui/coherence/coherence-vec-local.rs
new file mode 100644
index 00000000000..130cc39d0af
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-vec-local.stderr b/tests/ui/coherence/coherence-vec-local.stderr
new file mode 100644
index 00000000000..4835e771abd
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-wasm-bindgen.rs b/tests/ui/coherence/coherence-wasm-bindgen.rs
new file mode 100644
index 00000000000..ee09a72449b
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-wasm-bindgen.stderr b/tests/ui/coherence/coherence-wasm-bindgen.stderr
new file mode 100644
index 00000000000..89615f0fbc6
--- /dev/null
+++ b/tests/ui/coherence/coherence-wasm-bindgen.stderr
@@ -0,0 +1,21 @@
+error: conflicting implementations of trait `IntoWasmAbi` for type `&dyn 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 Fn(&_) -> _`
+   |
+   = 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
+note: the lint level is defined here
+  --> $DIR/coherence-wasm-bindgen.rs:10:9
+   |
+LL | #![deny(coherence_leak_check)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/coherence/coherence-where-clause.rs b/tests/ui/coherence/coherence-where-clause.rs
new file mode 100644
index 00000000000..5c40def86bb
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence-with-closure.rs b/tests/ui/coherence/coherence-with-closure.rs
new file mode 100644
index 00000000000..5b6a62b24d4
--- /dev/null
+++ b/tests/ui/coherence/coherence-with-closure.rs
@@ -0,0 +1,14 @@
+// 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> {}
+impl<T: Sync> Trait for Wrapper<T> {}
+//~^ ERROR conflicting implementations of trait `Trait` for type `Wrapper<OpaqueClosure>`
+
+fn main() {}
diff --git a/tests/ui/coherence/coherence-with-closure.stderr b/tests/ui/coherence/coherence-with-closure.stderr
new file mode 100644
index 00000000000..431108e14d7
--- /dev/null
+++ b/tests/ui/coherence/coherence-with-closure.stderr
@@ -0,0 +1,11 @@
+error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueClosure>`
+  --> $DIR/coherence-with-closure.rs:11:1
+   |
+LL | impl Trait for Wrapper<OpaqueClosure> {}
+   | ------------------------------------- first implementation here
+LL | impl<T: Sync> Trait for Wrapper<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueClosure>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/coherence-with-generator.rs b/tests/ui/coherence/coherence-with-generator.rs
new file mode 100644
index 00000000000..70665ba06f9
--- /dev/null
+++ b/tests/ui/coherence/coherence-with-generator.rs
@@ -0,0 +1,18 @@
+// 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> {}
+impl<T: Sync> Trait for Wrapper<T> {}
+//~^ ERROR conflicting implementations of trait `Trait` for type `Wrapper<OpaqueGenerator>`
+
+fn main() {}
diff --git a/tests/ui/coherence/coherence-with-generator.stderr b/tests/ui/coherence/coherence-with-generator.stderr
new file mode 100644
index 00000000000..6d3be2e16c6
--- /dev/null
+++ b/tests/ui/coherence/coherence-with-generator.stderr
@@ -0,0 +1,11 @@
+error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueGenerator>`
+  --> $DIR/coherence-with-generator.rs:15:1
+   |
+LL | impl Trait for Wrapper<OpaqueGenerator> {}
+   | --------------------------------------- first implementation here
+LL | impl<T: Sync> Trait for Wrapper<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueGenerator>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/coherence_copy_like.rs b/tests/ui/coherence/coherence_copy_like.rs
new file mode 100644
index 00000000000..92af341ccb5
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence_copy_like_err_fundamental_struct.rs b/tests/ui/coherence/coherence_copy_like_err_fundamental_struct.rs
new file mode 100644
index 00000000000..edee6cd7b6c
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence_copy_like_err_fundamental_struct_ref.rs b/tests/ui/coherence/coherence_copy_like_err_fundamental_struct_ref.rs
new file mode 100644
index 00000000000..599c804d213
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.rs b/tests/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.rs
new file mode 100644
index 00000000000..7d851b52884
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr b/tests/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr
new file mode 100644
index 00000000000..93486fa5f36
--- /dev/null
+++ b/tests/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr
@@ -0,0 +1,14 @@
+error[E0119]: conflicting implementations of trait `MyTrait` for type `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 `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/tests/ui/coherence/coherence_copy_like_err_struct.rs b/tests/ui/coherence/coherence_copy_like_err_struct.rs
new file mode 100644
index 00000000000..fe39370c901
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence_copy_like_err_struct.stderr b/tests/ui/coherence/coherence_copy_like_err_struct.stderr
new file mode 100644
index 00000000000..7432733b932
--- /dev/null
+++ b/tests/ui/coherence/coherence_copy_like_err_struct.stderr
@@ -0,0 +1,14 @@
+error[E0119]: conflicting implementations of trait `MyTrait` for type `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 `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/tests/ui/coherence/coherence_copy_like_err_tuple.rs b/tests/ui/coherence/coherence_copy_like_err_tuple.rs
new file mode 100644
index 00000000000..f63e205c9f8
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence_copy_like_err_tuple.stderr b/tests/ui/coherence/coherence_copy_like_err_tuple.stderr
new file mode 100644
index 00000000000..090497ec189
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence_inherent.rs b/tests/ui/coherence/coherence_inherent.rs
new file mode 100644
index 00000000000..f3ebf000386
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence_inherent.stderr b/tests/ui/coherence/coherence_inherent.stderr
new file mode 100644
index 00000000000..46b128c08fe
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence_inherent_cc.rs b/tests/ui/coherence/coherence_inherent_cc.rs
new file mode 100644
index 00000000000..759ada248f4
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence_inherent_cc.stderr b/tests/ui/coherence/coherence_inherent_cc.stderr
new file mode 100644
index 00000000000..af0ef3b6932
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence_local.rs b/tests/ui/coherence/coherence_local.rs
new file mode 100644
index 00000000000..ea724ada702
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence_local_err_struct.rs b/tests/ui/coherence/coherence_local_err_struct.rs
new file mode 100644
index 00000000000..a24038eb280
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence_local_err_struct.stderr b/tests/ui/coherence/coherence_local_err_struct.stderr
new file mode 100644
index 00000000000..afc6fc45d0e
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence_local_err_tuple.rs b/tests/ui/coherence/coherence_local_err_tuple.rs
new file mode 100644
index 00000000000..f4033862a3e
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence_local_err_tuple.stderr b/tests/ui/coherence/coherence_local_err_tuple.stderr
new file mode 100644
index 00000000000..a4953859f77
--- /dev/null
+++ b/tests/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/tests/ui/coherence/coherence_local_ref.rs b/tests/ui/coherence/coherence_local_ref.rs
new file mode 100644
index 00000000000..2e28839c8a4
--- /dev/null
+++ b/tests/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/tests/ui/coherence/conflicting-impl-with-err.rs b/tests/ui/coherence/conflicting-impl-with-err.rs
new file mode 100644
index 00000000000..3e0234b874d
--- /dev/null
+++ b/tests/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/tests/ui/coherence/conflicting-impl-with-err.stderr b/tests/ui/coherence/conflicting-impl-with-err.stderr
new file mode 100644
index 00000000000..3009b452dc7
--- /dev/null
+++ b/tests/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/tests/ui/coherence/const-generics-orphan-check-ok.rs b/tests/ui/coherence/const-generics-orphan-check-ok.rs
new file mode 100644
index 00000000000..217e8aed234
--- /dev/null
+++ b/tests/ui/coherence/const-generics-orphan-check-ok.rs
@@ -0,0 +1,28 @@
+// check-pass
+// aux-build:trait-with-const-param.rs
+extern crate trait_with_const_param;
+use trait_with_const_param::*;
+
+// Trivial case, const param after local type.
+struct Local1;
+impl<const N: usize, T> Trait<N, T> for Local1 {}
+
+// Concrete consts behave the same as foreign types,
+// so this also trivially works.
+impl Trait<3, Local1> for i32 {}
+
+// This case isn't as trivial as we would forbid type
+// parameters here, we do allow const parameters though.
+//
+// The reason that type parameters are forbidden for
+// `impl<T> Trait<T, LocalInA> for i32 {}` is that another
+// downstream crate can add `impl<T> Trait<LocalInB, T> for i32`.
+// As these two impls would overlap we forbid any impls which
+// have a type parameter in front of a local type.
+//
+// With const parameters this issue does not exist as there are no
+// constants local to another downstream crate.
+struct Local2;
+impl<const N: usize> Trait<N, Local2> for i32 {}
+
+fn main() {}
diff --git a/tests/ui/coherence/deep-bad-copy-reason.rs b/tests/ui/coherence/deep-bad-copy-reason.rs
new file mode 100644
index 00000000000..80bbe387ac7
--- /dev/null
+++ b/tests/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/tests/ui/coherence/deep-bad-copy-reason.stderr b/tests/ui/coherence/deep-bad-copy-reason.stderr
new file mode 100644
index 00000000000..168ee57263d
--- /dev/null
+++ b/tests/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:24
+   |
+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/tests/ui/coherence/impl-foreign-for-foreign.rs b/tests/ui/coherence/impl-foreign-for-foreign.rs
new file mode 100644
index 00000000000..4c0d46045e9
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl-foreign-for-foreign.stderr b/tests/ui/coherence/impl-foreign-for-foreign.stderr
new file mode 100644
index 00000000000..93f7a6fdc25
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl-foreign-for-foreign[foreign].rs b/tests/ui/coherence/impl-foreign-for-foreign[foreign].rs
new file mode 100644
index 00000000000..e79f66c0e13
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl-foreign-for-foreign[foreign].stderr b/tests/ui/coherence/impl-foreign-for-foreign[foreign].stderr
new file mode 100644
index 00000000000..e24537bce22
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl-foreign-for-foreign[local].rs b/tests/ui/coherence/impl-foreign-for-foreign[local].rs
new file mode 100644
index 00000000000..0b1413edf37
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl-foreign-for-fundamental[foreign].rs b/tests/ui/coherence/impl-foreign-for-fundamental[foreign].rs
new file mode 100644
index 00000000000..10bdf2db8bb
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl-foreign-for-fundamental[foreign].stderr b/tests/ui/coherence/impl-foreign-for-fundamental[foreign].stderr
new file mode 100644
index 00000000000..55ea4409e6f
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl-foreign-for-fundamental[local].rs b/tests/ui/coherence/impl-foreign-for-fundamental[local].rs
new file mode 100644
index 00000000000..c3fc0e6b8a7
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl-foreign-for-local.rs b/tests/ui/coherence/impl-foreign-for-local.rs
new file mode 100644
index 00000000000..04405bc46fb
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl-foreign-for-locally-defined-fundamental.rs b/tests/ui/coherence/impl-foreign-for-locally-defined-fundamental.rs
new file mode 100644
index 00000000000..bc1e18b657f
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl-foreign-for-locally-defined-fundamental[foreign].rs b/tests/ui/coherence/impl-foreign-for-locally-defined-fundamental[foreign].rs
new file mode 100644
index 00000000000..1e11789ef39
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl-foreign[foreign]-for-foreign.rs b/tests/ui/coherence/impl-foreign[foreign]-for-foreign.rs
new file mode 100644
index 00000000000..99a399ddc63
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl-foreign[foreign]-for-foreign.stderr b/tests/ui/coherence/impl-foreign[foreign]-for-foreign.stderr
new file mode 100644
index 00000000000..65b3aa394a8
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl-foreign[foreign]-for-local.rs b/tests/ui/coherence/impl-foreign[foreign]-for-local.rs
new file mode 100644
index 00000000000..bc6595bb340
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs b/tests/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs
new file mode 100644
index 00000000000..0476cdaffe7
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr b/tests/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr
new file mode 100644
index 00000000000..8e77c13e111
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs b/tests/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs
new file mode 100644
index 00000000000..7b83b048548
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign-for-foreign[t].rs b/tests/ui/coherence/impl[t]-foreign-for-foreign[t].rs
new file mode 100644
index 00000000000..5282de4b271
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign-for-foreign[t].stderr b/tests/ui/coherence/impl[t]-foreign-for-foreign[t].stderr
new file mode 100644
index 00000000000..92346c29198
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign-for-fundamental[t].rs b/tests/ui/coherence/impl[t]-foreign-for-fundamental[t].rs
new file mode 100644
index 00000000000..6f5605a2193
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr b/tests/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr
new file mode 100644
index 00000000000..249a5c44c79
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[foreign[t]_local]-for-foreign.rs b/tests/ui/coherence/impl[t]-foreign[foreign[t]_local]-for-foreign.rs
new file mode 100644
index 00000000000..99f3ce44760
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs b/tests/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs
new file mode 100644
index 00000000000..81044cd0529
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr b/tests/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr
new file mode 100644
index 00000000000..95a20cc5b0f
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[foreign]-for-t.rs b/tests/ui/coherence/impl[t]-foreign[foreign]-for-t.rs
new file mode 100644
index 00000000000..680ba9f2226
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr b/tests/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr
new file mode 100644
index 00000000000..aed184767a0
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs b/tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs
new file mode 100644
index 00000000000..fc7649085c3
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr b/tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr
new file mode 100644
index 00000000000..73b1e2c6ed2
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs b/tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs
new file mode 100644
index 00000000000..703f25dd60a
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr b/tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr
new file mode 100644
index 00000000000..5f89a7aa469
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs b/tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs
new file mode 100644
index 00000000000..ec21fdd4e04
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs b/tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs
new file mode 100644
index 00000000000..5bdab87bf4e
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr b/tests/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr
new file mode 100644
index 00000000000..45559d8b62d
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs b/tests/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs
new file mode 100644
index 00000000000..c9e3594cd34
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.stderr b/tests/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.stderr
new file mode 100644
index 00000000000..f94f04c8df5
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs b/tests/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs
new file mode 100644
index 00000000000..62e69357e3a
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[local]-for-foreign.rs b/tests/ui/coherence/impl[t]-foreign[local]-for-foreign.rs
new file mode 100644
index 00000000000..1fec19bbab9
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs b/tests/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs
new file mode 100644
index 00000000000..c8ed28be6f0
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs b/tests/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs
new file mode 100644
index 00000000000..f9b88c6459b
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs b/tests/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs
new file mode 100644
index 00000000000..7709bd9c89b
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr b/tests/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr
new file mode 100644
index 00000000000..e68f2fe5856
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[local]-for-local.rs b/tests/ui/coherence/impl[t]-foreign[local]-for-local.rs
new file mode 100644
index 00000000000..9c14eea1be2
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[local]-for-t.rs b/tests/ui/coherence/impl[t]-foreign[local]-for-t.rs
new file mode 100644
index 00000000000..eed3a4b5c23
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[local]-for-t.stderr b/tests/ui/coherence/impl[t]-foreign[local]-for-t.stderr
new file mode 100644
index 00000000000..d97e85dcb3c
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[local_fundamental[t]]-for-foreign.rs b/tests/ui/coherence/impl[t]-foreign[local_fundamental[t]]-for-foreign.rs
new file mode 100644
index 00000000000..63c342b76f1
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[t]-for-foreign.rs b/tests/ui/coherence/impl[t]-foreign[t]-for-foreign.rs
new file mode 100644
index 00000000000..9bb37c2baab
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr b/tests/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr
new file mode 100644
index 00000000000..44e3b7eedb4
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs b/tests/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs
new file mode 100644
index 00000000000..79b5aa3fc62
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr b/tests/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr
new file mode 100644
index 00000000000..80fb5dbec86
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[t]-for-local.rs b/tests/ui/coherence/impl[t]-foreign[t]-for-local.rs
new file mode 100644
index 00000000000..bc59721c088
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[t]-for-t.rs b/tests/ui/coherence/impl[t]-foreign[t]-for-t.rs
new file mode 100644
index 00000000000..bcd6b269a38
--- /dev/null
+++ b/tests/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/tests/ui/coherence/impl[t]-foreign[t]-for-t.stderr b/tests/ui/coherence/impl[t]-foreign[t]-for-t.stderr
new file mode 100644
index 00000000000..ff72969dc52
--- /dev/null
+++ b/tests/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/tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs b/tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs
new file mode 100644
index 00000000000..5b11c78ab26
--- /dev/null
+++ b/tests/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/tests/ui/coherence/inter-crate-ambiguity-causes-notes.stderr b/tests/ui/coherence/inter-crate-ambiguity-causes-notes.stderr
new file mode 100644
index 00000000000..4ddd712b27c
--- /dev/null
+++ b/tests/ui/coherence/inter-crate-ambiguity-causes-notes.stderr
@@ -0,0 +1,14 @@
+error[E0119]: conflicting implementations of trait `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/tests/ui/coherence/issue-85026.rs b/tests/ui/coherence/issue-85026.rs
new file mode 100644
index 00000000000..8b116545aa6
--- /dev/null
+++ b/tests/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/tests/ui/coherence/issue-85026.stderr b/tests/ui/coherence/issue-85026.stderr
new file mode 100644
index 00000000000..a5da19bbfaa
--- /dev/null
+++ b/tests/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/tests/ui/coherence/issue-99663-2.rs b/tests/ui/coherence/issue-99663-2.rs
new file mode 100644
index 00000000000..10a0a568849
--- /dev/null
+++ b/tests/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/tests/ui/coherence/issue-99663.rs b/tests/ui/coherence/issue-99663.rs
new file mode 100644
index 00000000000..a2d4d398ce1
--- /dev/null
+++ b/tests/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/tests/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs b/tests/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs
new file mode 100644
index 00000000000..d18e3f453c9
--- /dev/null
+++ b/tests/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/tests/ui/coherence/re-rebalance-coherence.rs b/tests/ui/coherence/re-rebalance-coherence.rs
new file mode 100644
index 00000000000..38d096b08e1
--- /dev/null
+++ b/tests/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() {}
diff --git a/tests/ui/coherence/strict-coherence-needs-negative-coherence.rs b/tests/ui/coherence/strict-coherence-needs-negative-coherence.rs
new file mode 100644
index 00000000000..221683dd56f
--- /dev/null
+++ b/tests/ui/coherence/strict-coherence-needs-negative-coherence.rs
@@ -0,0 +1,7 @@
+#![feature(rustc_attrs)]
+
+#[rustc_strict_coherence]
+trait Foo {}
+//~^ ERROR to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled
+
+fn main() {}
diff --git a/tests/ui/coherence/strict-coherence-needs-negative-coherence.stderr b/tests/ui/coherence/strict-coherence-needs-negative-coherence.stderr
new file mode 100644
index 00000000000..b5472928778
--- /dev/null
+++ b/tests/ui/coherence/strict-coherence-needs-negative-coherence.stderr
@@ -0,0 +1,10 @@
+error: to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled
+  --> $DIR/strict-coherence-needs-negative-coherence.rs:4:1
+   |
+LL | #[rustc_strict_coherence]
+   | ------------------------- due to this attribute
+LL | trait Foo {}
+   | ^^^^^^^^^
+
+error: aborting due to previous error
+