about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-01-26 14:47:03 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-02-02 15:40:11 +0000
commit38f50d1ecb2adf9f9e6305b22cdee96bd65f9cbe (patch)
treedc6c1a79606c3f72d01698198e02466c676f6242
parenta745797142f932877695a0a3cd1b452ab67e59df (diff)
downloadrust-38f50d1ecb2adf9f9e6305b22cdee96bd65f9cbe.tar.gz
rust-38f50d1ecb2adf9f9e6305b22cdee96bd65f9cbe.zip
Eagerly merge hidden types.
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs3
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs46
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/table.rs21
-rw-r--r--compiler/rustc_infer/src/infer/undo_log.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs4
-rw-r--r--src/test/ui/impl-trait/equality.stderr9
-rw-r--r--src/test/ui/impl-trait/issue-72911.rs1
-rw-r--r--src/test/ui/impl-trait/issue-72911.stderr10
-rw-r--r--src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr4
-rw-r--r--src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr4
-rw-r--r--src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr18
-rw-r--r--src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr42
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-63279.rs1
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-63279.stderr16
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-74280.stderr8
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr11
17 files changed, 125 insertions, 79 deletions
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index 20ccad26e89..a86471affaa 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -502,7 +502,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
             let opaque = self.tcx.mk_opaque(key.def_id, substs);
             for &ty in tys {
                 let ty = substitute_value(self.tcx, &result_subst, ty);
-                obligations.extend(self.handle_opaque_type(opaque, ty, cause, param_env)?);
+                obligations
+                    .extend(self.handle_opaque_type(opaque, ty, cause, param_env)?.obligations);
             }
         }
 
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index ff636616db4..cf57270df29 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -1,5 +1,5 @@
 use crate::infer::{InferCtxt, InferOk};
-use crate::traits::{self, PredicateObligation, PredicateObligations};
+use crate::traits::{self, PredicateObligation};
 use hir::def_id::{DefId, LocalDefId};
 use hir::OpaqueTyOrigin;
 use rustc_data_structures::sync::Lrc;
@@ -20,6 +20,8 @@ mod table;
 
 pub use table::{OpaqueTypeStorage, OpaqueTypeTable};
 
+use super::InferResult;
+
 /// Information about the opaque types whose values we
 /// are inferring in this function (these are the `impl Trait` that
 /// appear in the return type).
@@ -152,11 +154,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         opaque: Ty<'tcx>,
         cause: ObligationCause<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
-    ) -> Option<InferOk<'tcx, Ty<'tcx>>> {
-        let mut obligations = vec![];
-        let value = Instantiator { infcx: self, cause, param_env, obligations: &mut obligations }
-            .fold_opaque_ty_new(opaque, |_, _| ty)?;
-        Some(InferOk { value, obligations })
+    ) -> Option<InferResult<'tcx, ()>> {
+        Instantiator { infcx: self, cause, param_env }.fold_opaque_ty_new(opaque, |_, _| ty)
     }
 
     pub fn handle_opaque_type(
@@ -165,9 +164,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         b: Ty<'tcx>,
         cause: &ObligationCause<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
-    ) -> Result<PredicateObligations<'tcx>, TypeError<'tcx>> {
+    ) -> InferResult<'tcx, ()> {
         if a.references_error() || b.references_error() {
-            return Ok(vec![]);
+            return Ok(InferOk { value: (), obligations: vec![] });
         }
         if self.defining_use_anchor.is_some() {
             let process = |a: Ty<'tcx>, b: Ty<'tcx>| {
@@ -175,12 +174,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     return None;
                 }
                 self.instantiate_opaque_types(b, a, cause.clone(), param_env)
-                    .map(|res| res.obligations)
             };
             if let Some(res) = process(a, b) {
-                Ok(res)
+                res
             } else if let Some(res) = process(b, a) {
-                Ok(res)
+                res
             } else {
                 // Rerun equality check, but this time error out due to
                 // different types.
@@ -205,13 +203,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             };
             let key = opaque_type.expect_opaque_type();
             let origin = self.opaque_ty_origin_unchecked(key.def_id, cause.span);
-            self.inner.borrow_mut().opaque_types().register(
+            let prev = self.inner.borrow_mut().opaque_types().register(
                 key,
                 opaque_type,
                 OpaqueHiddenType { ty: hidden_ty, span: cause.span },
                 origin,
             );
-            Ok(vec![])
+            match prev {
+                Some(prev) => self.at(cause, param_env).eq(prev, hidden_ty),
+                None => Ok(InferOk { value: (), obligations: vec![] }),
+            }
         }
     }
 
@@ -599,7 +600,6 @@ struct Instantiator<'a, 'tcx> {
     infcx: &'a InferCtxt<'a, 'tcx>,
     cause: ObligationCause<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
-    obligations: &'a mut PredicateObligations<'tcx>,
 }
 
 impl<'a, 'tcx> Instantiator<'a, 'tcx> {
@@ -607,7 +607,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
         &mut self,
         ty: Ty<'tcx>,
         mk_ty: impl FnOnce(&InferCtxt<'_, 'tcx>, Span) -> Ty<'tcx>,
-    ) -> Option<Ty<'tcx>> {
+    ) -> Option<InferResult<'tcx, ()>> {
         // Check that this is `impl Trait` type is
         // declared by `parent_def_id` -- i.e., one whose
         // value we are inferring.  At present, this is
@@ -659,7 +659,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
         opaque_type_key: OpaqueTypeKey<'tcx>,
         origin: hir::OpaqueTyOrigin,
         mk_ty: impl FnOnce(&InferCtxt<'_, 'tcx>, Span) -> Ty<'tcx>,
-    ) -> Ty<'tcx> {
+    ) -> InferResult<'tcx, ()> {
         let infcx = self.infcx;
         let tcx = infcx.tcx;
         let OpaqueTypeKey { def_id, substs } = opaque_type_key;
@@ -673,12 +673,16 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
         // Foo, impl Bar)`.
         let span = self.cause.span;
 
-        self.infcx.inner.borrow_mut().opaque_types().register(
+        let mut obligations = vec![];
+        let prev = self.infcx.inner.borrow_mut().opaque_types().register(
             OpaqueTypeKey { def_id, substs },
             ty,
             OpaqueHiddenType { ty: ty_var, span },
             origin,
         );
+        if let Some(prev) = prev {
+            obligations = self.infcx.at(&self.cause, self.param_env).eq(prev, ty_var)?.obligations;
+        }
 
         debug!("generated new type inference var {:?}", ty_var.kind());
 
@@ -698,7 +702,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
                         projection_ty,
                         self.cause.clone(),
                         0,
-                        &mut self.obligations,
+                        &mut obligations,
                     ),
                     // Replace all other mentions of the same opaque type with the hidden type,
                     // as the bounds must hold on the hidden type after all.
@@ -714,19 +718,19 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
             if let ty::PredicateKind::Projection(projection) = predicate.kind().skip_binder() {
                 if projection.term.references_error() {
                     // No point on adding these obligations since there's a type error involved.
-                    return tcx.ty_error();
+                    return Ok(InferOk { value: (), obligations: vec![] });
                 }
                 trace!("{:#?}", projection.term);
             }
             // Require that the predicate holds for the concrete type.
             debug!(?predicate);
-            self.obligations.push(traits::Obligation::new(
+            obligations.push(traits::Obligation::new(
                 self.cause.clone(),
                 self.param_env,
                 predicate,
             ));
         }
-        ty_var
+        Ok(InferOk { value: (), obligations })
     }
 }
 
diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs
index dc47272c4fe..1895c1a85c7 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/table.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs
@@ -18,14 +18,14 @@ pub struct OpaqueTypeStorage<'tcx> {
 
 impl<'tcx> OpaqueTypeStorage<'tcx> {
     #[instrument(level = "debug")]
-    pub(crate) fn remove(&mut self, key: OpaqueTypeKey<'tcx>, idx: usize) {
-        if idx == 0 {
+    pub(crate) fn remove(&mut self, key: OpaqueTypeKey<'tcx>, idx: Option<OpaqueHiddenType<'tcx>>) {
+        if let Some(idx) = idx {
+            self.opaque_types.get_mut(&key).unwrap().hidden_types[0] = idx;
+        } else {
             match self.opaque_types.remove(&key) {
                 None => bug!("reverted opaque type inference that was never registered: {:?}", key),
                 Some(_) => {}
             }
-        } else {
-            self.opaque_types.get_mut(&key).unwrap().hidden_types.drain(idx..);
         }
     }
 
@@ -75,14 +75,17 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
         opaque_type: Ty<'tcx>,
         ty: OpaqueHiddenType<'tcx>,
         origin: OpaqueTyOrigin,
-    ) {
+    ) -> Option<Ty<'tcx>> {
         if let Some(decl) = self.storage.opaque_types.get_mut(&key) {
-            decl.hidden_types.push(ty);
-            self.undo_log.push(UndoLog::OpaqueTypes(key, decl.hidden_types.len()));
-            return;
+            assert_eq!(decl.hidden_types.len(), 1);
+            let prev = decl.hidden_types[0];
+            decl.hidden_types = vec![ty];
+            self.undo_log.push(UndoLog::OpaqueTypes(key, Some(prev)));
+            return Some(prev.ty);
         }
         let decl = OpaqueTypeDecl { opaque_type, hidden_types: vec![ty], origin };
         self.storage.opaque_types.insert(key, decl);
-        self.undo_log.push(UndoLog::OpaqueTypes(key, 0));
+        self.undo_log.push(UndoLog::OpaqueTypes(key, None));
+        None
     }
 }
diff --git a/compiler/rustc_infer/src/infer/undo_log.rs b/compiler/rustc_infer/src/infer/undo_log.rs
index 8f4abfde301..02b15baf8fb 100644
--- a/compiler/rustc_infer/src/infer/undo_log.rs
+++ b/compiler/rustc_infer/src/infer/undo_log.rs
@@ -11,6 +11,8 @@ use crate::{
     traits,
 };
 
+use super::opaque_types::OpaqueHiddenType;
+
 pub struct Snapshot<'tcx> {
     pub(crate) undo_len: usize,
     _marker: PhantomData<&'tcx ()>,
@@ -18,7 +20,7 @@ pub struct Snapshot<'tcx> {
 
 /// Records the "undo" data for a single operation that affects some form of inference variable.
 pub(crate) enum UndoLog<'tcx> {
-    OpaqueTypes(OpaqueTypeKey<'tcx>, usize),
+    OpaqueTypes(OpaqueTypeKey<'tcx>, Option<OpaqueHiddenType<'tcx>>),
     TypeVariables(type_variable::UndoLog<'tcx>),
     ConstUnificationTable(sv::UndoLog<ut::Delegate<ty::ConstVid<'tcx>>>),
     IntUnificationTable(sv::UndoLog<ut::Delegate<ty::IntVid>>),
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 68dd1cd2616..274f8a3ef79 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -652,7 +652,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
                         &obligation.cause,
                         obligation.param_env,
                     ) {
-                        Ok(value) => ProcessResult::Changed(mk_pending(value)),
+                        Ok(value) => ProcessResult::Changed(mk_pending(value.obligations)),
                         Err(err) => ProcessResult::Error(FulfillmentErrorCode::CodeSubtypeError(
                             ExpectedFound::new(true, a, b),
                             err,
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 3b99183d8eb..35818786cbb 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -705,8 +705,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                         &obligation.cause,
                         obligation.param_env,
                     ) {
-                        Ok(obligations) => {
-                            self.evaluate_predicates_recursively(previous_stack, obligations)
+                        Ok(res) => {
+                            self.evaluate_predicates_recursively(previous_stack, res.obligations)
                         }
                         Err(_) => Ok(EvaluatedToErr),
                     }
diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr
index f79411c1003..4032fbbceba 100644
--- a/src/test/ui/impl-trait/equality.stderr
+++ b/src/test/ui/impl-trait/equality.stderr
@@ -11,11 +11,14 @@ LL | #![feature(specialization)]
 error[E0308]: mismatched types
   --> $DIR/equality.rs:15:5
    |
-LL |         return 1_i32;
-   |                ----- type expected due to this
-LL |     }
+LL | fn two(x: bool) -> impl Foo {
+   |                    -------- the expected opaque 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/issue-72911.rs b/src/test/ui/impl-trait/issue-72911.rs
index d556e968f34..cf2c8b7e415 100644
--- a/src/test/ui/impl-trait/issue-72911.rs
+++ b/src/test/ui/impl-trait/issue-72911.rs
@@ -16,7 +16,6 @@ fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator<Item = Lint>
 
 fn lint_files() -> impl Iterator<Item = foo::MissingItem> {
     //~^ ERROR: failed to resolve
-    //~| ERROR `()` is not an iterator
     unimplemented!()
 }
 
diff --git a/src/test/ui/impl-trait/issue-72911.stderr b/src/test/ui/impl-trait/issue-72911.stderr
index 51648e6154d..4a990286d96 100644
--- a/src/test/ui/impl-trait/issue-72911.stderr
+++ b/src/test/ui/impl-trait/issue-72911.stderr
@@ -18,15 +18,7 @@ LL | pub fn gather_all() -> impl Iterator<Item = Lint> {
    |
    = help: the trait `Iterator` is not implemented for `()`
 
-error[E0277]: `()` is not an iterator
-  --> $DIR/issue-72911.rs:17:20
-   |
-LL | fn lint_files() -> impl Iterator<Item = foo::MissingItem> {
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
-   |
-   = help: the trait `Iterator` is not implemented for `()`
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0277, E0433.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr
index 0e195558bad..15476c706a7 100644
--- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr
+++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr
@@ -1,11 +1,11 @@
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ordinary-bounds-unrelated.rs:28:22
+  --> $DIR/ordinary-bounds-unrelated.rs:28:33
    |
 LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
    |                     -- hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here
 ...
 LL |     if condition() { a } else { b }
-   |                      ^
+   |                                 ^
    |
 help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound
    |
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr
index 032e88c6d9c..7315aa8e9d4 100644
--- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr
+++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr
@@ -1,11 +1,11 @@
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ordinary-bounds-unsuited.rs:31:22
+  --> $DIR/ordinary-bounds-unsuited.rs:31:33
    |
 LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
    |                     -- hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here
 ...
 LL |     if condition() { a } else { b }
-   |                      ^
+   |                                 ^
    |
 help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound
    |
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 4b4116887dc..b2f7166f0ae 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
@@ -1,20 +1,26 @@
 error[E0308]: mismatched types
   --> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:36:5
    |
-LL |         return A;
-   |                - type expected due to this
-LL |     }
+LL | fn can() -> impl NotObjectSafe {
+   |             ------------------ the expected opaque 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 |         return A;
-   |                - type expected due to this
-LL |     }
+LL | fn cat() -> impl ObjectSafe {
+   |             --------------- the expected opaque 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.stderr b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr
index eb0d3a52a4e..db0d446e559 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
@@ -1,31 +1,41 @@
 error[E0308]: mismatched types
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:5:5
    |
-LL |         return 0i32;
-   |                ---- type expected due to this
-LL |     }
+LL | fn foo() -> impl std::fmt::Display {
+   |             ---------------------- the expected opaque 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 |         return 0i32;
-   |                ---- type expected due to this
-LL |     } else {
+LL | fn bar() -> impl std::fmt::Display {
+   |             ---------------------- the expected opaque 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
    |
+LL |   fn baz() -> impl std::fmt::Display {
+   |               ---------------------- the expected opaque type
 LL | /     if false {
 LL | |         return 0i32;
-   | |                ---- type expected due to this
 LL | |     } else {
 LL | |         1u32
 LL | |     }
    | |_____^ expected `i32`, found `u32`
+   |
+   = note: expected opaque type `impl std::fmt::Display`
+                     found type `u32`
 
 error[E0308]: `if` and `else` have incompatible types
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:28:9
@@ -53,36 +63,48 @@ LL ~         Box::new(1u32)
 error[E0308]: mismatched types
   --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:33:5
    |
+LL |   fn bat() -> impl std::fmt::Display {
+   |               ---------------------- the expected opaque type
 LL | /     match 13 {
 LL | |         0 => return 0i32,
-   | |                     ---- type expected due to this
 LL | |         _ => 1u32,
 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:40:5
    |
+LL |   fn can() -> impl std::fmt::Display {
+   |               ---------------------- the expected opaque type
 LL | /     match 13 {
 LL | |         0 => return 0i32,
-   | |                     ---- type expected due to this
 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
    |
+LL |   fn cat() -> impl std::fmt::Display {
+   |               ---------------------- the expected opaque type
 LL | /     match 13 {
 LL | |         0 => {
 LL | |             return 0i32;
-   | |                    ---- type expected due to this
 LL | |         }
 ...  |
 LL | |         }
 LL | |     }
    | |_____^ expected `i32`, found `u32`
+   |
+   = note: expected opaque type `impl std::fmt::Display`
+                     found type `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/type-alias-impl-trait/issue-63279.rs b/src/test/ui/type-alias-impl-trait/issue-63279.rs
index 3d20b7e3719..e09e1a3afed 100644
--- a/src/test/ui/type-alias-impl-trait/issue-63279.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-63279.rs
@@ -8,6 +8,7 @@ type Closure = impl FnOnce();
 fn c() -> Closure {
     || -> Closure { || () }
     //~^ ERROR: mismatched types
+    //~| ERROR: mismatched types
     //~| ERROR: expected a `FnOnce<()>` closure, found `()`
 }
 
diff --git a/src/test/ui/type-alias-impl-trait/issue-63279.stderr b/src/test/ui/type-alias-impl-trait/issue-63279.stderr
index 385e816eebf..810c99c84bc 100644
--- a/src/test/ui/type-alias-impl-trait/issue-63279.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-63279.stderr
@@ -15,10 +15,18 @@ LL |     || -> Closure { || () }
    |
    = note: expected unit type `()`
                 found closure `[closure@$DIR/issue-63279.rs:9:21: 9:26]`
-help: you might have meant to return this value
+
+error[E0308]: mismatched types
+  --> $DIR/issue-63279.rs:9:5
+   |
+LL | type Closure = impl FnOnce();
+   |                ------------- the expected opaque type
+...
+LL |     || -> Closure { || () }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found closure
    |
-LL |     || -> Closure { return || (); }
-   |                     ++++++      +
+   = note: expected opaque type `impl FnOnce()`
+                  found closure `[closure@$DIR/issue-63279.rs:9:5: 9:28]`
 
 error: could not find defining uses
   --> $DIR/issue-63279.rs:5:16
@@ -26,7 +34,7 @@ error: could not find defining uses
 LL | type Closure = impl FnOnce();
    |                ^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0277, E0308.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-74280.stderr b/src/test/ui/type-alias-impl-trait/issue-74280.stderr
index 475a0052234..db8c5b7a72b 100644
--- a/src/test/ui/type-alias-impl-trait/issue-74280.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-74280.stderr
@@ -1,10 +1,14 @@
 error[E0308]: mismatched types
   --> $DIR/issue-74280.rs:10:5
    |
-LL |     let y = || -> Test { () };
-   |                          -- type expected due to this
+LL | type Test = impl Copy;
+   |             --------- the expected opaque type
+...
 LL |     7
    |     ^ expected `()`, found integer
+   |
+   = note: expected opaque type `impl Copy`
+                     found type `{integer}`
 
 error: could not find defining uses
   --> $DIR/issue-74280.rs:5:13
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
index 65bd12d9a9a..20da37ec9a1 100644
--- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
@@ -1,17 +1,18 @@
 error[E0308]: mismatched types
   --> $DIR/multiple-def-uses-in-one-fn3.rs:14:9
    |
+LL | type X<A: ToString + Clone, B: ToString + Clone> = impl ToString;
+   |                                                    ------------- the expected opaque type
+...
 LL | fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
    |      -                    - found type parameter
    |      |
    |      expected type parameter
 LL |     (a, b)
-   |      -  ^ expected type parameter `A`, found type parameter `B`
-   |      |
-   |      type expected due to this
+   |         ^ expected type parameter `A`, found type parameter `B`
    |
-   = note: expected type parameter `A`
-              found type parameter `B`
+   = note: expected opaque type `impl ToString`
+           found type parameter `B`
    = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters