From 86e1860495403ee0154608e51fe4b4d81203e15f Mon Sep 17 00:00:00 2001
From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Date: Wed, 16 Feb 2022 15:48:46 +0000
Subject: [PATCH] Revert to inference variable based hidden type computation
 for RPIT

---
 .../rustc_infer/src/infer/opaque_types.rs     |  2 +-
 compiler/rustc_typeck/src/check/check.rs      | 45 ++++++++++-
 compiler/rustc_typeck/src/check/writeback.rs  | 24 +++++-
 .../impl-trait-return-missing-constraint.rs   |  3 +-
 ...mpl-trait-return-missing-constraint.stderr | 31 ++++++-
 .../async-await/issue-64130-4-async-move.rs   |  2 +-
 .../issue-64130-4-async-move.stderr           |  6 +-
 src/test/ui/async-await/issue-70818.rs        |  2 +-
 src/test/ui/async-await/issue-70818.stderr    |  8 +-
 .../async-await/issue-70935-complex-spans.rs  |  2 +-
 .../issue-70935-complex-spans.stderr          |  6 +-
 src/test/ui/conservative_impl_trait.stderr    |  9 +--
 .../defaults/rp_impl_trait_fail.rs            |  9 ++-
 .../defaults/rp_impl_trait_fail.stderr        | 64 ++++++++++++---
 src/test/ui/generator/issue-88653.rs          |  8 +-
 src/test/ui/generator/issue-88653.stderr      | 28 +++++--
 .../type-mismatch-signature-deduction.rs      |  4 +-
 .../type-mismatch-signature-deduction.stderr  | 36 ++++++---
 .../issue-92096.migrate.stderr                | 18 ++---
 .../generic-associated-types/issue-92096.rs   |  4 +-
 .../ui/impl-trait/bound-normalization-fail.rs |  6 +-
 .../bound-normalization-fail.stderr           | 63 +++++++++++++--
 .../impl-trait/cross-return-site-inference.rs | 45 +++++++++++
 .../cross-return-site-inference.stderr        | 26 ++++++
 src/test/ui/impl-trait/divergence.rs          | 13 +++
 src/test/ui/impl-trait/equality.stderr        |  5 +-
 src/test/ui/impl-trait/issues/issue-70877.rs  |  2 +-
 .../ui/impl-trait/issues/issue-70877.stderr   | 11 ++-
 .../ui/impl-trait/issues/issue-88236-2.rs     |  4 +-
 .../ui/impl-trait/issues/issue-88236-2.stderr | 15 ++--
 ...t_outlive_least_region_or_bound.nll.stderr |  2 +-
 .../must_outlive_least_region_or_bound.rs     |  3 +-
 .../must_outlive_least_region_or_bound.stderr | 48 ++++++++---
 .../ui/impl-trait/nested_impl_trait.stderr    |  8 +-
 ...trait-in-return-position-impl-trait.stderr | 10 +--
 ...-to-type-err-cause-on-impl-trait-return.rs | 12 +--
 ...type-err-cause-on-impl-trait-return.stderr | 81 +++++--------------
 ...rojection-mismatch-in-impl-where-clause.rs |  2 +-
 ...ction-mismatch-in-impl-where-clause.stderr |  6 +-
 src/test/ui/impl-trait/question_mark.rs       | 31 +++++--
 .../type_parameters_captured.nll.stderr       |  2 +-
 .../ui/impl-trait/type_parameters_captured.rs |  3 +-
 .../type_parameters_captured.stderr           | 23 ++++--
 src/test/ui/issues-71798.rs                   |  2 +-
 src/test/ui/issues-71798.stderr               |  6 +-
 .../lang-item-missing-generator.stderr        |  4 +-
 .../lifetime-elision-return-type-trait.rs     |  3 +-
 .../lifetime-elision-return-type-trait.stderr | 19 ++++-
 .../impl-trait-return-trailing-semicolon.rs   |  1 +
 ...mpl-trait-return-trailing-semicolon.stderr | 11 ++-
 src/test/ui/suggestions/issue-81098.rs        |  2 +
 src/test/ui/suggestions/issue-81098.stderr    | 27 ++++++-
 .../trait-object-nested-in-impl-trait.stderr  | 52 ++++--------
 .../nested-tait-inference.rs                  |  3 +-
 .../nested-tait-inference.stderr              | 23 +++++-
 .../nested-tait-inference2.rs                 |  3 +-
 .../nested-tait-inference2.stderr             | 23 +++++-
 57 files changed, 642 insertions(+), 269 deletions(-)
 create mode 100644 src/test/ui/impl-trait/cross-return-site-inference.rs
 create mode 100644 src/test/ui/impl-trait/cross-return-site-inference.stderr
 create mode 100644 src/test/ui/impl-trait/divergence.rs

diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index ba74aa804e3..ce922bca356 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -510,7 +510,7 @@ impl UseKind {
 
 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     #[instrument(skip(self), level = "debug")]
-    fn register_hidden_type(
+    pub fn register_hidden_type(
         &self,
         opaque_type_key: OpaqueTypeKey<'tcx>,
         cause: ObligationCause<'tcx>,
diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs
index 1a5f118ea50..ee93a8ce535 100644
--- a/compiler/rustc_typeck/src/check/check.rs
+++ b/compiler/rustc_typeck/src/check/check.rs
@@ -3,6 +3,7 @@ use super::compare_method::check_type_bounds;
 use super::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl};
 use super::*;
 
+use hir::OpaqueTyOrigin;
 use rustc_attr as attr;
 use rustc_errors::{Applicability, ErrorGuaranteed};
 use rustc_hir as hir;
@@ -12,8 +13,9 @@ use rustc_hir::lang_items::LangItem;
 use rustc_hir::{def::Res, ItemKind, Node, PathSegment};
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
+use rustc_infer::traits::ObligationCause;
 use rustc_middle::hir::nested_filter;
-use rustc_middle::ty::fold::TypeFoldable;
+use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable};
 use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
 use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::util::{Discr, IntTypeExt};
@@ -95,7 +97,46 @@ pub(super) fn check_fn<'a, 'tcx>(
 
     let declared_ret_ty = fn_sig.output();
 
-    fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(declared_ret_ty)));
+    let ret_ty = declared_ret_ty.fold_with(&mut BottomUpFolder {
+        tcx: fcx.tcx,
+        ty_op: |ty| match *ty.kind() {
+            ty::Opaque(def_id, substs) => {
+                let span = tcx.def_span(def_id);
+                if let Some(origin @ OpaqueTyOrigin::FnReturn(_)) =
+                    fcx.infcx.opaque_type_origin(def_id, span)
+                {
+                    let hidden_ty = fcx.infcx.next_ty_var(TypeVariableOrigin {
+                        kind: TypeVariableOriginKind::MiscVariable,
+                        span: span,
+                    });
+
+                    let cause = ObligationCause::misc(span, body.value.hir_id);
+                    match fcx.infcx.register_hidden_type(
+                        ty::OpaqueTypeKey { def_id, substs },
+                        cause.clone(),
+                        param_env,
+                        hidden_ty,
+                        origin,
+                    ) {
+                        Ok(infer_ok) => {
+                            fcx.register_infer_ok_obligations(infer_ok);
+                            hidden_ty
+                        }
+                        Err(err) => {
+                            fcx.report_mismatched_types(&cause, ty, hidden_ty, err).emit();
+                            tcx.ty_error()
+                        }
+                    }
+                } else {
+                    ty
+                }
+            }
+            _ => ty,
+        },
+        lt_op: |lt| lt,
+        ct_op: |ct| ct,
+    });
+    fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
     fcx.ret_type_span = Some(decl.output.span());
 
     let span = body.value.span;
diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs
index 35f1ddb65aa..ecbd1e46349 100644
--- a/compiler/rustc_typeck/src/check/writeback.rs
+++ b/compiler/rustc_typeck/src/check/writeback.rs
@@ -20,6 +20,7 @@ use rustc_span::symbol::sym;
 use rustc_span::Span;
 
 use std::mem;
+use std::ops::ControlFlow;
 
 ///////////////////////////////////////////////////////////////////////////
 // Entry point
@@ -503,7 +504,28 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         for (opaque_type_key, decl) in opaque_types {
             let hidden_type = match decl.origin {
                 hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_) => {
-                    Some(self.resolve(decl.hidden_type.ty, &decl.hidden_type.span))
+                    let ty = self.resolve(decl.hidden_type.ty, &decl.hidden_type.span);
+                    struct RecursionChecker {
+                        def_id: DefId,
+                    }
+                    impl<'tcx> ty::TypeVisitor<'tcx> for RecursionChecker {
+                        type BreakTy = ();
+                        fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
+                            if let ty::Opaque(def_id, _) = *t.kind() {
+                                if def_id == self.def_id {
+                                    return ControlFlow::Break(());
+                                }
+                            }
+                            t.super_visit_with(self)
+                        }
+                    }
+                    if ty
+                        .visit_with(&mut RecursionChecker { def_id: opaque_type_key.def_id })
+                        .is_break()
+                    {
+                        return;
+                    }
+                    Some(ty)
                 }
                 hir::OpaqueTyOrigin::TyAlias => None,
             };
diff --git a/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs b/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs
index 30e4c1a3c53..ef0443034ec 100644
--- a/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs
+++ b/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs
@@ -23,8 +23,9 @@ fn bar() -> impl Bar {
 }
 
 fn baz() -> impl Bar<Item = i32> {
-    bar()
     //~^ ERROR type mismatch resolving `<impl Bar as Foo>::Item == i32`
+    //~| ERROR type mismatch resolving `<impl Bar as Foo>::Item == i32`
+    bar()
 }
 
 fn main() {
diff --git a/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr b/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr
index 9523a54d954..b7c49570ca4 100644
--- a/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr
+++ b/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr
@@ -1,11 +1,11 @@
 error[E0271]: type mismatch resolving `<impl Bar as Foo>::Item == i32`
-  --> $DIR/impl-trait-return-missing-constraint.rs:26:5
+  --> $DIR/impl-trait-return-missing-constraint.rs:25:13
    |
 LL | fn bar() -> impl Bar {
    |             -------- the expected opaque type
 ...
-LL |     bar()
-   |     ^^^^^ expected associated type, found `i32`
+LL | fn baz() -> impl Bar<Item = i32> {
+   |             ^^^^^^^^^^^^^^^^^^^^ expected associated type, found `i32`
    |
    = note: expected associated type `<impl Bar as Foo>::Item`
                          found type `i32`
@@ -16,6 +16,29 @@ help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i3
 LL | fn bar() -> impl Bar<Item = i32> {
    |                     ++++++++++++
 
-error: aborting due to previous error
+error[E0271]: type mismatch resolving `<impl Bar as Foo>::Item == i32`
+  --> $DIR/impl-trait-return-missing-constraint.rs:25:34
+   |
+LL |   fn bar() -> impl Bar {
+   |               -------- the expected opaque type
+...
+LL |   fn baz() -> impl Bar<Item = i32> {
+   |  __________________________________^
+LL | |
+LL | |
+LL | |     bar()
+LL | | }
+   | |_^ expected associated type, found `i32`
+   |
+   = note: expected associated type `<impl Bar as Foo>::Item`
+                         found type `i32`
+   = help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i32` or calling a method that returns `<impl Bar as Foo>::Item`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i32`
+   |
+LL | fn bar() -> impl Bar<Item = i32> {
+   |                     ++++++++++++
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/async-await/issue-64130-4-async-move.rs b/src/test/ui/async-await/issue-64130-4-async-move.rs
index 7cb02e5cf38..2538f34351e 100644
--- a/src/test/ui/async-await/issue-64130-4-async-move.rs
+++ b/src/test/ui/async-await/issue-64130-4-async-move.rs
@@ -13,9 +13,9 @@ impl Client {
 async fn get() { }
 
 pub fn foo() -> impl Future + Send {
+    //~^ ERROR future cannot be sent between threads safely
     let client = Client(Box::new(true));
     async move {
-        //~^ ERROR future cannot be sent between threads safely
         match client.status() {
             200 => {
                 let _x = get().await;
diff --git a/src/test/ui/async-await/issue-64130-4-async-move.stderr b/src/test/ui/async-await/issue-64130-4-async-move.stderr
index 3a84907e0c0..d631e6dc7f7 100644
--- a/src/test/ui/async-await/issue-64130-4-async-move.stderr
+++ b/src/test/ui/async-await/issue-64130-4-async-move.stderr
@@ -1,8 +1,8 @@
 error: future cannot be sent between threads safely
-  --> $DIR/issue-64130-4-async-move.rs:17:5
+  --> $DIR/issue-64130-4-async-move.rs:15:17
    |
-LL |     async move {
-   |     ^^^^^^^^^^ future created by async block is not `Send`
+LL | pub fn foo() -> impl Future + Send {
+   |                 ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
    |
    = help: the trait `Sync` is not implemented for `(dyn Any + Send + 'static)`
 note: future is not `Send` as this value is used across an await
diff --git a/src/test/ui/async-await/issue-70818.rs b/src/test/ui/async-await/issue-70818.rs
index 631389e10f3..019c56eb2fa 100644
--- a/src/test/ui/async-await/issue-70818.rs
+++ b/src/test/ui/async-await/issue-70818.rs
@@ -2,8 +2,8 @@
 
 use std::future::Future;
 fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
-    async { (ty, ty1) }
     //~^ Error future cannot be sent between threads safely
+    async { (ty, ty1) }
 }
 
 fn main() {}
diff --git a/src/test/ui/async-await/issue-70818.stderr b/src/test/ui/async-await/issue-70818.stderr
index cb50c70f998..20109d4d116 100644
--- a/src/test/ui/async-await/issue-70818.stderr
+++ b/src/test/ui/async-await/issue-70818.stderr
@@ -1,11 +1,11 @@
 error: future cannot be sent between threads safely
-  --> $DIR/issue-70818.rs:5:5
+  --> $DIR/issue-70818.rs:4:38
    |
-LL |     async { (ty, ty1) }
-   |     ^^^^^ future created by async block is not `Send`
+LL | fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
+   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
    |
 note: captured value is not `Send`
-  --> $DIR/issue-70818.rs:5:18
+  --> $DIR/issue-70818.rs:6:18
    |
 LL |     async { (ty, ty1) }
    |                  ^^^ has type `U` which is not `Send`
diff --git a/src/test/ui/async-await/issue-70935-complex-spans.rs b/src/test/ui/async-await/issue-70935-complex-spans.rs
index 49456122951..2965a7e0654 100644
--- a/src/test/ui/async-await/issue-70935-complex-spans.rs
+++ b/src/test/ui/async-await/issue-70935-complex-spans.rs
@@ -8,8 +8,8 @@ async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
 }
 
 fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send {
+    //~^ ERROR: future cannot be sent between threads safely
     async move {
-        //~^ ERROR: future cannot be sent between threads safely
         baz(|| async{
             foo(tx.clone());
         }).await;
diff --git a/src/test/ui/async-await/issue-70935-complex-spans.stderr b/src/test/ui/async-await/issue-70935-complex-spans.stderr
index ad61f21741b..db309938119 100644
--- a/src/test/ui/async-await/issue-70935-complex-spans.stderr
+++ b/src/test/ui/async-await/issue-70935-complex-spans.stderr
@@ -1,8 +1,8 @@
 error: future cannot be sent between threads safely
-  --> $DIR/issue-70935-complex-spans.rs:11:5
+  --> $DIR/issue-70935-complex-spans.rs:10:45
    |
-LL |     async move {
-   |     ^^^^^^^^^^ future created by async block is not `Send`
+LL | fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send {
+   |                                             ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
    |
    = help: the trait `Sync` is not implemented for `Sender<i32>`
 note: future is not `Send` as this value is used across an await
diff --git a/src/test/ui/conservative_impl_trait.stderr b/src/test/ui/conservative_impl_trait.stderr
index 9dc486980aa..63a4df242f8 100644
--- a/src/test/ui/conservative_impl_trait.stderr
+++ b/src/test/ui/conservative_impl_trait.stderr
@@ -1,11 +1,8 @@
 error[E0277]: `()` is not an iterator
-  --> $DIR/conservative_impl_trait.rs:3:60
+  --> $DIR/conservative_impl_trait.rs:3:33
    |
-LL |   fn will_ice(something: &u32) -> impl Iterator<Item = &u32> {
-   |  ____________________________________________________________^
-LL | |
-LL | | }
-   | |_^ `()` is not an iterator
+LL | fn will_ice(something: &u32) -> impl Iterator<Item = &u32> {
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `()`
 
diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs
index b3bd88ad7d5..24031aa1e61 100644
--- a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs
+++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs
@@ -4,8 +4,9 @@ trait Trait {}
 impl<const N: u32> Trait for Uwu<N> {}
 
 fn rawr() -> impl Trait {
-    Uwu::<10, 12>
     //~^ error: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied
+    //~| error: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied
+    Uwu::<10, 12>
 }
 
 trait Traitor<const N: u8 = 1, const M: u8 = N> { }
@@ -15,13 +16,15 @@ impl Traitor<1, 2> for u64 {}
 
 
 fn uwu<const N: u8>() -> impl Traitor<N> {
-    1_u32
     //~^ error: the trait bound `u32: Traitor<N, N>` is not satisfied
+    //~| error: the trait bound `u32: Traitor<N, N>` is not satisfied
+    1_u32
 }
 
 fn owo() -> impl Traitor {
-    1_u64
     //~^ error: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied
+    //~| error: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied
+    1_u64
 }
 
 fn main() {
diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr
index 1cfaf83c5a6..81cfcb35606 100644
--- a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr
+++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr
@@ -1,32 +1,76 @@
 error[E0277]: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied
-  --> $DIR/rp_impl_trait_fail.rs:7:5
+  --> $DIR/rp_impl_trait_fail.rs:6:14
    |
-LL |     Uwu::<10, 12>
-   |     ^^^^^^^^^^^^^ the trait `Trait` is not implemented for `Uwu<10_u32, 12_u32>`
+LL | fn rawr() -> impl Trait {
+   |              ^^^^^^^^^^ the trait `Trait` is not implemented for `Uwu<10_u32, 12_u32>`
+   |
+   = help: the following implementations were found:
+             <Uwu<N> as Trait>
+
+error[E0277]: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied
+  --> $DIR/rp_impl_trait_fail.rs:6:25
+   |
+LL |   fn rawr() -> impl Trait {
+   |  _________________________^
+LL | |
+LL | |
+LL | |     Uwu::<10, 12>
+LL | | }
+   | |_^ the trait `Trait` is not implemented for `Uwu<10_u32, 12_u32>`
    |
    = help: the following implementations were found:
              <Uwu<N> as Trait>
 
 error[E0277]: the trait bound `u32: Traitor<N, N>` is not satisfied
-  --> $DIR/rp_impl_trait_fail.rs:18:5
+  --> $DIR/rp_impl_trait_fail.rs:18:26
    |
-LL |     1_u32
-   |     ^^^^^ the trait `Traitor<N, N>` is not implemented for `u32`
+LL | fn uwu<const N: u8>() -> impl Traitor<N> {
+   |                          ^^^^^^^^^^^^^^^ the trait `Traitor<N, N>` is not implemented for `u32`
+   |
+   = help: the following implementations were found:
+             <u32 as Traitor<N, 2_u8>>
+             <u64 as Traitor<1_u8, 2_u8>>
+
+error[E0277]: the trait bound `u32: Traitor<N, N>` is not satisfied
+  --> $DIR/rp_impl_trait_fail.rs:18:42
+   |
+LL |   fn uwu<const N: u8>() -> impl Traitor<N> {
+   |  __________________________________________^
+LL | |
+LL | |
+LL | |     1_u32
+LL | | }
+   | |_^ the trait `Traitor<N, N>` is not implemented for `u32`
    |
    = help: the following implementations were found:
              <u32 as Traitor<N, 2_u8>>
              <u64 as Traitor<1_u8, 2_u8>>
 
 error[E0277]: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied
-  --> $DIR/rp_impl_trait_fail.rs:23:5
+  --> $DIR/rp_impl_trait_fail.rs:24:13
    |
-LL |     1_u64
-   |     ^^^^^ the trait `Traitor<1_u8, 1_u8>` is not implemented for `u64`
+LL | fn owo() -> impl Traitor {
+   |             ^^^^^^^^^^^^ the trait `Traitor<1_u8, 1_u8>` is not implemented for `u64`
    |
    = help: the following implementations were found:
              <u64 as Traitor<1_u8, 2_u8>>
              <u32 as Traitor<N, 2_u8>>
 
-error: aborting due to 3 previous errors
+error[E0277]: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied
+  --> $DIR/rp_impl_trait_fail.rs:24:26
+   |
+LL |   fn owo() -> impl Traitor {
+   |  __________________________^
+LL | |
+LL | |
+LL | |     1_u64
+LL | | }
+   | |_^ the trait `Traitor<1_u8, 1_u8>` is not implemented for `u64`
+   |
+   = help: the following implementations were found:
+             <u64 as Traitor<1_u8, 2_u8>>
+             <u32 as Traitor<N, 2_u8>>
+
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/generator/issue-88653.rs b/src/test/ui/generator/issue-88653.rs
index c4905995a86..f27956e4595 100644
--- a/src/test/ui/generator/issue-88653.rs
+++ b/src/test/ui/generator/issue-88653.rs
@@ -6,10 +6,14 @@
 use std::ops::Generator;
 
 fn foo(bar: bool) -> impl Generator<(bool,)> {
-    |bar| {
-    //~^ NOTE: found signature of `fn(bool) -> _`
+    //~^ ERROR: type mismatch in generator arguments [E0631]
     //~| ERROR: type mismatch in generator arguments [E0631]
     //~| NOTE: expected signature of `fn((bool,)) -> _`
+    //~| NOTE: expected signature of `fn((bool,)) -> _`
+    //~| NOTE: in this expansion of desugaring of `impl Trait`
+    |bar| {
+        //~^ NOTE: found signature of `fn(bool) -> _`
+        //~| NOTE: found signature of `fn(bool) -> _`
         if bar {
             yield bar;
         }
diff --git a/src/test/ui/generator/issue-88653.stderr b/src/test/ui/generator/issue-88653.stderr
index eaa90a8e60a..25357411ce1 100644
--- a/src/test/ui/generator/issue-88653.stderr
+++ b/src/test/ui/generator/issue-88653.stderr
@@ -1,12 +1,28 @@
 error[E0631]: type mismatch in generator arguments
-  --> $DIR/issue-88653.rs:9:5
+  --> $DIR/issue-88653.rs:8:22
    |
+LL | fn foo(bar: bool) -> impl Generator<(bool,)> {
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^ expected signature of `fn((bool,)) -> _`
+...
 LL |     |bar| {
-   |     ^^^^^
-   |     |
-   |     expected signature of `fn((bool,)) -> _`
-   |     found signature of `fn(bool) -> _`
+   |     ----- found signature of `fn(bool) -> _`
 
-error: aborting due to previous error
+error[E0631]: type mismatch in generator arguments
+  --> $DIR/issue-88653.rs:8:46
+   |
+LL |   fn foo(bar: bool) -> impl Generator<(bool,)> {
+   |  ______________________________________________^
+LL | |
+LL | |
+LL | |
+...  |
+LL | |     |bar| {
+   | |     ----- found signature of `fn(bool) -> _`
+...  |
+LL | |     }
+LL | | }
+   | |_^ expected signature of `fn((bool,)) -> _`
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0631`.
diff --git a/src/test/ui/generator/type-mismatch-signature-deduction.rs b/src/test/ui/generator/type-mismatch-signature-deduction.rs
index d1b16b6e10d..77b830783c3 100644
--- a/src/test/ui/generator/type-mismatch-signature-deduction.rs
+++ b/src/test/ui/generator/type-mismatch-signature-deduction.rs
@@ -3,7 +3,9 @@
 use std::ops::Generator;
 
 fn foo() -> impl Generator<Return = i32> {
-    || { //~ ERROR type mismatch
+    //~^ ERROR type mismatch
+    //~| ERROR type mismatch
+    || {
         if false {
             return Ok(6);
         }
diff --git a/src/test/ui/generator/type-mismatch-signature-deduction.stderr b/src/test/ui/generator/type-mismatch-signature-deduction.stderr
index 3e78e5b53ba..6369e7ec4c7 100644
--- a/src/test/ui/generator/type-mismatch-signature-deduction.stderr
+++ b/src/test/ui/generator/type-mismatch-signature-deduction.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/type-mismatch-signature-deduction.rs:13:9
+  --> $DIR/type-mismatch-signature-deduction.rs:15:9
    |
 LL |         5
    |         ^ expected enum `Result`, found integer
@@ -7,27 +7,37 @@ LL |         5
    = note: expected type `Result<{integer}, _>`
               found type `{integer}`
 note: return type inferred to be `Result<{integer}, _>` here
-  --> $DIR/type-mismatch-signature-deduction.rs:8:20
+  --> $DIR/type-mismatch-signature-deduction.rs:10:20
    |
 LL |             return Ok(6);
    |                    ^^^^^
 
-error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature-deduction.rs:6:5: 14:6] as Generator>::Return == i32`
-  --> $DIR/type-mismatch-signature-deduction.rs:6:5
+error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature-deduction.rs:8:5: 16:6] as Generator>::Return == i32`
+  --> $DIR/type-mismatch-signature-deduction.rs:5:13
    |
-LL | /     || {
-LL | |         if false {
-LL | |             return Ok(6);
-LL | |         }
-...  |
-LL | |         5
-LL | |     }
-   | |_____^ expected enum `Result`, found `i32`
+LL | fn foo() -> impl Generator<Return = i32> {
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Result`, found `i32`
    |
    = note: expected enum `Result<{integer}, _>`
               found type `i32`
 
-error: aborting due to 2 previous errors
+error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature-deduction.rs:8:5: 16:6] as Generator>::Return == i32`
+  --> $DIR/type-mismatch-signature-deduction.rs:5:42
+   |
+LL |   fn foo() -> impl Generator<Return = i32> {
+   |  __________________________________________^
+LL | |
+LL | |
+LL | |     || {
+...  |
+LL | |     }
+LL | | }
+   | |_^ expected enum `Result`, found `i32`
+   |
+   = note: expected enum `Result<{integer}, _>`
+              found type `i32`
+
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0271, E0308.
 For more information about an error, try `rustc --explain E0271`.
diff --git a/src/test/ui/generic-associated-types/issue-92096.migrate.stderr b/src/test/ui/generic-associated-types/issue-92096.migrate.stderr
index f8c89829e16..72ade5774d7 100644
--- a/src/test/ui/generic-associated-types/issue-92096.migrate.stderr
+++ b/src/test/ui/generic-associated-types/issue-92096.migrate.stderr
@@ -1,20 +1,18 @@
 error[E0311]: the parameter type `C` may not live long enough
-  --> $DIR/issue-92096.rs:24:5
+  --> $DIR/issue-92096.rs:20:33
    |
 LL | fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send
-   |                 - help: consider adding an explicit lifetime bound...: `C: 'a`
-...
-LL |     async move { c.connect().await }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds
+   |                 -               ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds
+   |                 |
+   |                 help: consider adding an explicit lifetime bound...: `C: 'a`
 
 error[E0311]: the parameter type `C` may not live long enough
-  --> $DIR/issue-92096.rs:24:5
+  --> $DIR/issue-92096.rs:20:33
    |
 LL | fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send
-   |                 - help: consider adding an explicit lifetime bound...: `C: 'a`
-...
-LL |     async move { c.connect().await }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds
+   |                 -               ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds
+   |                 |
+   |                 help: consider adding an explicit lifetime bound...: `C: 'a`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/generic-associated-types/issue-92096.rs b/src/test/ui/generic-associated-types/issue-92096.rs
index 2bc1af5506f..066132a5d98 100644
--- a/src/test/ui/generic-associated-types/issue-92096.rs
+++ b/src/test/ui/generic-associated-types/issue-92096.rs
@@ -18,12 +18,12 @@ trait Client {
 }
 
 fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send
+//[migrate]~^ ERROR the parameter
+//[migrate]~| ERROR the parameter
 where
     C: Client + Send + Sync,
 {
     async move { c.connect().await }
-    //[migrate]~^ ERROR the parameter
-    //[migrate]~| ERROR the parameter
 }
 
 fn main() {}
diff --git a/src/test/ui/impl-trait/bound-normalization-fail.rs b/src/test/ui/impl-trait/bound-normalization-fail.rs
index 20ddad0547e..9f962fa9bba 100644
--- a/src/test/ui/impl-trait/bound-normalization-fail.rs
+++ b/src/test/ui/impl-trait/bound-normalization-fail.rs
@@ -23,8 +23,9 @@ mod impl_trait {
 
     /// `T::Assoc` can't be normalized any further here.
     fn foo_fail<T: Trait>() -> impl FooLike<Output = T::Assoc> {
-        Foo(())
         //~^ ERROR: type mismatch
+        //~| ERROR: type mismatch
+        Foo(())
     }
 }
 
@@ -40,8 +41,9 @@ mod lifetimes {
     /// Missing bound constraining `Assoc`, `T::Assoc` can't be normalized further.
     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
         //~^ ERROR `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
+        //~| ERROR: type mismatch
+        //~| ERROR: type mismatch
         Foo(())
-        //~^ ERROR: type mismatch
     }
 }
 
diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr
index 01fb853e1d1..0344f416eb7 100644
--- a/src/test/ui/impl-trait/bound-normalization-fail.stderr
+++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr
@@ -1,8 +1,31 @@
 error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc`
-  --> $DIR/bound-normalization-fail.rs:26:9
+  --> $DIR/bound-normalization-fail.rs:25:32
    |
-LL |         Foo(())
-   |         ^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc`
+LL |     fn foo_fail<T: Trait>() -> impl FooLike<Output = T::Assoc> {
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc`
+   |
+note: expected this to be `()`
+  --> $DIR/bound-normalization-fail.rs:14:19
+   |
+LL |     type Output = T;
+   |                   ^
+   = note:    expected unit type `()`
+           found associated type `<T as impl_trait::Trait>::Assoc`
+help: consider constraining the associated type `<T as impl_trait::Trait>::Assoc` to `()`
+   |
+LL |     fn foo_fail<T: Trait<Assoc = ()>>() -> impl FooLike<Output = T::Assoc> {
+   |                         ++++++++++++
+
+error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc`
+  --> $DIR/bound-normalization-fail.rs:25:64
+   |
+LL |       fn foo_fail<T: Trait>() -> impl FooLike<Output = T::Assoc> {
+   |  ________________________________________________________________^
+LL | |
+LL | |
+LL | |         Foo(())
+LL | |     }
+   | |_____^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc`
    |
 note: expected this to be `()`
   --> $DIR/bound-normalization-fail.rs:14:19
@@ -17,16 +40,16 @@ LL |     fn foo_fail<T: Trait<Assoc = ()>>() -> impl FooLike<Output = T::Assoc>
    |                         ++++++++++++
 
 error[E0760]: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
-  --> $DIR/bound-normalization-fail.rs:41:41
+  --> $DIR/bound-normalization-fail.rs:42:41
    |
 LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc`
-  --> $DIR/bound-normalization-fail.rs:43:9
+  --> $DIR/bound-normalization-fail.rs:42:41
    |
-LL |         Foo(())
-   |         ^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc`
+LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc`
    |
 note: expected this to be `()`
   --> $DIR/bound-normalization-fail.rs:14:19
@@ -40,7 +63,31 @@ help: consider constraining the associated type `<T as lifetimes::Trait<'static>
 LL |     fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike<Output = T::Assoc> {
    |                                 ++++++++++++
 
-error: aborting due to 3 previous errors
+error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc`
+  --> $DIR/bound-normalization-fail.rs:42:73
+   |
+LL |       fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
+   |  _________________________________________________________________________^
+LL | |
+LL | |
+LL | |
+LL | |         Foo(())
+LL | |     }
+   | |_____^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc`
+   |
+note: expected this to be `()`
+  --> $DIR/bound-normalization-fail.rs:14:19
+   |
+LL |     type Output = T;
+   |                   ^
+   = note:    expected unit type `()`
+           found associated type `<T as lifetimes::Trait<'static>>::Assoc`
+help: consider constraining the associated type `<T as lifetimes::Trait<'static>>::Assoc` to `()`
+   |
+LL |     fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike<Output = T::Assoc> {
+   |                                 ++++++++++++
+
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0271, E0760.
 For more information about an error, try `rustc --explain E0271`.
diff --git a/src/test/ui/impl-trait/cross-return-site-inference.rs b/src/test/ui/impl-trait/cross-return-site-inference.rs
new file mode 100644
index 00000000000..ceb8414650f
--- /dev/null
+++ b/src/test/ui/impl-trait/cross-return-site-inference.rs
@@ -0,0 +1,45 @@
+// edition:2021
+
+fn foo(b: bool) -> impl std::fmt::Debug {
+    if b {
+        return vec![42]
+    }
+    [].into_iter().collect()
+}
+
+fn bar(b: bool) -> impl std::fmt::Debug {
+    if b {
+        return [].into_iter().collect()
+    }
+    vec![42]
+}
+
+fn bak(b: bool) -> impl std::fmt::Debug {
+    if b {
+        return std::iter::empty().collect()
+    }
+    vec![42]
+}
+
+fn baa(b: bool) -> impl std::fmt::Debug {
+    if b {
+        return [42].into_iter().collect()
+    }
+    vec![]
+}
+
+fn muh() -> Result<(), impl std::fmt::Debug> {
+    Err("whoops")?; //~ ERROR `?` couldn't convert the error to `impl Debug`
+    Ok(())
+}
+
+fn muh2() -> Result<(), impl std::fmt::Debug> {
+    return Err(From::from("foo")); //~ ERROR the trait bound `impl Debug: From<&str>` is not satisfied
+    Ok(())
+}
+
+fn muh3() -> Result<(), impl std::fmt::Debug> {
+    Err(From::from("foo")) //~ ERROR the trait bound `impl Debug: From<&str>` is not satisfied
+}
+
+fn main() {}
\ No newline at end of file
diff --git a/src/test/ui/impl-trait/cross-return-site-inference.stderr b/src/test/ui/impl-trait/cross-return-site-inference.stderr
new file mode 100644
index 00000000000..06afb938c5f
--- /dev/null
+++ b/src/test/ui/impl-trait/cross-return-site-inference.stderr
@@ -0,0 +1,26 @@
+error[E0277]: `?` couldn't convert the error to `impl Debug`
+  --> $DIR/cross-return-site-inference.rs:32:18
+   |
+LL | fn muh() -> Result<(), impl std::fmt::Debug> {
+   |             -------------------------------- expected `impl Debug` because of this
+LL |     Err("whoops")?;
+   |                  ^ the trait `From<&str>` is not implemented for `impl Debug`
+   |
+   = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
+   = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, &str>>` for `Result<(), impl Debug>`
+
+error[E0277]: the trait bound `impl Debug: From<&str>` is not satisfied
+  --> $DIR/cross-return-site-inference.rs:37:16
+   |
+LL |     return Err(From::from("foo"));
+   |                ^^^^^^^^^^ the trait `From<&str>` is not implemented for `impl Debug`
+
+error[E0277]: the trait bound `impl Debug: From<&str>` is not satisfied
+  --> $DIR/cross-return-site-inference.rs:42:9
+   |
+LL |     Err(From::from("foo"))
+   |         ^^^^^^^^^^ the trait `From<&str>` is not implemented for `impl Debug`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/divergence.rs b/src/test/ui/impl-trait/divergence.rs
new file mode 100644
index 00000000000..211f7972dbc
--- /dev/null
+++ b/src/test/ui/impl-trait/divergence.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+fn foo() -> impl MyTrait {
+    panic!();
+    MyStruct
+}
+
+struct MyStruct;
+trait MyTrait {}
+
+impl MyTrait for MyStruct {}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr
index 185a3f53f65..804ccbcc6c0 100644
--- a/src/test/ui/impl-trait/equality.stderr
+++ b/src/test/ui/impl-trait/equality.stderr
@@ -12,13 +12,10 @@ error[E0308]: mismatched types
   --> $DIR/equality.rs:15:5
    |
 LL | fn two(x: bool) -> impl Foo {
-   |                    -------- the expected opaque type
+   |                    -------- expected `_` because of return type
 ...
 LL |     0_u32
    |     ^^^^^ expected `i32`, found `u32`
-   |
-   = note: expected opaque type `impl Foo`
-                     found type `u32`
 
 error[E0277]: cannot add `impl Foo` to `u32`
   --> $DIR/equality.rs:24:11
diff --git a/src/test/ui/impl-trait/issues/issue-70877.rs b/src/test/ui/impl-trait/issues/issue-70877.rs
index 1a86fa00ed1..9cbe33aef5b 100644
--- a/src/test/ui/impl-trait/issues/issue-70877.rs
+++ b/src/test/ui/impl-trait/issues/issue-70877.rs
@@ -28,7 +28,7 @@ fn ham() -> Foo {
 fn oof() -> impl std::fmt::Debug {
     let mut bar = ham();
     let func = bar.next().unwrap();
-    return func(&"oof"); //~ ERROR opaque type's hidden type cannot be another opaque type
+    return func(&"oof"); //~^^^ ERROR opaque type's hidden type cannot be another opaque type
 }
 
 fn main() {
diff --git a/src/test/ui/impl-trait/issues/issue-70877.stderr b/src/test/ui/impl-trait/issues/issue-70877.stderr
index 7cbd58bdabf..2610a198186 100644
--- a/src/test/ui/impl-trait/issues/issue-70877.stderr
+++ b/src/test/ui/impl-trait/issues/issue-70877.stderr
@@ -13,10 +13,15 @@ LL |         Some(Box::new(quux))
               found enum `Option<Box<for<'r> fn(&'r (dyn ToString + 'r)) -> FooRet {quux}>>`
 
 error: opaque type's hidden type cannot be another opaque type from the same scope
-  --> $DIR/issue-70877.rs:31:12
+  --> $DIR/issue-70877.rs:28:34
    |
-LL |     return func(&"oof");
-   |            ^^^^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope
+LL |   fn oof() -> impl std::fmt::Debug {
+   |  __________________________________^
+LL | |     let mut bar = ham();
+LL | |     let func = bar.next().unwrap();
+LL | |     return func(&"oof");
+LL | | }
+   | |_^ one of the two opaque types used here has to be outside its defining scope
    |
 note: opaque type whose hidden type is being assigned
   --> $DIR/issue-70877.rs:28:13
diff --git a/src/test/ui/impl-trait/issues/issue-88236-2.rs b/src/test/ui/impl-trait/issues/issue-88236-2.rs
index f89ab7fbd36..af26a1f54c4 100644
--- a/src/test/ui/impl-trait/issues/issue-88236-2.rs
+++ b/src/test/ui/impl-trait/issues/issue-88236-2.rs
@@ -14,10 +14,10 @@ impl<'a> Hrtb<'a> for &'a () {
 
 fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {}
 fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
-    &() //~ ERROR implementation of `Hrtb` is not general enough
+    &() //~^ ERROR implementation of `Hrtb` is not general enough
 }
 fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
-    x //~ ERROR implementation of `Hrtb` is not general enough
+    x //~^ ERROR implementation of `Hrtb` is not general enough
 }
 
 fn main() {}
diff --git a/src/test/ui/impl-trait/issues/issue-88236-2.stderr b/src/test/ui/impl-trait/issues/issue-88236-2.stderr
index 95c4a528036..45fadcab3f2 100644
--- a/src/test/ui/impl-trait/issues/issue-88236-2.stderr
+++ b/src/test/ui/impl-trait/issues/issue-88236-2.stderr
@@ -1,17 +1,20 @@
 error: implementation of `Hrtb` is not general enough
-  --> $DIR/issue-88236-2.rs:17:5
+  --> $DIR/issue-88236-2.rs:16:38
    |
-LL |     &()
-   |     ^^^ implementation of `Hrtb` is not general enough
+LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
+   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Hrtb` is not general enough
    |
    = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`...
    = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1`
 
 error: implementation of `Hrtb` is not general enough
-  --> $DIR/issue-88236-2.rs:20:5
+  --> $DIR/issue-88236-2.rs:19:82
    |
-LL |     x
-   |     ^ implementation of `Hrtb` is not general enough
+LL |   fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {
+   |  __________________________________________________________________________________^
+LL | |     x
+LL | | }
+   | |_^ implementation of `Hrtb` is not general enough
    |
    = note: `&()` must implement `Hrtb<'0>`, for any lifetime `'0`...
    = note: ...but `Hrtb<'_>` is actually implemented for the type `&()`
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
index eb38f84d4af..9589b69491e 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
@@ -80,7 +80,7 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32
    |                                                                              ++++
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:39:5
+  --> $DIR/must_outlive_least_region_or_bound.rs:41:5
    |
 LL |     x
    |     ^
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
index 02ea0255912..baa42da6446 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
@@ -36,8 +36,9 @@ fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
 }
 
 fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
-    x
     //~^ ERROR the parameter type `T` may not live long enough
+    //~| ERROR the parameter type `T` may not live long enough
+    x
 }
 
 fn main() {}
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
index 77ba0bf9087..1272adb35e9 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
@@ -28,10 +28,15 @@ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'sta
   --> $DIR/must_outlive_least_region_or_bound.rs:9:46
    |
 LL | fn elided2(x: &i32) -> impl Copy + 'static { x }
-   |               ----                           ^ ...is used and required to live as long as `'static` here
+   |               ----                           ^ ...is used here...
    |               |
    |               this data with an anonymous lifetime `'_`...
    |
+note: ...and is required to live as long as `'static` here
+  --> $DIR/must_outlive_least_region_or_bound.rs:9:24
+   |
+LL | fn elided2(x: &i32) -> impl Copy + 'static { x }
+   |                        ^^^^^^^^^^^^^^^^^^^
 help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x`
    |
 LL | fn elided2(x: &i32) -> impl Copy + '_ { x }
@@ -45,10 +50,15 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime
   --> $DIR/must_outlive_least_region_or_bound.rs:11:55
    |
 LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
-   |                     -------                           ^ ...is used and required to live as long as `'static` here
+   |                     -------                           ^ ...is used here...
    |                     |
    |                     this data with lifetime `'a`...
    |
+note: ...and is required to live as long as `'static` here
+  --> $DIR/must_outlive_least_region_or_bound.rs:11:33
+   |
+LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
+   |                                 ^^^^^^^^^^^^^^^^^^^
 help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x`
    |
 LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x }
@@ -59,10 +69,10 @@ LL | fn explicit2<'a>(x: &'static i32) -> impl Copy + 'static { x }
    |                     ~~~~~~~~~~~~
 
 error[E0621]: explicit lifetime required in the type of `x`
-  --> $DIR/must_outlive_least_region_or_bound.rs:13:41
+  --> $DIR/must_outlive_least_region_or_bound.rs:13:24
    |
 LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x }
-   |               ----                      ^ lifetime `'a` required
+   |               ----     ^^^^^^^^^^^^^^ lifetime `'a` required
    |               |
    |               help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
 
@@ -85,8 +95,13 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime
   --> $DIR/must_outlive_least_region_or_bound.rs:29:69
    |
 LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
-   |                      ------- this data with lifetime `'a`...        ^ ...is used and required to live as long as `'static` here
+   |                      ------- this data with lifetime `'a`...        ^ ...is used here...
    |
+note: ...and is required to live as long as `'static` here
+  --> $DIR/must_outlive_least_region_or_bound.rs:29:34
+   |
+LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
+   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x`
    |
 LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x }
@@ -110,12 +125,25 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32
    |                                                                              ++++
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:39:5
+  --> $DIR/must_outlive_least_region_or_bound.rs:38:51
    |
 LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
-   |                                 -- help: consider adding an explicit lifetime bound...: `T: 'static +`
-LL |     x
-   |     ^ ...so that the type `T` will meet its required lifetime bounds
+   |                                 --                ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+   |                                 |
+   |                                 help: consider adding an explicit lifetime bound...: `T: 'static +`
+
+error[E0310]: the parameter type `T` may not live long enough
+  --> $DIR/must_outlive_least_region_or_bound.rs:38:72
+   |
+LL |   fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
+   |  _________________________________--_____________________________________^
+   | |                                 |
+   | |                                 help: consider adding an explicit lifetime bound...: `T: 'static +`
+LL | |
+LL | |
+LL | |     x
+LL | | }
+   | |_^ ...so that the type `T` will meet its required lifetime bounds
 
 error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/must_outlive_least_region_or_bound.rs:16:50
@@ -203,7 +231,7 @@ help: alternatively, add an explicit `'static` bound to this reference
 LL | fn explicit4<'a>(x: &'static i32) -> Box<dyn Debug + 'static> { Box::new(x) }
    |                     ~~~~~~~~~~~~
 
-error: aborting due to 13 previous errors
+error: aborting due to 14 previous errors
 
 Some errors have detailed explanations: E0310, E0621, E0700, E0759.
 For more information about an error, try `rustc --explain E0310`.
diff --git a/src/test/ui/impl-trait/nested_impl_trait.stderr b/src/test/ui/impl-trait/nested_impl_trait.stderr
index a10e4ec3182..26b48c7cdf7 100644
--- a/src/test/ui/impl-trait/nested_impl_trait.stderr
+++ b/src/test/ui/impl-trait/nested_impl_trait.stderr
@@ -47,18 +47,18 @@ LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
    |                                          ^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
-  --> $DIR/nested_impl_trait.rs:5:70
+  --> $DIR/nested_impl_trait.rs:5:46
    |
 LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
-   |                                                                      ^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
+   |                                              ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
    |
    = note: required because of the requirements on the impl of `Into<impl Debug>` for `impl Into<u32>`
 
 error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
-  --> $DIR/nested_impl_trait.rs:18:58
+  --> $DIR/nested_impl_trait.rs:18:34
    |
 LL |     fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
-   |                                                          ^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
+   |                                  ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
    |
    = note: required because of the requirements on the impl of `Into<impl Debug>` for `impl Into<u32>`
 
diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr
index b2f7166f0ae..5ca01a59376 100644
--- a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr
+++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr
@@ -2,25 +2,19 @@ error[E0308]: mismatched types
   --> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:36:5
    |
 LL | fn can() -> impl NotObjectSafe {
-   |             ------------------ the expected opaque type
+   |             ------------------ expected `_` because of return type
 ...
 LL |     B
    |     ^ expected struct `A`, found struct `B`
-   |
-   = note: expected opaque type `impl NotObjectSafe`
-                   found struct `B`
 
 error[E0308]: mismatched types
   --> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:43:5
    |
 LL | fn cat() -> impl ObjectSafe {
-   |             --------------- the expected opaque type
+   |             --------------- expected `_` because of return type
 ...
 LL |     B
    |     ^ expected struct `A`, found struct `B`
-   |
-   = note: expected opaque type `impl ObjectSafe`
-                   found struct `B`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs
index 9f9a6c784e6..fa7664a83ee 100644
--- a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs
+++ b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs
@@ -14,10 +14,10 @@ fn bar() -> impl std::fmt::Display {
 }
 
 fn baz() -> impl std::fmt::Display {
-    if false { //~ ERROR mismatched types
+    if false {
         return 0i32;
     } else {
-        1u32
+        1u32 //~ ERROR mismatched types
     }
 }
 
@@ -30,9 +30,9 @@ fn qux() -> impl std::fmt::Display {
 }
 
 fn bat() -> impl std::fmt::Display {
-    match 13 { //~ ERROR mismatched types
+    match 13 {
         0 => return 0i32,
-        _ => 1u32,
+        _ => 1u32, //~ ERROR mismatched types
     }
 }
 
@@ -45,12 +45,12 @@ fn can() -> impl std::fmt::Display {
 }
 
 fn cat() -> impl std::fmt::Display {
-    match 13 { //~ ERROR mismatched types
+    match 13 {
         0 => {
             return 0i32;
         }
         _ => {
-            1u32
+            1u32 //~ ERROR mismatched types
         }
     }
 }
diff --git a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr
index db0d446e559..0c595f441ba 100644
--- a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr
+++ b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr
@@ -2,40 +2,28 @@ error[E0308]: mismatched types
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:5:5
    |
 LL | fn foo() -> impl std::fmt::Display {
-   |             ---------------------- the expected opaque type
+   |             ---------------------- expected `_` because of return type
 ...
 LL |     1u32
    |     ^^^^ expected `i32`, found `u32`
-   |
-   = note: expected opaque type `impl std::fmt::Display`
-                     found type `u32`
 
 error[E0308]: mismatched types
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:12:16
    |
 LL | fn bar() -> impl std::fmt::Display {
-   |             ---------------------- the expected opaque type
+   |             ---------------------- expected `_` because of return type
 ...
 LL |         return 1u32;
    |                ^^^^ expected `i32`, found `u32`
-   |
-   = note: expected opaque type `impl std::fmt::Display`
-                     found type `u32`
 
 error[E0308]: mismatched types
-  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:17:5
+  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:20:9
    |
-LL |   fn baz() -> impl std::fmt::Display {
-   |               ---------------------- the expected opaque type
-LL | /     if false {
-LL | |         return 0i32;
-LL | |     } else {
-LL | |         1u32
-LL | |     }
-   | |_____^ expected `i32`, found `u32`
-   |
-   = note: expected opaque type `impl std::fmt::Display`
-                     found type `u32`
+LL | fn baz() -> impl std::fmt::Display {
+   |             ---------------------- expected `_` because of return type
+...
+LL |         1u32
+   |         ^^^^ expected `i32`, found `u32`
 
 error[E0308]: `if` and `else` have incompatible types
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:28:9
@@ -48,63 +36,36 @@ LL | |         1u32
    | |         ^^^^ expected `i32`, found `u32`
 LL | |     }
    | |_____- `if` and `else` have incompatible types
-   |
-help: you could change the return type to be a boxed trait object
-   |
-LL | fn qux() -> Box<dyn std::fmt::Display> {
-   |             ~~~~~~~                  +
-help: if you change the return type to expect trait objects, box the returned expressions
-   |
-LL ~         Box::new(0i32)
-LL |     } else {
-LL ~         Box::new(1u32)
-   |
 
 error[E0308]: mismatched types
-  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:33:5
+  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:35:14
    |
-LL |   fn bat() -> impl std::fmt::Display {
-   |               ---------------------- the expected opaque type
-LL | /     match 13 {
-LL | |         0 => return 0i32,
-LL | |         _ => 1u32,
-LL | |     }
-   | |_____^ expected `i32`, found `u32`
-   |
-   = note: expected opaque type `impl std::fmt::Display`
-                     found type `u32`
+LL | fn bat() -> impl std::fmt::Display {
+   |             ---------------------- expected `_` because of return type
+...
+LL |         _ => 1u32,
+   |              ^^^^ expected `i32`, found `u32`
 
 error[E0308]: mismatched types
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:40:5
    |
 LL |   fn can() -> impl std::fmt::Display {
-   |               ---------------------- the expected opaque type
+   |               ---------------------- expected `_` because of return type
 LL | /     match 13 {
 LL | |         0 => return 0i32,
 LL | |         1 => 1u32,
 LL | |         _ => 2u32,
 LL | |     }
    | |_____^ expected `i32`, found `u32`
-   |
-   = note: expected opaque type `impl std::fmt::Display`
-                     found type `u32`
 
 error[E0308]: mismatched types
-  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:48:5
+  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:53:13
    |
-LL |   fn cat() -> impl std::fmt::Display {
-   |               ---------------------- the expected opaque type
-LL | /     match 13 {
-LL | |         0 => {
-LL | |             return 0i32;
-LL | |         }
-...  |
-LL | |         }
-LL | |     }
-   | |_____^ expected `i32`, found `u32`
-   |
-   = note: expected opaque type `impl std::fmt::Display`
-                     found type `u32`
+LL | fn cat() -> impl std::fmt::Display {
+   |             ---------------------- expected `_` because of return type
+...
+LL |             1u32
+   |             ^^^^ expected `i32`, found `u32`
 
 error[E0308]: `match` arms have incompatible types
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:61:14
diff --git a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs
index 2e7cb21592c..b4fd6b3e743 100644
--- a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs
+++ b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs
@@ -11,8 +11,8 @@ pub trait Test {}
 impl<T> Test for T where T: Super<Assoc = ()> {}
 
 fn test() -> impl Test {
-    ()
     //~^ERROR type mismatch resolving `<() as Super>::Assoc == ()`
+    ()
 }
 
 fn main() {
diff --git a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr
index 5ef1e9abef6..ade0dfa1bb3 100644
--- a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr
+++ b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr
@@ -1,8 +1,8 @@
 error[E0271]: type mismatch resolving `<() as Super>::Assoc == ()`
-  --> $DIR/projection-mismatch-in-impl-where-clause.rs:14:5
+  --> $DIR/projection-mismatch-in-impl-where-clause.rs:13:14
    |
-LL |     ()
-   |     ^^ type mismatch resolving `<() as Super>::Assoc == ()`
+LL | fn test() -> impl Test {
+   |              ^^^^^^^^^ type mismatch resolving `<() as Super>::Assoc == ()`
    |
 note: expected this to be `u8`
   --> $DIR/projection-mismatch-in-impl-where-clause.rs:6:18
diff --git a/src/test/ui/impl-trait/question_mark.rs b/src/test/ui/impl-trait/question_mark.rs
index 211f7972dbc..495bf5c1d64 100644
--- a/src/test/ui/impl-trait/question_mark.rs
+++ b/src/test/ui/impl-trait/question_mark.rs
@@ -1,13 +1,30 @@
 // check-pass
 
-fn foo() -> impl MyTrait {
-    panic!();
-    MyStruct
+use std::fmt::Debug;
+
+#[derive(Debug)]
+pub struct Target;
+
+#[derive(Debug)]
+pub struct Source;
+impl From<Source> for Target {
+    fn from(_: Source) -> Self {
+        Self
+    }
 }
 
-struct MyStruct;
-trait MyTrait {}
+fn maybe_source() -> Result<(), Source> {
+    todo!()
+}
 
-impl MyTrait for MyStruct {}
+pub fn typaram() -> Result<(), impl Debug> {
+    maybe_source()?;
+    Ok::<_, Target>(())
+}
 
-fn main() {}
+pub fn direct() -> Result<(), impl Debug> {
+    maybe_source()?;
+    Err(Target)
+}
+
+fn main() {}
\ No newline at end of file
diff --git a/src/test/ui/impl-trait/type_parameters_captured.nll.stderr b/src/test/ui/impl-trait/type_parameters_captured.nll.stderr
index e0b77544d43..b1175a5952e 100644
--- a/src/test/ui/impl-trait/type_parameters_captured.nll.stderr
+++ b/src/test/ui/impl-trait/type_parameters_captured.nll.stderr
@@ -1,5 +1,5 @@
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/type_parameters_captured.rs:8:5
+  --> $DIR/type_parameters_captured.rs:10:5
    |
 LL |     x
    |     ^
diff --git a/src/test/ui/impl-trait/type_parameters_captured.rs b/src/test/ui/impl-trait/type_parameters_captured.rs
index 81ee7d3f8a5..bb9cab742a5 100644
--- a/src/test/ui/impl-trait/type_parameters_captured.rs
+++ b/src/test/ui/impl-trait/type_parameters_captured.rs
@@ -5,8 +5,9 @@ impl<T> Any for T {}
 
 // Check that type parameters are captured and not considered 'static
 fn foo<T>(x: T) -> impl Any + 'static {
-    x
     //~^ ERROR the parameter type `T` may not live long enough
+    //~| ERROR the parameter type `T` may not live long enough
+    x
 }
 
 fn main() {}
diff --git a/src/test/ui/impl-trait/type_parameters_captured.stderr b/src/test/ui/impl-trait/type_parameters_captured.stderr
index c0de4f4b4a0..c4ca34a6ed3 100644
--- a/src/test/ui/impl-trait/type_parameters_captured.stderr
+++ b/src/test/ui/impl-trait/type_parameters_captured.stderr
@@ -1,11 +1,24 @@
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/type_parameters_captured.rs:8:5
+  --> $DIR/type_parameters_captured.rs:7:20
    |
 LL | fn foo<T>(x: T) -> impl Any + 'static {
-   |        - help: consider adding an explicit lifetime bound...: `T: 'static`
-LL |     x
-   |     ^ ...so that the type `T` will meet its required lifetime bounds
+   |        -           ^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+   |        |
+   |        help: consider adding an explicit lifetime bound...: `T: 'static`
 
-error: aborting due to previous error
+error[E0310]: the parameter type `T` may not live long enough
+  --> $DIR/type_parameters_captured.rs:7:39
+   |
+LL |   fn foo<T>(x: T) -> impl Any + 'static {
+   |  ________-______________________________^
+   | |        |
+   | |        help: consider adding an explicit lifetime bound...: `T: 'static`
+LL | |
+LL | |
+LL | |     x
+LL | | }
+   | |_^ ...so that the type `T` will meet its required lifetime bounds
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0310`.
diff --git a/src/test/ui/issues-71798.rs b/src/test/ui/issues-71798.rs
index 89e07037afd..14b6c0f3581 100644
--- a/src/test/ui/issues-71798.rs
+++ b/src/test/ui/issues-71798.rs
@@ -1,6 +1,6 @@
 fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ {
-    *x
     //~^ ERROR `u32` is not a future
+    *x
 }
 
 fn main() {
diff --git a/src/test/ui/issues-71798.stderr b/src/test/ui/issues-71798.stderr
index 1efa886436e..ab72c3e41af 100644
--- a/src/test/ui/issues-71798.stderr
+++ b/src/test/ui/issues-71798.stderr
@@ -5,10 +5,10 @@ LL |     let _ = test_ref & u;
    |                        ^ not found in this scope
 
 error[E0277]: `u32` is not a future
-  --> $DIR/issues-71798.rs:2:5
+  --> $DIR/issues-71798.rs:1:25
    |
-LL |     *x
-   |     ^^ `u32` is not a future
+LL | fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ {
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `u32` is not a future
    |
    = help: the trait `Future` is not implemented for `u32`
    = note: u32 must be a future or must implement `IntoFuture` to be awaited
diff --git a/src/test/ui/lang-items/lang-item-missing-generator.stderr b/src/test/ui/lang-items/lang-item-missing-generator.stderr
index e5f26822f26..fa13bf0b127 100644
--- a/src/test/ui/lang-items/lang-item-missing-generator.stderr
+++ b/src/test/ui/lang-items/lang-item-missing-generator.stderr
@@ -1,8 +1,8 @@
 error: requires `generator` lang_item
-  --> $DIR/lang-item-missing-generator.rs:15:22
+  --> $DIR/lang-item-missing-generator.rs:15:17
    |
 LL | pub fn abc() -> impl FnOnce(f32) {
-   |                      ^^^^^^^^^^^
+   |                 ^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs
index fd49b4842a7..133679f30f8 100644
--- a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs
+++ b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs
@@ -6,8 +6,9 @@ trait Future {
 use std::error::Error;
 
 fn foo() -> impl Future<Item=(), Error=Box<dyn Error>> {
-    Ok(())
     //~^ ERROR not satisfied
+    //~| ERROR not satisfied
+    Ok(())
 }
 
 fn main() {}
diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr
index 7f8384d7eca..a3badd7b25a 100644
--- a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr
+++ b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr
@@ -1,9 +1,20 @@
 error[E0277]: the trait bound `Result<(), _>: Future` is not satisfied
-  --> $DIR/lifetime-elision-return-type-trait.rs:9:5
+  --> $DIR/lifetime-elision-return-type-trait.rs:8:13
    |
-LL |     Ok(())
-   |     ^^^^^^ the trait `Future` is not implemented for `Result<(), _>`
+LL | fn foo() -> impl Future<Item=(), Error=Box<dyn Error>> {
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Future` is not implemented for `Result<(), _>`
 
-error: aborting due to previous error
+error[E0277]: the trait bound `Result<(), _>: Future` is not satisfied
+  --> $DIR/lifetime-elision-return-type-trait.rs:8:56
+   |
+LL |   fn foo() -> impl Future<Item=(), Error=Box<dyn Error>> {
+   |  ________________________________________________________^
+LL | |
+LL | |
+LL | |     Ok(())
+LL | | }
+   | |_^ the trait `Future` is not implemented for `Result<(), _>`
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs
index e72a2d8ccc6..cad7d76c6ab 100644
--- a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs
+++ b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs
@@ -2,6 +2,7 @@ trait Bar {}
 impl Bar for u8 {}
 fn foo() -> impl Bar {
     5; //~^ ERROR the trait bound `(): Bar` is not satisfied
+    //~| ERROR the trait bound `(): Bar` is not satisfied
 }
 
 fn main() {}
diff --git a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr
index 07c1d8bccba..ba6967e78e1 100644
--- a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr
+++ b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr
@@ -1,12 +1,21 @@
+error[E0277]: the trait bound `(): Bar` is not satisfied
+  --> $DIR/impl-trait-return-trailing-semicolon.rs:3:13
+   |
+LL | fn foo() -> impl Bar {
+   |             ^^^^^^^^ the trait `Bar` is not implemented for `()`
+LL |     5;
+   |      - consider removing this semicolon
+
 error[E0277]: the trait bound `(): Bar` is not satisfied
   --> $DIR/impl-trait-return-trailing-semicolon.rs:3:22
    |
 LL |   fn foo() -> impl Bar {
    |  ______________________^
 LL | |     5;
+LL | |
 LL | | }
    | |_^ the trait `Bar` is not implemented for `()`
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggestions/issue-81098.rs b/src/test/ui/suggestions/issue-81098.rs
index a601b5866f4..7ca7380a7be 100644
--- a/src/test/ui/suggestions/issue-81098.rs
+++ b/src/test/ui/suggestions/issue-81098.rs
@@ -1,12 +1,14 @@
 // Don't suggest removing a semicolon if the last statement isn't an expression with semicolon
 // (#81098)
 fn wat() -> impl core::fmt::Display { //~ ERROR: `()` doesn't implement `std::fmt::Display`
+    //~^ ERROR: `()` doesn't implement `std::fmt::Display`
     fn why() {}
 }
 
 // Do it if the last statement is an expression with semicolon
 // (#54771)
 fn ok() -> impl core::fmt::Display { //~ ERROR: `()` doesn't implement `std::fmt::Display`
+    //~^ ERROR: `()` doesn't implement `std::fmt::Display`
     1;
 }
 
diff --git a/src/test/ui/suggestions/issue-81098.stderr b/src/test/ui/suggestions/issue-81098.stderr
index f13e653cb06..d62526442e9 100644
--- a/src/test/ui/suggestions/issue-81098.stderr
+++ b/src/test/ui/suggestions/issue-81098.stderr
@@ -1,8 +1,18 @@
+error[E0277]: `()` doesn't implement `std::fmt::Display`
+  --> $DIR/issue-81098.rs:3:13
+   |
+LL | fn wat() -> impl core::fmt::Display {
+   |             ^^^^^^^^^^^^^^^^^^^^^^^ `()` cannot be formatted with the default formatter
+   |
+   = help: the trait `std::fmt::Display` is not implemented for `()`
+   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+
 error[E0277]: `()` doesn't implement `std::fmt::Display`
   --> $DIR/issue-81098.rs:3:37
    |
 LL |   fn wat() -> impl core::fmt::Display {
    |  _____________________________________^
+LL | |
 LL | |     fn why() {}
 LL | | }
    | |_^ `()` cannot be formatted with the default formatter
@@ -11,10 +21,23 @@ LL | | }
    = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
 
 error[E0277]: `()` doesn't implement `std::fmt::Display`
-  --> $DIR/issue-81098.rs:9:36
+  --> $DIR/issue-81098.rs:10:12
+   |
+LL | fn ok() -> impl core::fmt::Display {
+   |            ^^^^^^^^^^^^^^^^^^^^^^^ `()` cannot be formatted with the default formatter
+LL |
+LL |     1;
+   |      - consider removing this semicolon
+   |
+   = help: the trait `std::fmt::Display` is not implemented for `()`
+   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+
+error[E0277]: `()` doesn't implement `std::fmt::Display`
+  --> $DIR/issue-81098.rs:10:36
    |
 LL |   fn ok() -> impl core::fmt::Display {
    |  ____________________________________^
+LL | |
 LL | |     1;
 LL | | }
    | |_^ `()` cannot be formatted with the default formatter
@@ -22,6 +45,6 @@ LL | | }
    = help: the trait `std::fmt::Display` is not implemented for `()`
    = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr
index c7f1215c8cc..a5b50634c71 100644
--- a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr
+++ b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr
@@ -7,18 +7,13 @@ LL |     fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> {
 LL |             remaining: self.0.iter(),
    |                        ------ ^^^^
    |                        |
-   |                        ...is used and required to live as long as `'static` here
+   |                        ...is used here...
    |
-note: `'static` lifetime requirement introduced by the return type
+note: ...and is required to live as long as `'static` here
   --> $DIR/trait-object-nested-in-impl-trait.rs:27:23
    |
-LL |       fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> {
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
-LL | /         Iter {
-LL | |             current: None,
-LL | |             remaining: self.0.iter(),
-LL | |         }
-   | |_________- because of this returned expression
+LL |     fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> {
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound
    |
 LL |     fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
@@ -37,18 +32,13 @@ LL |     fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
 LL |             remaining: self.0.iter(),
    |                        ------ ^^^^
    |                        |
-   |                        ...is used and required to live as long as `'static` here
+   |                        ...is used here...
    |
-note: `'static` lifetime requirement introduced by the return type
+note: ...and is required to live as long as `'static` here
   --> $DIR/trait-object-nested-in-impl-trait.rs:38:23
    |
-LL |       fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
-LL | /         Iter {
-LL | |             current: None,
-LL | |             remaining: self.0.iter(),
-LL | |         }
-   | |_________- because of this returned expression
+LL |     fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: to declare that the trait object captures data from argument `self`, you can add an explicit `'_` lifetime bound
    |
 LL |     fn iter(&self) -> impl Iterator<Item = Box<dyn Foo + '_>> + '_ {
@@ -63,18 +53,13 @@ LL |     fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
 LL |             remaining: self.0.iter(),
    |                        ------ ^^^^
    |                        |
-   |                        ...is used and required to live as long as `'static` here
+   |                        ...is used here...
    |
-note: `'static` lifetime requirement introduced by the return type
+note: ...and is required to live as long as `'static` here
   --> $DIR/trait-object-nested-in-impl-trait.rs:49:30
    |
-LL |       fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
-LL | /         Iter {
-LL | |             current: None,
-LL | |             remaining: self.0.iter(),
-LL | |         }
-   | |_________- because of this returned expression
+LL |     fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: to declare that the trait object captures data from argument `self`, you can add an explicit `'a` lifetime bound
    |
 LL |     fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo + 'a>> + 'a {
@@ -89,18 +74,13 @@ LL |     fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> {
 LL |             remaining: self.0.iter(),
    |                        ------ ^^^^
    |                        |
-   |                        ...is used and required to live as long as `'static` here
+   |                        ...is used here...
    |
-note: `'static` lifetime requirement introduced by the return type
+note: ...and is required to live as long as `'static` here
   --> $DIR/trait-object-nested-in-impl-trait.rs:60:30
    |
-LL |       fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> {
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
-LL | /         Iter {
-LL | |             current: None,
-LL | |             remaining: self.0.iter(),
-LL | |         }
-   | |_________- because of this returned expression
+LL |     fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> {
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'a` lifetime bound
    |
 LL |     fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs
index 784a6c75886..314e5362a8f 100644
--- a/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs
@@ -10,9 +10,10 @@ trait Foo<A> { }
 impl Foo<()> for () { }
 
 fn foo() -> impl Foo<FooX> {
+    //~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied
+    //~| ERROR: the trait bound `(): Foo<FooX>` is not satisfied
     // FIXME(type-alias-impl-trait): We could probably make this work.
     ()
-    //~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied
 }
 
 fn main() { }
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr
index 9472cac6355..eb72e887691 100644
--- a/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr
@@ -1,12 +1,27 @@
 error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied
-  --> $DIR/nested-tait-inference.rs:14:5
+  --> $DIR/nested-tait-inference.rs:12:13
    |
-LL |     ()
-   |     ^^ the trait `Foo<FooX>` is not implemented for `()`
+LL | fn foo() -> impl Foo<FooX> {
+   |             ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()`
    |
    = help: the following implementations were found:
              <() as Foo<()>>
 
-error: aborting due to previous error
+error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied
+  --> $DIR/nested-tait-inference.rs:12:28
+   |
+LL |   fn foo() -> impl Foo<FooX> {
+   |  ____________________________^
+LL | |
+LL | |
+LL | |     // FIXME(type-alias-impl-trait): We could probably make this work.
+LL | |     ()
+LL | | }
+   | |_^ the trait `Foo<FooX>` is not implemented for `()`
+   |
+   = help: the following implementations were found:
+             <() as Foo<()>>
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs
index 00bd44c493c..4dc30d9257b 100644
--- a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs
@@ -11,8 +11,9 @@ impl Foo<()> for () {}
 impl Foo<u32> for () {}
 
 fn foo() -> impl Foo<FooX> {
-    ()
     //~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied
+    //~| ERROR: the trait bound `(): Foo<FooX>` is not satisfied
+    ()
 }
 
 fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr
index ec1b4642d08..1372a018667 100644
--- a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr
@@ -1,13 +1,28 @@
 error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied
-  --> $DIR/nested-tait-inference2.rs:14:5
+  --> $DIR/nested-tait-inference2.rs:13:13
    |
-LL |     ()
-   |     ^^ the trait `Foo<FooX>` is not implemented for `()`
+LL | fn foo() -> impl Foo<FooX> {
+   |             ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()`
    |
    = help: the following implementations were found:
              <() as Foo<()>>
              <() as Foo<u32>>
 
-error: aborting due to previous error
+error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied
+  --> $DIR/nested-tait-inference2.rs:13:28
+   |
+LL |   fn foo() -> impl Foo<FooX> {
+   |  ____________________________^
+LL | |
+LL | |
+LL | |     ()
+LL | | }
+   | |_^ the trait `Foo<FooX>` is not implemented for `()`
+   |
+   = help: the following implementations were found:
+             <() as Foo<()>>
+             <() as Foo<u32>>
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.