about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-01-08 02:40:59 +0000
committerMichael Goulet <michael@errs.io>2023-01-08 18:50:08 +0000
commitca554efaf78962f9dc9599663b29626269c69c8c (patch)
tree3958b41c6b13ed4740a484744b29b24a9b05d358
parentfa51fc01ca3d654d08d627b1d1482d1b77e5ed8b (diff)
downloadrust-ca554efaf78962f9dc9599663b29626269c69c8c.tar.gz
rust-ca554efaf78962f9dc9599663b29626269c69c8c.zip
Improve spans of non-WF implied bound types
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs58
-rw-r--r--compiler/rustc_middle/src/query/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/engine.rs6
-rw-r--r--compiler/rustc_ty_utils/src/implied_bounds.rs67
-rw-r--r--src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr4
-rw-r--r--src/test/ui/associated-types/associated-types-no-suitable-bound.stderr4
-rw-r--r--src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr4
-rw-r--r--src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr8
-rw-r--r--src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr4
-rw-r--r--src/test/ui/associated-types/issue-59324.rs2
-rw-r--r--src/test/ui/associated-types/issue-59324.stderr17
-rw-r--r--src/test/ui/issues/issue-18611.stderr8
-rw-r--r--src/test/ui/issues/issue-20831-debruijn.stderr24
-rw-r--r--src/test/ui/issues/issue-35570.rs1
-rw-r--r--src/test/ui/issues/issue-35570.stderr16
-rw-r--r--src/test/ui/nll/normalization-bounds-error.stderr8
-rw-r--r--src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs1
-rw-r--r--src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr21
-rw-r--r--src/test/ui/specialization/min_specialization/issue-79224.rs6
-rw-r--r--src/test/ui/specialization/min_specialization/issue-79224.stderr18
-rw-r--r--src/test/ui/wf/issue-103573.stderr4
-rw-r--r--src/test/ui/wf/wf-foreign-fn-decl-ret.stderr4
22 files changed, 134 insertions, 153 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 1afe6242403..b663f90cab7 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -1489,54 +1489,38 @@ fn check_fn_or_method<'tcx>(
     def_id: LocalDefId,
 ) {
     let tcx = wfcx.tcx();
-    let sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig);
+    let mut sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig);
 
     // Normalize the input and output types one at a time, using a different
     // `WellFormedLoc` for each. We cannot call `normalize_associated_types`
     // on the entire `FnSig`, since this would use the same `WellFormedLoc`
     // for each type, preventing the HIR wf check from generating
     // a nice error message.
-    let ty::FnSig { mut inputs_and_output, c_variadic, unsafety, abi } = sig;
-    inputs_and_output = tcx.mk_type_list(inputs_and_output.iter().enumerate().map(|(i, ty)| {
-        wfcx.normalize(
-            span,
-            Some(WellFormedLoc::Param {
-                function: def_id,
-                // Note that the `param_idx` of the output type is
-                // one greater than the index of the last input type.
-                param_idx: i.try_into().unwrap(),
-            }),
-            ty,
-        )
-    }));
-    // Manually call `normalize_associated_types_in` on the other types
-    // in `FnSig`. This ensures that if the types of these fields
-    // ever change to include projections, we will start normalizing
-    // them automatically.
-    let sig = ty::FnSig {
-        inputs_and_output,
-        c_variadic: wfcx.normalize(span, None, c_variadic),
-        unsafety: wfcx.normalize(span, None, unsafety),
-        abi: wfcx.normalize(span, None, abi),
-    };
+    let arg_span =
+        |idx| hir_decl.inputs.get(idx).map_or(hir_decl.output.span(), |arg: &hir::Ty<'_>| arg.span);
+
+    sig.inputs_and_output =
+        tcx.mk_type_list(sig.inputs_and_output.iter().enumerate().map(|(idx, ty)| {
+            wfcx.normalize(
+                arg_span(idx),
+                Some(WellFormedLoc::Param {
+                    function: def_id,
+                    // Note that the `param_idx` of the output type is
+                    // one greater than the index of the last input type.
+                    param_idx: idx.try_into().unwrap(),
+                }),
+                ty,
+            )
+        }));
 
-    for (i, (&input_ty, ty)) in iter::zip(sig.inputs(), hir_decl.inputs).enumerate() {
+    for (idx, ty) in sig.inputs_and_output.iter().enumerate() {
         wfcx.register_wf_obligation(
-            ty.span,
-            Some(WellFormedLoc::Param { function: def_id, param_idx: i.try_into().unwrap() }),
-            input_ty.into(),
+            arg_span(idx),
+            Some(WellFormedLoc::Param { function: def_id, param_idx: idx.try_into().unwrap() }),
+            ty.into(),
         );
     }
 
-    wfcx.register_wf_obligation(
-        hir_decl.output.span(),
-        Some(WellFormedLoc::Param {
-            function: def_id,
-            param_idx: sig.inputs().len().try_into().unwrap(),
-        }),
-        sig.output().into(),
-    );
-
     check_where_clauses(wfcx, span, def_id);
 
     check_return_position_impl_trait_in_trait_bounds(
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 37db2274f67..7f794a926c0 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -803,7 +803,7 @@ rustc_queries! {
     ///
     /// Note that we've liberated the late bound regions of function signatures, so
     /// this can not be used to check whether these types are well formed.
-    query assumed_wf_types(key: DefId) -> &'tcx ty::List<Ty<'tcx>> {
+    query assumed_wf_types(key: DefId) -> &'tcx [(Ty<'tcx>, Span)] {
         desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) }
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs
index bc6d9d4b922..72ed3aa499d 100644
--- a/compiler/rustc_trait_selection/src/traits/engine.rs
+++ b/compiler/rustc_trait_selection/src/traits/engine.rs
@@ -191,8 +191,8 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
         let assumed_wf_types = tcx.assumed_wf_types(def_id);
         let mut implied_bounds = FxIndexSet::default();
         let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
-        let cause = ObligationCause::misc(span, hir_id);
-        for ty in assumed_wf_types {
+        for &(ty, ty_span) in assumed_wf_types {
+            let span = if ty_span.is_dummy() { span } else { ty_span };
             // FIXME(@lcnr): rustc currently does not check wf for types
             // pre-normalization, meaning that implied bounds are sometimes
             // incorrect. See #100910 for more details.
@@ -205,7 +205,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
             // sound and then uncomment this line again.
 
             // implied_bounds.insert(ty);
-            let normalized = self.normalize(&cause, param_env, ty);
+            let normalized = self.normalize(&ObligationCause::misc(span, hir_id), param_env, ty);
             implied_bounds.insert(normalized);
         }
         implied_bounds
diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs
index b7a24a22c53..e3f34373ccc 100644
--- a/compiler/rustc_ty_utils/src/implied_bounds.rs
+++ b/compiler/rustc_ty_utils/src/implied_bounds.rs
@@ -1,33 +1,80 @@
 use crate::rustc_middle::ty::DefIdTree;
-use rustc_hir::{def::DefKind, def_id::DefId};
+use rustc_hir::{self as hir, def::DefKind, def_id::DefId};
 use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_span::{Span, DUMMY_SP};
 
 pub fn provide(providers: &mut ty::query::Providers) {
     *providers = ty::query::Providers { assumed_wf_types, ..*providers };
 }
 
-fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Ty<'_>> {
+fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &[(Ty<'_>, Span)] {
     match tcx.def_kind(def_id) {
         DefKind::Fn => {
             let sig = tcx.fn_sig(def_id);
             let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig);
-            liberated_sig.inputs_and_output
+            if let Some(node) = tcx.hir().get_if_local(def_id)
+                && let Some(decl) = node.fn_decl()
+            {
+                assert_eq!(decl.inputs.len(), liberated_sig.inputs().len());
+                tcx.arena.alloc_from_iter(std::iter::zip(
+                    liberated_sig.inputs_and_output,
+                    decl.inputs.iter().map(|ty| ty.span).chain([decl.output.span()]),
+                ))
+            } else {
+                tcx.arena.alloc_from_iter(
+                    liberated_sig.inputs_and_output.iter().map(|ty| (ty, DUMMY_SP)),
+                )
+            }
         }
         DefKind::AssocFn => {
             let sig = tcx.fn_sig(def_id);
             let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig);
-            let mut assumed_wf_types: Vec<_> =
-                tcx.assumed_wf_types(tcx.parent(def_id)).as_slice().into();
-            assumed_wf_types.extend(liberated_sig.inputs_and_output);
-            tcx.intern_type_list(&assumed_wf_types)
+            let assumed_wf_types = tcx.assumed_wf_types(tcx.parent(def_id));
+            if let Some(node) = tcx.hir().get_if_local(def_id)
+                && let Some(decl) = node.fn_decl()
+            {
+                assert_eq!(decl.inputs.len(), liberated_sig.inputs().len());
+                tcx.arena.alloc_from_iter(assumed_wf_types.iter().copied().chain(std::iter::zip(
+                    liberated_sig.inputs_and_output,
+                    decl.inputs.iter().map(|ty| ty.span).chain([decl.output.span()]),
+                )))
+            } else {
+                tcx.arena.alloc_from_iter(assumed_wf_types.iter().copied().chain(
+                    liberated_sig.inputs_and_output.iter().map(|ty| (ty, DUMMY_SP)),
+                ))
+            }
         }
         DefKind::Impl => match tcx.impl_trait_ref(def_id) {
             Some(trait_ref) => {
                 let types: Vec<_> = trait_ref.substs.types().collect();
-                tcx.intern_type_list(&types)
+                let self_span = if let Some(hir::Node::Item(hir::Item {
+                    kind: hir::ItemKind::Impl(impl_),
+                    ..
+                })) = tcx.hir().get_if_local(def_id)
+                {
+                    impl_.self_ty.span
+                } else {
+                    DUMMY_SP
+                };
+                tcx.arena.alloc_from_iter(std::iter::zip(
+                    types,
+                    // FIXME: reliable way of getting trait ref substs...
+                    [self_span].into_iter().chain(std::iter::repeat(DUMMY_SP)),
+                ))
             }
             // Only the impl self type
-            None => tcx.intern_type_list(&[tcx.type_of(def_id)]),
+            None => {
+                let span = if let Some(hir::Node::Item(hir::Item {
+                    kind: hir::ItemKind::Impl(impl_),
+                    ..
+                })) = tcx.hir().get_if_local(def_id)
+                {
+                    impl_.self_ty.span
+                } else {
+                    DUMMY_SP
+                };
+                tcx.arena.alloc_from_iter([(tcx.type_of(def_id), span)])
+            }
         },
         DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)),
         DefKind::Mod
@@ -56,6 +103,6 @@ fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Ty<'_>> {
         | DefKind::LifetimeParam
         | DefKind::GlobalAsm
         | DefKind::Closure
-        | DefKind::Generator => ty::List::empty(),
+        | DefKind::Generator => &[],
     }
 }
diff --git a/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr b/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr
index 389cc7beddd..6552c8be780 100644
--- a/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr
+++ b/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `Self: Get` is not satisfied
-  --> $DIR/associated-types-for-unimpl-trait.rs:10:5
+  --> $DIR/associated-types-for-unimpl-trait.rs:10:40
    |
 LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
+   |                                        ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
    |
 help: consider further restricting `Self`
    |
diff --git a/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr b/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr
index 1feaa612ee6..b2ee1b5e6d0 100644
--- a/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr
+++ b/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `T: Get` is not satisfied
-  --> $DIR/associated-types-no-suitable-bound.rs:11:5
+  --> $DIR/associated-types-no-suitable-bound.rs:11:21
    |
 LL |     fn uhoh<T>(foo: <T as Get>::Value) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T`
+   |                     ^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T`
    |
 help: consider restricting type parameter `T`
    |
diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr b/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr
index cc3ed556115..2e40dbd065d 100644
--- a/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr
+++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `Self: Get` is not satisfied
-  --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:5
+  --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:40
    |
 LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
+   |                                        ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
    |
 help: consider further restricting `Self`
    |
diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr
index 18f2830d8b2..bd3ee2abd2c 100644
--- a/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr
+++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr
@@ -1,14 +1,14 @@
 error[E0277]: the trait bound `(T, U): Get` is not satisfied
-  --> $DIR/associated-types-no-suitable-supertrait.rs:22:5
+  --> $DIR/associated-types-no-suitable-supertrait.rs:22:40
    |
 LL |     fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
 
 error[E0277]: the trait bound `Self: Get` is not satisfied
-  --> $DIR/associated-types-no-suitable-supertrait.rs:17:5
+  --> $DIR/associated-types-no-suitable-supertrait.rs:17:40
    |
 LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
+   |                                        ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
    |
 help: consider further restricting `Self`
    |
diff --git a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr
index 66d59bccdbb..2e67c21940f 100644
--- a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr
+++ b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `Self: Get` is not satisfied
-  --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:5
+  --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:40
    |
 LL |     fn okay<U:Get>(&self, foo: U, bar: <Self as Get>::Value);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
+   |                                        ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
    |
 help: consider further restricting `Self`
    |
diff --git a/src/test/ui/associated-types/issue-59324.rs b/src/test/ui/associated-types/issue-59324.rs
index 9e68e9e7751..551f13ee178 100644
--- a/src/test/ui/associated-types/issue-59324.rs
+++ b/src/test/ui/associated-types/issue-59324.rs
@@ -15,9 +15,9 @@ pub trait ThriftService<Bug: NotFoo>:
 {
     fn get_service(
     //~^ ERROR the trait bound `Bug: Foo` is not satisfied
-    //~| ERROR the trait bound `Bug: Foo` is not satisfied
         &self,
     ) -> Self::AssocType;
+    //~^ ERROR the trait bound `Bug: Foo` is not satisfied
 }
 
 fn with_factory<H>(factory: dyn ThriftService<()>) {}
diff --git a/src/test/ui/associated-types/issue-59324.stderr b/src/test/ui/associated-types/issue-59324.stderr
index 62cf1f37a77..a84b599b52b 100644
--- a/src/test/ui/associated-types/issue-59324.stderr
+++ b/src/test/ui/associated-types/issue-59324.stderr
@@ -20,7 +20,7 @@ LL | |
 LL | |
 LL | |     Service<AssocType = <Bug as Foo>::OnlyFoo>
 ...  |
-LL | |     ) -> Self::AssocType;
+LL | |
 LL | | }
    | |_^ the trait `Foo` is not implemented for `Bug`
    |
@@ -34,7 +34,6 @@ error[E0277]: the trait bound `Bug: Foo` is not satisfied
    |
 LL | /     fn get_service(
 LL | |
-LL | |
 LL | |         &self,
 LL | |     ) -> Self::AssocType;
    | |_________________________^ the trait `Foo` is not implemented for `Bug`
@@ -45,20 +44,16 @@ LL | pub trait ThriftService<Bug: NotFoo + Foo>:
    |                                     +++++
 
 error[E0277]: the trait bound `(): Foo` is not satisfied
-  --> $DIR/issue-59324.rs:23:1
+  --> $DIR/issue-59324.rs:23:29
    |
 LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
+   |                             ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
 
 error[E0277]: the trait bound `Bug: Foo` is not satisfied
-  --> $DIR/issue-59324.rs:16:5
+  --> $DIR/issue-59324.rs:19:10
    |
-LL | /     fn get_service(
-LL | |
-LL | |
-LL | |         &self,
-LL | |     ) -> Self::AssocType;
-   | |_________________________^ the trait `Foo` is not implemented for `Bug`
+LL |     ) -> Self::AssocType;
+   |          ^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bug`
    |
 help: consider further restricting this bound
    |
diff --git a/src/test/ui/issues/issue-18611.stderr b/src/test/ui/issues/issue-18611.stderr
index 22c3470b61e..bd18d46223e 100644
--- a/src/test/ui/issues/issue-18611.stderr
+++ b/src/test/ui/issues/issue-18611.stderr
@@ -1,10 +1,8 @@
 error[E0277]: the trait bound `isize: HasState` is not satisfied
-  --> $DIR/issue-18611.rs:1:1
+  --> $DIR/issue-18611.rs:1:18
    |
-LL | / fn add_state(op: <isize as HasState>::State) {
-LL | |
-LL | | }
-   | |_^ the trait `HasState` is not implemented for `isize`
+LL | fn add_state(op: <isize as HasState>::State) {
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasState` is not implemented for `isize`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr
index ef62dece836..c3af1f6786b 100644
--- a/src/test/ui/issues/issue-20831-debruijn.stderr
+++ b/src/test/ui/issues/issue-20831-debruijn.stderr
@@ -1,14 +1,8 @@
 error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
-  --> $DIR/issue-20831-debruijn.rs:28:5
+  --> $DIR/issue-20831-debruijn.rs:28:33
    |
-LL | /     fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
-LL | |         // Not obvious, but there is an implicit lifetime here -------^
-LL | |
-LL | |         //
-...  |
-LL | |         self.sub = t;
-LL | |     }
-   | |_____^
+LL |     fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: first, the lifetime cannot outlive the anonymous lifetime defined here...
   --> $DIR/issue-20831-debruijn.rs:28:58
@@ -21,16 +15,10 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined he
 LL | impl<'a> Publisher<'a> for MyStruct<'a> {
    |      ^^
 note: ...so that the types are compatible
-  --> $DIR/issue-20831-debruijn.rs:28:5
+  --> $DIR/issue-20831-debruijn.rs:28:33
    |
-LL | /     fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
-LL | |         // Not obvious, but there is an implicit lifetime here -------^
-LL | |
-LL | |         //
-...  |
-LL | |         self.sub = t;
-LL | |     }
-   | |_____^
+LL |     fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: expected `<MyStruct<'a> as Publisher<'_>>`
               found `<MyStruct<'_> as Publisher<'_>>`
 
diff --git a/src/test/ui/issues/issue-35570.rs b/src/test/ui/issues/issue-35570.rs
index a2b0222d4f3..42bdb423f8f 100644
--- a/src/test/ui/issues/issue-35570.rs
+++ b/src/test/ui/issues/issue-35570.rs
@@ -7,7 +7,6 @@ trait Trait2<'a> {
 
 fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
     //~^ ERROR the trait bound `for<'a> (): Trait2<'a>` is not satisfied
-    //~| ERROR the trait bound `for<'a> (): Trait2<'a>` is not satisfied
     let _e: (usize, usize) = unsafe{mem::transmute(param)};
 }
 
diff --git a/src/test/ui/issues/issue-35570.stderr b/src/test/ui/issues/issue-35570.stderr
index ebc40f6786f..b6c244241ed 100644
--- a/src/test/ui/issues/issue-35570.stderr
+++ b/src/test/ui/issues/issue-35570.stderr
@@ -1,19 +1,9 @@
 error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied
-  --> $DIR/issue-35570.rs:8:1
-   |
-LL | / fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
-LL | |
-LL | |
-LL | |     let _e: (usize, usize) = unsafe{mem::transmute(param)};
-LL | | }
-   | |_^ the trait `for<'a> Trait2<'a>` is not implemented for `()`
-
-error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied
-  --> $DIR/issue-35570.rs:8:40
+  --> $DIR/issue-35570.rs:8:16
    |
 LL | fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
-   |                                        ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()`
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/nll/normalization-bounds-error.stderr b/src/test/ui/nll/normalization-bounds-error.stderr
index 6abe53127c3..0fc3670d6c5 100644
--- a/src/test/ui/nll/normalization-bounds-error.stderr
+++ b/src/test/ui/nll/normalization-bounds-error.stderr
@@ -1,8 +1,8 @@
 error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'d` due to conflicting requirements
-  --> $DIR/normalization-bounds-error.rs:12:1
+  --> $DIR/normalization-bounds-error.rs:12:31
    |
 LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: first, the lifetime cannot outlive the lifetime `'d` as defined here...
   --> $DIR/normalization-bounds-error.rs:12:14
@@ -15,10 +15,10 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined he
 LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
    |                  ^^
 note: ...so that the types are compatible
-  --> $DIR/normalization-bounds-error.rs:12:1
+  --> $DIR/normalization-bounds-error.rs:12:31
    |
 LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: expected `Visitor<'d>`
               found `Visitor<'_>`
 
diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs
index 1106352037a..429548f119b 100644
--- a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs
+++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs
@@ -20,7 +20,6 @@ trait Trait2<'a, 'b> {
 // do not infer that.
 fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
     //~^ ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
-    //~| ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
 {
 }
 
diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr
index 66f592c34dd..43b7b9c16b1 100644
--- a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr
+++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr
@@ -1,29 +1,14 @@
 error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
-  --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:1
-   |
-LL | / fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
-LL | |
-LL | |
-LL | | {
-LL | | }
-   | |_^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T`
-   |
-help: consider restricting type parameter `T`
-   |
-LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
-   |                    ++++++++++++++++++++++++
-
-error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
-  --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:49
+  --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:25
    |
 LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
-   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T`
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T`
    |
 help: consider restricting type parameter `T`
    |
 LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
    |                    ++++++++++++++++++++++++
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/specialization/min_specialization/issue-79224.rs b/src/test/ui/specialization/min_specialization/issue-79224.rs
index 408732fe944..d02c108ae6b 100644
--- a/src/test/ui/specialization/min_specialization/issue-79224.rs
+++ b/src/test/ui/specialization/min_specialization/issue-79224.rs
@@ -15,8 +15,10 @@ impl ToString for Cow<'_, str> {
     }
 }
 
-impl<B: ?Sized> Display for Cow<'_, B> { //~ ERROR: the trait bound `B: Clone` is not satisfied [E0277]
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { //~ ERROR: the trait bound `B: Clone` is not satisfied [E0277]
+impl<B: ?Sized> Display for Cow<'_, B> {
+    //~^ ERROR: the trait bound `B: Clone` is not satisfied [E0277]
+    //~| ERROR: the trait bound `B: Clone` is not satisfied [E0277]
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "foo")
     }
 }
diff --git a/src/test/ui/specialization/min_specialization/issue-79224.stderr b/src/test/ui/specialization/min_specialization/issue-79224.stderr
index fd34a59d2bd..d4d7daf4111 100644
--- a/src/test/ui/specialization/min_specialization/issue-79224.stderr
+++ b/src/test/ui/specialization/min_specialization/issue-79224.stderr
@@ -1,12 +1,8 @@
 error[E0277]: the trait bound `B: Clone` is not satisfied
-  --> $DIR/issue-79224.rs:18:1
+  --> $DIR/issue-79224.rs:18:29
    |
-LL | / impl<B: ?Sized> Display for Cow<'_, B> {
-LL | |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-LL | |         write!(f, "foo")
-LL | |     }
-LL | | }
-   | |_^ the trait `Clone` is not implemented for `B`
+LL | impl<B: ?Sized> Display for Cow<'_, B> {
+   |                             ^^^^^^^^^^ the trait `Clone` is not implemented for `B`
    |
    = note: required for `B` to implement `ToOwned`
 help: consider further restricting this bound
@@ -15,12 +11,10 @@ LL | impl<B: ?Sized + std::clone::Clone> Display for Cow<'_, B> {
    |                +++++++++++++++++++
 
 error[E0277]: the trait bound `B: Clone` is not satisfied
-  --> $DIR/issue-79224.rs:19:5
+  --> $DIR/issue-79224.rs:18:29
    |
-LL | /     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-LL | |         write!(f, "foo")
-LL | |     }
-   | |_____^ the trait `Clone` is not implemented for `B`
+LL | impl<B: ?Sized> Display for Cow<'_, B> {
+   |                             ^^^^^^^^^^ the trait `Clone` is not implemented for `B`
    |
    = note: required for `B` to implement `ToOwned`
 help: consider further restricting this bound
diff --git a/src/test/ui/wf/issue-103573.stderr b/src/test/ui/wf/issue-103573.stderr
index fcf3f15e4d3..3b6ab332612 100644
--- a/src/test/ui/wf/issue-103573.stderr
+++ b/src/test/ui/wf/issue-103573.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `<<Self as TraitC<E>>::TypeC<'a> as TraitB>::TypeB: TraitA` is not satisfied
-  --> $DIR/issue-103573.rs:18:5
+  --> $DIR/issue-103573.rs:18:17
    |
 LL |     fn g<'a>(_: &<<Self::TypeC<'a> as TraitB>::TypeB as TraitA>::TypeA);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TraitA` is not implemented for `<<Self as TraitC<E>>::TypeC<'a> as TraitB>::TypeB`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TraitA` is not implemented for `<<Self as TraitC<E>>::TypeC<'a> as TraitB>::TypeB`
    |
 help: consider further restricting the associated type
    |
diff --git a/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr
index 78312a09105..b03023b5fd1 100644
--- a/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr
+++ b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `(): Foo` is not satisfied
-  --> $DIR/wf-foreign-fn-decl-ret.rs:11:5
+  --> $DIR/wf-foreign-fn-decl-ret.rs:11:25
    |
 LL |     pub fn lint_me() -> <() as Foo>::Assoc;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
+   |                         ^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
 
 error[E0277]: the trait bound `u32: Unsatisfied` is not satisfied
   --> $DIR/wf-foreign-fn-decl-ret.rs:14:32