about summary refs log tree commit diff
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2025-03-19 17:52:53 +0100
committerlcnr <rust@lcnr.de>2025-03-19 17:52:53 +0100
commitcfc78cec79653e0c68e894b28295765a4208639e (patch)
treefface9c436d956f09ca00e38ed1eca5d114aa656
parentf8fe978fab83d6cdb7ccd148a7e2bd5c9caae156 (diff)
downloadrust-cfc78cec79653e0c68e894b28295765a4208639e.tar.gz
rust-cfc78cec79653e0c68e894b28295765a4208639e.zip
merge opaque types of nested bodies
-rw-r--r--compiler/rustc_borrowck/src/lib.rs7
-rw-r--r--compiler/rustc_borrowck/src/nll.rs20
-rw-r--r--compiler/rustc_borrowck/src/opaque_types.rs55
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs37
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs6
-rw-r--r--tests/crashes/122904.rs12
-rw-r--r--tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs3
-rw-r--r--tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr18
-rw-r--r--tests/ui/impl-trait/issues/issue-86800.rs1
-rw-r--r--tests/ui/impl-trait/issues/issue-86800.stderr23
-rw-r--r--tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr19
-rw-r--r--tests/ui/type-alias-impl-trait/const_generic_type.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/error-tainting-issue-122904.rs18
-rw-r--r--tests/ui/type-alias-impl-trait/error-tainting-issue-122904.stderr30
-rw-r--r--tests/ui/type-alias-impl-trait/hkl_forbidden4.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr19
-rw-r--r--tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.stderr10
19 files changed, 146 insertions, 146 deletions
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index ed95545dea4..84b7b8c6a2d 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -73,6 +73,7 @@ mod def_use;
 mod diagnostics;
 mod member_constraints;
 mod nll;
+mod opaque_types;
 mod path_utils;
 mod place_ext;
 mod places_conflict;
@@ -192,7 +193,7 @@ fn do_mir_borrowck<'tcx>(
     // Compute non-lexical lifetimes.
     let nll::NllOutput {
         regioncx,
-        opaque_type_values,
+        concrete_opaque_types,
         polonius_input,
         polonius_output,
         opt_closure_req,
@@ -222,7 +223,7 @@ fn do_mir_borrowck<'tcx>(
         body,
         &regioncx,
         &opt_closure_req,
-        &opaque_type_values,
+        &concrete_opaque_types,
         diags_buffer,
     );
 
@@ -357,7 +358,7 @@ fn do_mir_borrowck<'tcx>(
     let tainted_by_errors = mbcx.emit_errors();
 
     let result = BorrowCheckResult {
-        concrete_opaque_types: opaque_type_values,
+        concrete_opaque_types: concrete_opaque_types.into_inner(),
         closure_requirements: opt_closure_req,
         used_mut_upvars: mbcx.used_mut_upvars,
         tainted_by_errors,
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index 2031579dfd5..d0bd364425a 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -6,8 +6,6 @@ use std::str::FromStr;
 use std::{env, io};
 
 use polonius_engine::{Algorithm, Output};
-use rustc_data_structures::fx::FxIndexMap;
-use rustc_hir::def_id::LocalDefId;
 use rustc_index::IndexSlice;
 use rustc_middle::mir::pretty::{PrettyPrintMirOptions, dump_mir_with_options};
 use rustc_middle::mir::{
@@ -15,7 +13,7 @@ use rustc_middle::mir::{
     dump_enabled, dump_mir,
 };
 use rustc_middle::ty::print::with_no_trimmed_paths;
-use rustc_middle::ty::{self, OpaqueHiddenType, TyCtxt};
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_mir_dataflow::ResultsCursor;
 use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
 use rustc_mir_dataflow::move_paths::MoveData;
@@ -27,6 +25,7 @@ use tracing::{debug, instrument};
 use crate::borrow_set::BorrowSet;
 use crate::consumers::ConsumerOptions;
 use crate::diagnostics::{BorrowckDiagnosticsBuffer, RegionErrors};
+use crate::opaque_types::ConcreteOpaqueTypes;
 use crate::polonius::PoloniusDiagnosticsContext;
 use crate::polonius::legacy::{
     PoloniusFacts, PoloniusFactsExt, PoloniusLocationTable, PoloniusOutput,
@@ -40,7 +39,7 @@ use crate::{BorrowckInferCtxt, polonius, renumber};
 /// closure requirements to propagate, and any generated errors.
 pub(crate) struct NllOutput<'tcx> {
     pub regioncx: RegionInferenceContext<'tcx>,
-    pub opaque_type_values: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
+    pub concrete_opaque_types: ConcreteOpaqueTypes<'tcx>,
     pub polonius_input: Option<Box<PoloniusFacts>>,
     pub polonius_output: Option<Box<PoloniusOutput>>,
     pub opt_closure_req: Option<ClosureRegionRequirements<'tcx>>,
@@ -99,6 +98,8 @@ pub(crate) fn compute_regions<'a, 'tcx>(
 
     let location_map = Rc::new(DenseLocationMap::new(body));
 
+    let mut concrete_opaque_types = ConcreteOpaqueTypes::default();
+
     // Run the MIR type-checker.
     let MirTypeckResults {
         constraints,
@@ -116,6 +117,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
         flow_inits,
         move_data,
         Rc::clone(&location_map),
+        &mut concrete_opaque_types,
     );
 
     // Create the region inference context, taking ownership of the
@@ -180,11 +182,11 @@ pub(crate) fn compute_regions<'a, 'tcx>(
         infcx.set_tainted_by_errors(guar);
     }
 
-    let remapped_opaque_tys = regioncx.infer_opaque_types(infcx, opaque_type_values);
+    regioncx.infer_opaque_types(infcx, opaque_type_values, &mut concrete_opaque_types);
 
     NllOutput {
         regioncx,
-        opaque_type_values: remapped_opaque_tys,
+        concrete_opaque_types,
         polonius_input: polonius_facts.map(Box::new),
         polonius_output,
         opt_closure_req: closure_region_requirements,
@@ -300,7 +302,7 @@ pub(super) fn dump_annotation<'tcx, 'infcx>(
     body: &Body<'tcx>,
     regioncx: &RegionInferenceContext<'tcx>,
     closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
-    opaque_type_values: &FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
+    concrete_opaque_types: &ConcreteOpaqueTypes<'tcx>,
     diagnostics_buffer: &mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>,
 ) {
     let tcx = infcx.tcx;
@@ -343,8 +345,8 @@ pub(super) fn dump_annotation<'tcx, 'infcx>(
         err
     };
 
-    if !opaque_type_values.is_empty() {
-        err.note(format!("Inferred opaque type values:\n{opaque_type_values:#?}"));
+    if !concrete_opaque_types.is_empty() {
+        err.note(format!("Inferred opaque type values:\n{concrete_opaque_types:#?}"));
     }
 
     diagnostics_buffer.buffer_non_error(err);
diff --git a/compiler/rustc_borrowck/src/opaque_types.rs b/compiler/rustc_borrowck/src/opaque_types.rs
new file mode 100644
index 00000000000..5c78814abdd
--- /dev/null
+++ b/compiler/rustc_borrowck/src/opaque_types.rs
@@ -0,0 +1,55 @@
+use rustc_data_structures::fx::FxIndexMap;
+use rustc_hir::def_id::LocalDefId;
+use rustc_middle::ty::{OpaqueHiddenType, Ty, TyCtxt};
+
+#[derive(Debug, Default)]
+pub(super) struct ConcreteOpaqueTypes<'tcx> {
+    concrete_opaque_types: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
+}
+
+impl<'tcx> ConcreteOpaqueTypes<'tcx> {
+    pub(super) fn is_empty(&self) -> bool {
+        self.concrete_opaque_types.is_empty()
+    }
+
+    pub(super) fn into_inner(self) -> FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> {
+        self.concrete_opaque_types
+    }
+
+    /// Insert an opaque type into the list of opaque types defined by this function
+    /// after mapping the hidden type to the generic parameters of the opaque type
+    /// definition.
+    pub(super) fn insert(
+        &mut self,
+        tcx: TyCtxt<'tcx>,
+        def_id: LocalDefId,
+        hidden_ty: OpaqueHiddenType<'tcx>,
+    ) {
+        // Sometimes two opaque types are the same only after we remap the generic parameters
+        // back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to
+        // `(X, Y)` and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we
+        // only know that once we convert the generic parameters to those of the opaque type.
+        if let Some(prev) = self.concrete_opaque_types.get_mut(&def_id) {
+            if prev.ty != hidden_ty.ty {
+                let (Ok(guar) | Err(guar)) =
+                    prev.build_mismatch_error(&hidden_ty, tcx).map(|d| d.emit());
+                prev.ty = Ty::new_error(tcx, guar);
+            }
+            // Pick a better span if there is one.
+            // FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
+            prev.span = prev.span.substitute_dummy(hidden_ty.span);
+        } else {
+            self.concrete_opaque_types.insert(def_id, hidden_ty);
+        }
+    }
+
+    pub(super) fn extend_from_nested_body(
+        &mut self,
+        tcx: TyCtxt<'tcx>,
+        nested_body: &FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
+    ) {
+        for (&def_id, &hidden_ty) in nested_body {
+            self.insert(tcx, def_id, hidden_ty);
+        }
+    }
+}
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 04839448596..ca8b9fb4e9d 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -15,6 +15,7 @@ use rustc_trait_selection::traits::ObligationCtxt;
 use tracing::{debug, instrument};
 
 use super::RegionInferenceContext;
+use crate::opaque_types::ConcreteOpaqueTypes;
 use crate::session_diagnostics::{LifetimeMismatchOpaqueParam, NonGenericOpaqueTypeParam};
 use crate::universal_regions::RegionClassification;
 
@@ -67,8 +68,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         &self,
         infcx: &InferCtxt<'tcx>,
         opaque_ty_decls: FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
-    ) -> FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> {
-        let mut result: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> = FxIndexMap::default();
+        concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
+    ) {
         let mut decls_modulo_regions: FxIndexMap<OpaqueTypeKey<'tcx>, (OpaqueTypeKey<'tcx>, Span)> =
             FxIndexMap::default();
 
@@ -143,33 +144,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                     continue;
                 }
             }
-            // Sometimes two opaque types are the same only after we remap the generic parameters
-            // back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to
-            // `(X, Y)` and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we
-            // only know that once we convert the generic parameters to those of the opaque type.
-            if let Some(prev) = result.get_mut(&opaque_type_key.def_id) {
-                if prev.ty != ty {
-                    let guar = ty.error_reported().err().unwrap_or_else(|| {
-                        let (Ok(e) | Err(e)) = prev
-                            .build_mismatch_error(
-                                &OpaqueHiddenType { ty, span: concrete_type.span },
-                                infcx.tcx,
-                            )
-                            .map(|d| d.emit());
-                        e
-                    });
-                    prev.ty = Ty::new_error(infcx.tcx, guar);
-                }
-                // Pick a better span if there is one.
-                // FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
-                prev.span = prev.span.substitute_dummy(concrete_type.span);
-            } else {
-                result.insert(
-                    opaque_type_key.def_id,
-                    OpaqueHiddenType { ty, span: concrete_type.span },
-                );
-            }
 
+            concrete_opaque_types.insert(
+                infcx.tcx,
+                opaque_type_key.def_id,
+                OpaqueHiddenType { ty, span: concrete_type.span },
+            );
             // Check that all opaque types have the same region parameters if they have the same
             // non-region parameters. This is necessary because within the new solver we perform
             // various query operations modulo regions, and thus could unsoundly select some impls
@@ -193,7 +173,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 });
             }
         }
-        result
     }
 
     /// Map the regions in the type to named regions. This is similar to what
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 0fda3e31690..f6144a25938 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -45,6 +45,7 @@ use crate::borrow_set::BorrowSet;
 use crate::constraints::{OutlivesConstraint, OutlivesConstraintSet};
 use crate::diagnostics::UniverseInfo;
 use crate::member_constraints::MemberConstraintSet;
+use crate::opaque_types::ConcreteOpaqueTypes;
 use crate::polonius::legacy::{PoloniusFacts, PoloniusLocationTable};
 use crate::polonius::{PoloniusContext, PoloniusLivenessContext};
 use crate::region_infer::TypeTest;
@@ -111,6 +112,7 @@ pub(crate) fn type_check<'a, 'tcx>(
     flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
     move_data: &MoveData<'tcx>,
     location_map: Rc<DenseLocationMap>,
+    concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
 ) -> MirTypeckResults<'tcx> {
     let implicit_region_bound = ty::Region::new_var(infcx.tcx, universal_regions.fr_fn_body);
     let mut constraints = MirTypeckRegionConstraints {
@@ -165,6 +167,7 @@ pub(crate) fn type_check<'a, 'tcx>(
         polonius_facts,
         borrow_set,
         constraints: &mut constraints,
+        concrete_opaque_types,
         polonius_liveness,
     };
 
@@ -230,6 +233,7 @@ struct TypeChecker<'a, 'tcx> {
     polonius_facts: &'a mut Option<PoloniusFacts>,
     borrow_set: &'a BorrowSet<'tcx>,
     constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
+    concrete_opaque_types: &'a mut ConcreteOpaqueTypes<'tcx>,
     /// When using `-Zpolonius=next`, the liveness helper data used to create polonius constraints.
     polonius_liveness: Option<PoloniusLivenessContext>,
 }
@@ -2499,7 +2503,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         args: GenericArgsRef<'tcx>,
         locations: Locations,
     ) -> ty::InstantiatedPredicates<'tcx> {
-        if let Some(closure_requirements) = &tcx.mir_borrowck(def_id).closure_requirements {
+        let closure_borrowck_results = tcx.mir_borrowck(def_id);
+        self.concrete_opaque_types
+            .extend_from_nested_body(tcx, &closure_borrowck_results.concrete_opaque_types);
+
+        if let Some(closure_requirements) = &closure_borrowck_results.closure_requirements {
             constraint_conversion::ConstraintConversion::new(
                 self.infcx,
                 self.universal_regions,
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
index 075dc590b99..3dec1e286b4 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
@@ -258,9 +258,6 @@ impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> {
         self.tcx
     }
     fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
-        if let hir::ExprKind::Closure(closure) = ex.kind {
-            self.check(closure.def_id);
-        }
         intravisit::walk_expr(self, ex);
     }
     fn visit_item(&mut self, it: &'tcx Item<'tcx>) {
@@ -389,9 +386,6 @@ impl<'tcx> intravisit::Visitor<'tcx> for RpitConstraintChecker<'tcx> {
         self.tcx
     }
     fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
-        if let hir::ExprKind::Closure(closure) = ex.kind {
-            self.check(closure.def_id);
-        }
         intravisit::walk_expr(self, ex);
     }
     fn visit_item(&mut self, it: &'tcx Item<'tcx>) {
diff --git a/tests/crashes/122904.rs b/tests/crashes/122904.rs
deleted file mode 100644
index 2068cd9d239..00000000000
--- a/tests/crashes/122904.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ known-bug: #122904
-trait T {}
-
-type Alias<'a> = impl T;
-
-struct S;
-impl<'a> T for &'a S {}
-
-#[define_opaque(Alias)]
-fn with_positive(fun: impl Fn(Alias<'_>)) {
-    with_positive(|&n| ());
-}
diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs
index 2f17c0ff508..776bb7278ce 100644
--- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs
+++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs
@@ -2,8 +2,7 @@
 use std::fmt::Debug;
 
 fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
-    //~^ ERROR cannot resolve opaque type
-    //~| WARNING elided lifetime has a name
+    //~^ WARNING elided lifetime has a name
     |x| x
     //~^ ERROR expected generic lifetime parameter, found `'_`
 }
diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
index 91550f0e284..209186db4cc 100644
--- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
+++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
@@ -7,24 +7,14 @@ LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
    = note: `#[warn(elided_named_lifetimes)]` on by default
 
 error[E0792]: expected generic lifetime parameter, found `'_`
-  --> $DIR/impl-fn-predefined-lifetimes.rs:7:9
+  --> $DIR/impl-fn-predefined-lifetimes.rs:6:9
    |
 LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
    |                                                -- this generic parameter must be used with a generic lifetime parameter
-...
+LL |
 LL |     |x| x
    |         ^
 
-error[E0720]: cannot resolve opaque type
-  --> $DIR/impl-fn-predefined-lifetimes.rs:4:35
-   |
-LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
-   |                                   ^^^^^^^^^^^^^^^ recursive opaque type
-...
-LL |     |x| x
-   |     ----- returning here with type `{closure@$DIR/impl-fn-predefined-lifetimes.rs:7:5: 7:8}`
-
-error: aborting due to 2 previous errors; 1 warning emitted
+error: aborting due to 1 previous error; 1 warning emitted
 
-Some errors have detailed explanations: E0720, E0792.
-For more information about an error, try `rustc --explain E0720`.
+For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/impl-trait/issues/issue-86800.rs b/tests/ui/impl-trait/issues/issue-86800.rs
index c1176255f24..9e8ea439dde 100644
--- a/tests/ui/impl-trait/issues/issue-86800.rs
+++ b/tests/ui/impl-trait/issues/issue-86800.rs
@@ -40,7 +40,6 @@ impl Context {
         f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O>,
     ) -> TransactionResult<O> {
         //~^ ERROR expected generic lifetime parameter, found `'_`
-        //~| ERROR: item does not constrain
         let mut conn = Connection {};
         let mut transaction = TestTransaction { conn: &mut conn };
         f(&mut transaction).await
diff --git a/tests/ui/impl-trait/issues/issue-86800.stderr b/tests/ui/impl-trait/issues/issue-86800.stderr
index 11e23d97d72..80aa5d75c3c 100644
--- a/tests/ui/impl-trait/issues/issue-86800.stderr
+++ b/tests/ui/impl-trait/issues/issue-86800.stderr
@@ -24,26 +24,6 @@ note: this opaque type is supposed to be constrained
 LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: item does not constrain `TransactionFuture::{opaque#0}`
-  --> $DIR/issue-86800.rs:41:31
-   |
-LL |       ) -> TransactionResult<O> {
-   |  _______________________________^
-LL | |
-LL | |
-LL | |         let mut conn = Connection {};
-LL | |         let mut transaction = TestTransaction { conn: &mut conn };
-LL | |         f(&mut transaction).await
-LL | |     }
-   | |_____^
-   |
-   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
-note: this opaque type is supposed to be constrained
-  --> $DIR/issue-86800.rs:21:34
-   |
-LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
-   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
 error[E0792]: expected generic lifetime parameter, found `'_`
   --> $DIR/issue-86800.rs:31:5
    |
@@ -62,13 +42,12 @@ LL |   type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionRe
 LL |       ) -> TransactionResult<O> {
    |  _______________________________^
 LL | |
-LL | |
 LL | |         let mut conn = Connection {};
 LL | |         let mut transaction = TestTransaction { conn: &mut conn };
 LL | |         f(&mut transaction).await
 LL | |     }
    | |_____^
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr
index ba97bbf89f8..241eccc5f2b 100644
--- a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr
+++ b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr
@@ -19,22 +19,5 @@ note: this opaque type is supposed to be constrained
 LL | type Bar = impl std::fmt::Display;
    |            ^^^^^^^^^^^^^^^^^^^^^^
 
-error: item does not constrain `Bar::{opaque#0}`
-  --> $DIR/const_generic_type.rs:8:31
-   |
-LL |   async fn test<const N: Bar>() {
-   |  _______________________________^
-...  |
-LL | |     let x: u32 = N;
-LL | | }
-   | |_^
-   |
-   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
-note: this opaque type is supposed to be constrained
-  --> $DIR/const_generic_type.rs:5:12
-   |
-LL | type Bar = impl std::fmt::Display;
-   |            ^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.rs b/tests/ui/type-alias-impl-trait/const_generic_type.rs
index 5b093be9231..9b38f1449f8 100644
--- a/tests/ui/type-alias-impl-trait/const_generic_type.rs
+++ b/tests/ui/type-alias-impl-trait/const_generic_type.rs
@@ -8,7 +8,6 @@ type Bar = impl std::fmt::Display;
 async fn test<const N: Bar>() {
     //~^ ERROR: `Bar` is forbidden as the type of a const generic parameter
     //[no_infer]~^^ ERROR item does not constrain
-    //[no_infer]~| ERROR item does not constrain
     #[cfg(infer)]
     let x: u32 = N;
 }
diff --git a/tests/ui/type-alias-impl-trait/error-tainting-issue-122904.rs b/tests/ui/type-alias-impl-trait/error-tainting-issue-122904.rs
new file mode 100644
index 00000000000..a2de3957c0b
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/error-tainting-issue-122904.rs
@@ -0,0 +1,18 @@
+// We previously didn't taint the borrowck result in this test,
+// causing an ICE later on.
+#![feature(type_alias_impl_trait)]
+trait T {}
+
+type Alias<'a> = impl T;
+
+struct S;
+impl<'a> T for &'a S {}
+
+#[define_opaque(Alias)]
+fn with_positive(fun: impl Fn(Alias<'_>)) {
+    //~^ WARN function cannot return without recursing
+    with_positive(|&n| ());
+    //~^ ERROR cannot move out of a shared reference
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/error-tainting-issue-122904.stderr b/tests/ui/type-alias-impl-trait/error-tainting-issue-122904.stderr
new file mode 100644
index 00000000000..956ce3e5936
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/error-tainting-issue-122904.stderr
@@ -0,0 +1,30 @@
+warning: function cannot return without recursing
+  --> $DIR/error-tainting-issue-122904.rs:12:1
+   |
+LL | fn with_positive(fun: impl Fn(Alias<'_>)) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
+LL |
+LL |     with_positive(|&n| ());
+   |     ---------------------- recursive call site
+   |
+   = help: a `loop` may express intention better if this is on purpose
+   = note: `#[warn(unconditional_recursion)]` on by default
+
+error[E0507]: cannot move out of a shared reference
+  --> $DIR/error-tainting-issue-122904.rs:14:20
+   |
+LL |     with_positive(|&n| ());
+   |                    ^-
+   |                     |
+   |                     data moved here
+   |                     move occurs because `n` has type `S`, which does not implement the `Copy` trait
+   |
+help: consider removing the borrow
+   |
+LL -     with_positive(|&n| ());
+LL +     with_positive(|n| ());
+   |
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0507`.
diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs
index 7e010918b29..cbd8150d117 100644
--- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs
+++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs
@@ -22,7 +22,6 @@ where
     for<'any> F: FnMut(&'any mut ()) -> FutNothing<'any>,
 {
     //~^ ERROR: expected generic lifetime parameter, found `'any`
-    //~| ERROR item does not constrain
 }
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr
index 2ca6a199448..2c0be0cbcdc 100644
--- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr
+++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr
@@ -11,21 +11,6 @@ note: this opaque type is supposed to be constrained
 LL | type FutNothing<'a> = impl 'a + Future<Output = ()>;
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: item does not constrain `FutNothing::{opaque#0}`
-  --> $DIR/hkl_forbidden4.rs:23:1
-   |
-LL | / {
-...  |
-LL | | }
-   | |_^
-   |
-   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
-note: this opaque type is supposed to be constrained
-  --> $DIR/hkl_forbidden4.rs:10:23
-   |
-LL | type FutNothing<'a> = impl 'a + Future<Output = ()>;
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
 error: concrete type differs from previous defining opaque type use
   --> $DIR/hkl_forbidden4.rs:12:1
    |
@@ -54,10 +39,10 @@ LL |   type FutNothing<'a> = impl 'a + Future<Output = ()>;
    |                   -- this generic parameter must be used with a generic lifetime parameter
 ...
 LL | / {
-...  |
+LL | |
 LL | | }
    | |_^
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.rs b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.rs
index 7452000b65d..92c8a8f3216 100644
--- a/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.rs
+++ b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.rs
@@ -6,7 +6,7 @@ trait Foo {
 }
 
 impl Foo for () {
-    type Assoc<'a> = impl Sized; //~ ERROR unconstrained opaque type
+    type Assoc<'a> = impl Sized;
     fn bar<'a: 'a>()
     where
         Self::Assoc<'a>:,
diff --git a/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.stderr b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.stderr
index 1274a8b60de..7ce4517fb1e 100644
--- a/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.stderr
+++ b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.stderr
@@ -9,14 +9,6 @@ LL |     fn bar<'a: 'a>()
 LL |             let _: Self::Assoc<'a> = x;
    |                    ^^^^^^^^^^^^^^^
 
-error: unconstrained opaque type
-  --> $DIR/in-assoc-ty-early-bound2.rs:9:22
-   |
-LL |     type Assoc<'a> = impl Sized;
-   |                      ^^^^^^^^^^
-   |
-   = note: `Assoc` must be used in combination with a concrete type within the same impl
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0700`.