about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_middle/src/query/mod.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs2
-rw-r--r--compiler/rustc_typeck/src/coherence/mod.rs19
-rw-r--r--compiler/rustc_typeck/src/coherence/orphan.rs176
-rw-r--r--compiler/rustc_typeck/src/coherence/unsafety.rs35
-rw-r--r--compiler/rustc_typeck/src/lib.rs10
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr24
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr24
-rw-r--r--src/test/ui/coherence/coherence-impls-copy.stderr42
-rw-r--r--src/test/ui/coherence/coherence-impls-send.stderr22
-rw-r--r--src/test/ui/coherence/coherence-impls-sized.stderr66
-rw-r--r--src/test/ui/coherence/coherence-with-closure.stderr18
-rw-r--r--src/test/ui/coherence/coherence-with-generator.stderr18
-rw-r--r--src/test/ui/impl-trait/auto-trait.stderr18
-rw-r--r--src/test/ui/impl-trait/negative-reasoning.stderr22
-rw-r--r--src/test/ui/traits/alias/issue-83613.stderr16
-rw-r--r--src/test/ui/traits/issue-78372.rs1
-rw-r--r--src/test/ui/traits/issue-78372.stderr15
18 files changed, 251 insertions, 284 deletions
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index e0b4eced075..e1f7408cbf8 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -906,9 +906,10 @@ rustc_queries! {
 
     /// Checks whether all impls in the crate pass the overlap check, returning
     /// which impls fail it. If all impls are correct, the returned slice is empty.
-    query orphan_check_crate(_: ()) -> &'tcx [LocalDefId] {
-        desc {
-            "checking whether the immpl in the this crate follow the orphan rules",
+    query orphan_check_impl(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
+        desc { |tcx|
+            "checking whether impl `{}` follows the orphan rules",
+            tcx.def_path_str(key.to_def_id()),
         }
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 95f1e224a4c..a1861529b59 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -452,7 +452,7 @@ fn report_conflicting_impls(
     match used_to_be_allowed {
         None => {
             let reported = if overlap.with_impl.is_local()
-                || !tcx.orphan_check_crate(()).contains(&impl_def_id)
+                || tcx.orphan_check_impl(impl_def_id).is_ok()
             {
                 let err = struct_span_err!(tcx.sess, impl_span, E0119, "");
                 Some(decorate(
diff --git a/compiler/rustc_typeck/src/coherence/mod.rs b/compiler/rustc_typeck/src/coherence/mod.rs
index 3903448a007..447ec87f302 100644
--- a/compiler/rustc_typeck/src/coherence/mod.rs
+++ b/compiler/rustc_typeck/src/coherence/mod.rs
@@ -146,7 +146,7 @@ pub fn provide(providers: &mut Providers) {
     use self::builtin::coerce_unsized_info;
     use self::inherent_impls::{crate_incoherent_impls, crate_inherent_impls, inherent_impls};
     use self::inherent_impls_overlap::crate_inherent_impls_overlap_check;
-    use self::orphan::orphan_check_crate;
+    use self::orphan::orphan_check_impl;
 
     *providers = Providers {
         coherent_trait,
@@ -155,7 +155,7 @@ pub fn provide(providers: &mut Providers) {
         inherent_impls,
         crate_inherent_impls_overlap_check,
         coerce_unsized_info,
-        orphan_check_crate,
+        orphan_check_impl,
         ..*providers
     };
 }
@@ -171,21 +171,12 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) {
 
         check_impl(tcx, impl_def_id, trait_ref);
         check_object_overlap(tcx, impl_def_id, trait_ref);
-    }
-    builtin::check_trait(tcx, def_id);
-}
 
-pub fn check_coherence(tcx: TyCtxt<'_>) {
-    tcx.sess.time("unsafety_checking", || unsafety::check(tcx));
-    tcx.ensure().orphan_check_crate(());
-
-    for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
-        tcx.ensure().coherent_trait(trait_def_id);
+        tcx.sess.time("unsafety_checking", || unsafety::check_item(tcx, impl_def_id));
+        tcx.sess.time("orphan_checking", || tcx.ensure().orphan_check_impl(impl_def_id));
     }
 
-    // these queries are executed for side-effects (error reporting):
-    tcx.ensure().crate_inherent_impls(());
-    tcx.ensure().crate_inherent_impls_overlap_check(());
+    builtin::check_trait(tcx, def_id);
 }
 
 /// Checks whether an impl overlaps with the automatic `impl Trait for dyn Trait`.
diff --git a/compiler/rustc_typeck/src/coherence/orphan.rs b/compiler/rustc_typeck/src/coherence/orphan.rs
index 9ddfc8d5cc8..90121313b0c 100644
--- a/compiler/rustc_typeck/src/coherence/orphan.rs
+++ b/compiler/rustc_typeck/src/coherence/orphan.rs
@@ -18,26 +18,29 @@ use rustc_span::Span;
 use rustc_trait_selection::traits;
 use std::ops::ControlFlow;
 
-pub(super) fn orphan_check_crate(tcx: TyCtxt<'_>, (): ()) -> &[LocalDefId] {
-    let mut errors = Vec::new();
-    for (&trait_def_id, impls_of_trait) in tcx.all_local_trait_impls(()) {
-        for &impl_of_trait in impls_of_trait {
-            match orphan_check_impl(tcx, impl_of_trait) {
-                Ok(()) => {}
-                Err(_) => errors.push(impl_of_trait),
-            }
-        }
+#[instrument(skip(tcx), level = "debug")]
+pub(crate) fn orphan_check_impl(
+    tcx: TyCtxt<'_>,
+    impl_def_id: LocalDefId,
+) -> Result<(), ErrorGuaranteed> {
+    let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
+    if trait_ref.references_error() {
+        return Ok(());
+    }
 
-        if tcx.trait_is_auto(trait_def_id) {
-            lint_auto_trait_impls(tcx, trait_def_id, impls_of_trait);
-        }
+    let ret = do_orphan_check_impl(tcx, trait_ref, impl_def_id);
+    if tcx.trait_is_auto(trait_ref.def_id) {
+        lint_auto_trait_impls(tcx, trait_ref, impl_def_id);
     }
-    tcx.arena.alloc_slice(&errors)
+
+    ret
 }
 
-#[instrument(skip(tcx), level = "debug")]
-fn orphan_check_impl(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
-    let trait_ref = tcx.impl_trait_ref(def_id).unwrap();
+fn do_orphan_check_impl<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    trait_ref: ty::TraitRef<'tcx>,
+    def_id: LocalDefId,
+) -> Result<(), ErrorGuaranteed> {
     let trait_def_id = trait_ref.def_id;
 
     let item = tcx.hir().item(hir::ItemId { def_id });
@@ -329,89 +332,82 @@ fn emit_orphan_check_error<'tcx>(
 
 /// Lint impls of auto traits if they are likely to have
 /// unsound or surprising effects on auto impls.
-fn lint_auto_trait_impls(tcx: TyCtxt<'_>, trait_def_id: DefId, impls: &[LocalDefId]) {
-    let mut non_covering_impls = Vec::new();
-    for &impl_def_id in impls {
-        let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
-        if trait_ref.references_error() {
-            return;
-        }
+fn lint_auto_trait_impls<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    trait_ref: ty::TraitRef<'tcx>,
+    impl_def_id: LocalDefId,
+) {
+    if tcx.impl_polarity(impl_def_id) != ImplPolarity::Positive {
+        return;
+    }
 
-        if tcx.impl_polarity(impl_def_id) != ImplPolarity::Positive {
+    assert_eq!(trait_ref.substs.len(), 1);
+    let self_ty = trait_ref.self_ty();
+    let (self_type_did, substs) = match self_ty.kind() {
+        ty::Adt(def, substs) => (def.did(), substs),
+        _ => {
+            // FIXME: should also lint for stuff like `&i32` but
+            // considering that auto traits are unstable, that
+            // isn't too important for now as this only affects
+            // crates using `nightly`, and std.
             return;
         }
+    };
 
-        assert_eq!(trait_ref.substs.len(), 1);
-        let self_ty = trait_ref.self_ty();
-        let (self_type_did, substs) = match self_ty.kind() {
-            ty::Adt(def, substs) => (def.did(), substs),
-            _ => {
-                // FIXME: should also lint for stuff like `&i32` but
-                // considering that auto traits are unstable, that
-                // isn't too important for now as this only affects
-                // crates using `nightly`, and std.
-                continue;
-            }
-        };
+    // Impls which completely cover a given root type are fine as they
+    // disable auto impls entirely. So only lint if the substs
+    // are not a permutation of the identity substs.
+    let Err(arg) = tcx.uses_unique_generic_params(substs, IgnoreRegions::Yes) else {
+        // ok
+        return;
+    };
 
-        // Impls which completely cover a given root type are fine as they
-        // disable auto impls entirely. So only lint if the substs
-        // are not a permutation of the identity substs.
-        match tcx.uses_unique_generic_params(substs, IgnoreRegions::Yes) {
-            Ok(()) => {} // ok
-            Err(arg) => {
-                // Ideally:
-                //
-                // - compute the requirements for the auto impl candidate
-                // - check whether these are implied by the non covering impls
-                // - if not, emit the lint
-                //
-                // What we do here is a bit simpler:
-                //
-                // - badly check if an auto impl candidate definitely does not apply
-                //   for the given simplified type
-                // - if so, do not lint
-                if fast_reject_auto_impl(tcx, trait_def_id, self_ty) {
-                    // ok
-                } else {
-                    non_covering_impls.push((impl_def_id, self_type_did, arg));
-                }
-            }
-        }
+    // Ideally:
+    //
+    // - compute the requirements for the auto impl candidate
+    // - check whether these are implied by the non covering impls
+    // - if not, emit the lint
+    //
+    // What we do here is a bit simpler:
+    //
+    // - badly check if an auto impl candidate definitely does not apply
+    //   for the given simplified type
+    // - if so, do not lint
+    if fast_reject_auto_impl(tcx, trait_ref.def_id, self_ty) {
+        // ok
+        return;
     }
 
-    for &(impl_def_id, self_type_did, arg) in &non_covering_impls {
-        tcx.struct_span_lint_hir(
-            lint::builtin::SUSPICIOUS_AUTO_TRAIT_IMPLS,
-            tcx.hir().local_def_id_to_hir_id(impl_def_id),
-            tcx.def_span(impl_def_id),
-            |err| {
-                let item_span = tcx.def_span(self_type_did);
-                let self_descr = tcx.def_kind(self_type_did).descr(self_type_did);
-                let mut err = err.build(&format!(
-                    "cross-crate traits with a default impl, like `{}`, \
+    tcx.struct_span_lint_hir(
+        lint::builtin::SUSPICIOUS_AUTO_TRAIT_IMPLS,
+        tcx.hir().local_def_id_to_hir_id(impl_def_id),
+        tcx.def_span(impl_def_id),
+        |err| {
+            let item_span = tcx.def_span(self_type_did);
+            let self_descr = tcx.def_kind(self_type_did).descr(self_type_did);
+            let mut err = err.build(&format!(
+                "cross-crate traits with a default impl, like `{}`, \
                          should not be specialized",
-                    tcx.def_path_str(trait_def_id),
-                ));
-                match arg {
-                    ty::util::NotUniqueParam::DuplicateParam(arg) => {
-                        err.note(&format!("`{}` is mentioned multiple times", arg));
-                    }
-                    ty::util::NotUniqueParam::NotParam(arg) => {
-                        err.note(&format!("`{}` is not a generic parameter", arg));
-                    }
+                tcx.def_path_str(trait_ref.def_id),
+            ));
+            match arg {
+                ty::util::NotUniqueParam::DuplicateParam(arg) => {
+                    err.note(&format!("`{}` is mentioned multiple times", arg));
                 }
-                err.span_note(
-                    item_span,
-                    &format!(
-                        "try using the same sequence of generic parameters as the {} definition",
-                        self_descr,
-                    ),
-                );
-                err.emit();
-            },
-        );
-    }
+                ty::util::NotUniqueParam::NotParam(arg) => {
+                    err.note(&format!("`{}` is not a generic parameter", arg));
+                }
+            }
+            err.span_note(
+                item_span,
+                &format!(
+                    "try using the same sequence of generic parameters as the {} definition",
+                    self_descr,
+                ),
+            );
+            err.emit();
+        },
+    );
 }
 
 fn fast_reject_auto_impl<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, self_ty: Ty<'tcx>) -> bool {
diff --git a/compiler/rustc_typeck/src/coherence/unsafety.rs b/compiler/rustc_typeck/src/coherence/unsafety.rs
index 3cfc96ccbfd..e45fb5fe41c 100644
--- a/compiler/rustc_typeck/src/coherence/unsafety.rs
+++ b/compiler/rustc_typeck/src/coherence/unsafety.rs
@@ -6,37 +6,18 @@ use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::Unsafety;
 use rustc_middle::ty::TyCtxt;
+use rustc_span::def_id::LocalDefId;
 
-pub fn check(tcx: TyCtxt<'_>) {
-    for id in tcx.hir().items() {
-        if matches!(tcx.def_kind(id.def_id), DefKind::Impl) {
-            let item = tcx.hir().item(id);
-            if let hir::ItemKind::Impl(ref impl_) = item.kind {
-                check_unsafety_coherence(
-                    tcx,
-                    item,
-                    Some(&impl_.generics),
-                    impl_.unsafety,
-                    impl_.polarity,
-                );
-            }
-        }
-    }
-}
+pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
+    debug_assert!(matches!(tcx.def_kind(def_id), DefKind::Impl));
+    let item = tcx.hir().expect_item(def_id);
+    let hir::ItemKind::Impl(ref impl_) = item.kind else { bug!() };
 
-fn check_unsafety_coherence<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    item: &hir::Item<'_>,
-    impl_generics: Option<&hir::Generics<'_>>,
-    unsafety: hir::Unsafety,
-    polarity: hir::ImplPolarity,
-) {
     if let Some(trait_ref) = tcx.impl_trait_ref(item.def_id) {
         let trait_def = tcx.trait_def(trait_ref.def_id);
-        let unsafe_attr = impl_generics.and_then(|generics| {
-            generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle")
-        });
-        match (trait_def.unsafety, unsafe_attr, unsafety, polarity) {
+        let unsafe_attr =
+            impl_.generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle");
+        match (trait_def.unsafety, unsafe_attr, impl_.unsafety, impl_.polarity) {
             (Unsafety::Normal, None, Unsafety::Unsafe, hir::ImplPolarity::Positive) => {
                 struct_span_err!(
                     tcx.sess,
diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs
index d613edf0ab0..a7a008bc2eb 100644
--- a/compiler/rustc_typeck/src/lib.rs
+++ b/compiler/rustc_typeck/src/lib.rs
@@ -513,7 +513,15 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
     })?;
 
     tcx.sess.track_errors(|| {
-        tcx.sess.time("coherence_checking", || coherence::check_coherence(tcx));
+        tcx.sess.time("coherence_checking", || {
+            for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
+                tcx.ensure().coherent_trait(trait_def_id);
+            }
+
+            // these queries are executed for side-effects (error reporting):
+            tcx.ensure().crate_inherent_impls(());
+            tcx.ensure().crate_inherent_impls_overlap_check(());
+        });
     })?;
 
     if tcx.features().rustc_attrs {
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr
index 91289148079..c364c707ff9 100644
--- a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr
+++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr
@@ -1,3 +1,15 @@
+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
    |
@@ -21,18 +33,6 @@ error[E0321]: cross-crate traits with a default impl, like `Send`, can only be i
 LL | impl !Send for dyn Object + Marker2 {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
 
-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: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0117, E0321, E0371.
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr
index 056198374a4..b80429794f9 100644
--- a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr
+++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr
@@ -1,3 +1,15 @@
+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
    |
@@ -21,18 +33,6 @@ error[E0321]: cross-crate traits with a default impl, like `Send`, can only be i
 LL | unsafe impl Send for dyn Object + Marker2 {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
 
-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: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0117, E0321, E0371.
diff --git a/src/test/ui/coherence/coherence-impls-copy.stderr b/src/test/ui/coherence/coherence-impls-copy.stderr
index b3ca354c633..86356af2564 100644
--- a/src/test/ui/coherence/coherence-impls-copy.stderr
+++ b/src/test/ui/coherence/coherence-impls-copy.stderr
@@ -9,49 +9,49 @@ LL | impl Copy for i32 {}
    |
    = note: define and implement a trait or new type instead
 
+error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&NotSync`
+  --> $DIR/coherence-impls-copy.rs:28:1
+   |
+LL | impl Copy for &'static NotSync {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `core`:
+           - impl<T> Copy for &T
+             where T: ?Sized;
+
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-copy.rs:25:1
+  --> $DIR/coherence-impls-copy.rs:33:1
    |
-LL | impl Copy for (MyType, MyType) {}
-   | ^^^^^^^^^^^^^^----------------
+LL | impl Copy for &'static [NotSync] {}
+   | ^^^^^^^^^^^^^^------------------
    | |             |
-   | |             this is not defined in the current crate because tuples are always foreign
+   | |             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:30:1
+  --> $DIR/coherence-impls-copy.rs:25:1
    |
-LL | impl Copy for [MyType] {}
-   | ^^^^^^^^^^^^^^--------
+LL | impl Copy for (MyType, MyType) {}
+   | ^^^^^^^^^^^^^^----------------
    | |             |
-   | |             this is not defined in the current crate because slices are always foreign
+   | |             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:33:1
+  --> $DIR/coherence-impls-copy.rs:30:1
    |
-LL | impl Copy for &'static [NotSync] {}
-   | ^^^^^^^^^^^^^^------------------
+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[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&NotSync`
-  --> $DIR/coherence-impls-copy.rs:28:1
-   |
-LL | impl Copy for &'static NotSync {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: conflicting implementation in crate `core`:
-           - impl<T> Copy for &T
-             where T: ?Sized;
-
 error[E0206]: the trait `Copy` may not be implemented for this type
   --> $DIR/coherence-impls-copy.rs:21:15
    |
diff --git a/src/test/ui/coherence/coherence-impls-send.stderr b/src/test/ui/coherence/coherence-impls-send.stderr
index dd1fd1b0dce..e1071846e14 100644
--- a/src/test/ui/coherence/coherence-impls-send.stderr
+++ b/src/test/ui/coherence/coherence-impls-send.stderr
@@ -1,4 +1,15 @@
 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) {}
@@ -26,17 +37,6 @@ LL | unsafe impl Send for [MyType] {}
    |
    = 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: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: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0117, E0321.
diff --git a/src/test/ui/coherence/coherence-impls-sized.stderr b/src/test/ui/coherence/coherence-impls-sized.stderr
index e1e4acd4cd8..17a7544521d 100644
--- a/src/test/ui/coherence/coherence-impls-sized.stderr
+++ b/src/test/ui/coherence/coherence-impls-sized.stderr
@@ -1,36 +1,3 @@
-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[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[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[E0322]: explicit impls for the `Sized` trait are not permitted
   --> $DIR/coherence-impls-sized.rs:14:1
    |
@@ -49,6 +16,17 @@ error[E0322]: explicit impls for the `Sized` trait are not permitted
 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
    |
@@ -61,12 +39,34 @@ error[E0322]: explicit impls for the `Sized` trait are not permitted
 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.
diff --git a/src/test/ui/coherence/coherence-with-closure.stderr b/src/test/ui/coherence/coherence-with-closure.stderr
index 20b986cee69..d2ca63fa146 100644
--- a/src/test/ui/coherence/coherence-with-closure.stderr
+++ b/src/test/ui/coherence/coherence-with-closure.stderr
@@ -1,3 +1,12 @@
+error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueClosure>`
+  --> $DIR/coherence-with-closure.rs:12:1
+   |
+LL | impl Trait for Wrapper<OpaqueClosure> {}
+   | ------------------------------------- first implementation here
+LL |
+LL | impl<T: Sync> Trait for Wrapper<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueClosure>`
+
 error: cannot implement trait on type alias impl trait
   --> $DIR/coherence-with-closure.rs:10:24
    |
@@ -10,15 +19,6 @@ note: type alias impl trait defined here
 LL | type OpaqueClosure = impl Sized;
    |                      ^^^^^^^^^^
 
-error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueClosure>`
-  --> $DIR/coherence-with-closure.rs:12:1
-   |
-LL | impl Trait for Wrapper<OpaqueClosure> {}
-   | ------------------------------------- first implementation here
-LL |
-LL | impl<T: Sync> Trait for Wrapper<T> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueClosure>`
-
 error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-with-generator.stderr b/src/test/ui/coherence/coherence-with-generator.stderr
index 249ad3cb9ec..804bc1c3a6d 100644
--- a/src/test/ui/coherence/coherence-with-generator.stderr
+++ b/src/test/ui/coherence/coherence-with-generator.stderr
@@ -1,3 +1,12 @@
+error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueGenerator>`
+  --> $DIR/coherence-with-generator.rs:16:1
+   |
+LL | impl Trait for Wrapper<OpaqueGenerator> {}
+   | --------------------------------------- first implementation here
+LL |
+LL | impl<T: Sync> Trait for Wrapper<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueGenerator>`
+
 error: cannot implement trait on type alias impl trait
   --> $DIR/coherence-with-generator.rs:14:24
    |
@@ -10,15 +19,6 @@ note: type alias impl trait defined here
 LL | type OpaqueGenerator = impl Sized;
    |                        ^^^^^^^^^^
 
-error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueGenerator>`
-  --> $DIR/coherence-with-generator.rs:16:1
-   |
-LL | impl Trait for Wrapper<OpaqueGenerator> {}
-   | --------------------------------------- first implementation here
-LL |
-LL | impl<T: Sync> Trait for Wrapper<T> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueGenerator>`
-
 error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/impl-trait/auto-trait.stderr b/src/test/ui/impl-trait/auto-trait.stderr
index 3b360f492b7..5e10272b0db 100644
--- a/src/test/ui/impl-trait/auto-trait.stderr
+++ b/src/test/ui/impl-trait/auto-trait.stderr
@@ -1,3 +1,12 @@
+error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
+  --> $DIR/auto-trait.rs:21:1
+   |
+LL | impl<T: Send> AnotherTrait for T {}
+   | -------------------------------- first implementation here
+...
+LL | impl AnotherTrait for D<OpaqueType> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
+
 error: cannot implement trait on type alias impl trait
   --> $DIR/auto-trait.rs:21:25
    |
@@ -10,15 +19,6 @@ note: type alias impl trait defined here
 LL | type OpaqueType = impl OpaqueTrait;
    |                   ^^^^^^^^^^^^^^^^
 
-error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
-  --> $DIR/auto-trait.rs:21:1
-   |
-LL | impl<T: Send> AnotherTrait for T {}
-   | -------------------------------- first implementation here
-...
-LL | impl AnotherTrait for D<OpaqueType> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
-
 error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/impl-trait/negative-reasoning.stderr b/src/test/ui/impl-trait/negative-reasoning.stderr
index 98f9fbd8fef..479b451855d 100644
--- a/src/test/ui/impl-trait/negative-reasoning.stderr
+++ b/src/test/ui/impl-trait/negative-reasoning.stderr
@@ -1,3 +1,14 @@
+error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
+  --> $DIR/negative-reasoning.rs:19:1
+   |
+LL | impl<T: std::fmt::Debug> AnotherTrait for T {}
+   | ------------------------------------------- first implementation here
+...
+LL | impl AnotherTrait for D<OpaqueType> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
+   |
+   = note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `OpaqueType` in future versions
+
 error: cannot implement trait on type alias impl trait
   --> $DIR/negative-reasoning.rs:19:25
    |
@@ -10,17 +21,6 @@ note: type alias impl trait defined here
 LL | type OpaqueType = impl OpaqueTrait;
    |                   ^^^^^^^^^^^^^^^^
 
-error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
-  --> $DIR/negative-reasoning.rs:19:1
-   |
-LL | impl<T: std::fmt::Debug> AnotherTrait for T {}
-   | ------------------------------------------- first implementation here
-...
-LL | impl AnotherTrait for D<OpaqueType> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
-   |
-   = note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `OpaqueType` in future versions
-
 error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/traits/alias/issue-83613.stderr b/src/test/ui/traits/alias/issue-83613.stderr
index bbc240b6aec..b9d93160192 100644
--- a/src/test/ui/traits/alias/issue-83613.stderr
+++ b/src/test/ui/traits/alias/issue-83613.stderr
@@ -1,3 +1,11 @@
+error[E0119]: conflicting implementations of trait `AnotherTrait` for type `OpaqueType`
+  --> $DIR/issue-83613.rs:10:1
+   |
+LL | impl<T: Send> AnotherTrait for T {}
+   | -------------------------------- first implementation here
+LL | impl AnotherTrait for OpaqueType {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `OpaqueType`
+
 error: cannot implement trait on type alias impl trait
   --> $DIR/issue-83613.rs:10:23
    |
@@ -10,14 +18,6 @@ note: type alias impl trait defined here
 LL | type OpaqueType = impl OpaqueTrait;
    |                   ^^^^^^^^^^^^^^^^
 
-error[E0119]: conflicting implementations of trait `AnotherTrait` for type `OpaqueType`
-  --> $DIR/issue-83613.rs:10:1
-   |
-LL | impl<T: Send> AnotherTrait for T {}
-   | -------------------------------- first implementation here
-LL | impl AnotherTrait for OpaqueType {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `OpaqueType`
-
 error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/traits/issue-78372.rs b/src/test/ui/traits/issue-78372.rs
index 77a8c92c81c..92f9f4b467a 100644
--- a/src/test/ui/traits/issue-78372.rs
+++ b/src/test/ui/traits/issue-78372.rs
@@ -4,7 +4,6 @@ impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {} //~ ERROR cannot find type `U`
 //~^ ERROR cannot find type `MISC` in this scope
 //~| ERROR use of unstable library feature 'dispatch_from_dyn'
 //~| ERROR the trait `DispatchFromDyn` may only be implemented for a coercion between structures
-//~| ERROR type parameter `T` must be covered by another type when it appears before the first
 trait Foo: X<u32> {}
 trait X<T> {
     fn foo(self: Smaht<Self, T>);
diff --git a/src/test/ui/traits/issue-78372.stderr b/src/test/ui/traits/issue-78372.stderr
index 49a9f479368..7574c9107d9 100644
--- a/src/test/ui/traits/issue-78372.stderr
+++ b/src/test/ui/traits/issue-78372.stderr
@@ -50,22 +50,13 @@ LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
    |
    = help: add `#![feature(dispatch_from_dyn)]` to the crate attributes to enable
 
-error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Smaht<[type error], [type error]>`)
-  --> $DIR/issue-78372.rs:3:6
-   |
-LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
-   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Smaht<[type error], [type error]>`)
-   |
-   = 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[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures
   --> $DIR/issue-78372.rs:3:1
    |
 LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 7 previous errors
+error: aborting due to 6 previous errors
 
-Some errors have detailed explanations: E0210, E0378, E0412, E0658.
-For more information about an error, try `rustc --explain E0210`.
+Some errors have detailed explanations: E0378, E0412, E0658.
+For more information about an error, try `rustc --explain E0378`.