about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-06-18 23:11:22 +0000
committerMichael Goulet <michael@errs.io>2023-06-19 14:49:56 +0000
commit2e8af07a8aa14de595b11841ce655b9e6c271f60 (patch)
treea4c1760d9ed59924fd5816ef33f5c9373e8a578b
parent18a6d911caba59605eb03db1452848a85d2e5879 (diff)
downloadrust-2e8af07a8aa14de595b11841ce655b9e6c271f60.tar.gz
rust-2e8af07a8aa14de595b11841ce655b9e6c271f60.zip
Don't consider TAIT normalizable to hidden ty if it would result in impossible item bounds
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs3
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs10
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt.rs13
-rw-r--r--compiler/rustc_trait_selection/src/solve/opaques.rs24
-rw-r--r--tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs2
5 files changed, 39 insertions, 13 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 33f75437478..cbb1c307354 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1065,7 +1065,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         )?;
 
                         ocx.infcx.add_item_bounds_for_hidden_type(
-                            opaque_type_key,
+                            opaque_type_key.def_id.to_def_id(),
+                            opaque_type_key.substs,
                             cause,
                             param_env,
                             hidden_ty.ty,
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 6b8293f90f1..b19f685a4a4 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -536,7 +536,8 @@ impl<'tcx> InferCtxt<'tcx> {
         )?;
 
         self.add_item_bounds_for_hidden_type(
-            opaque_type_key,
+            opaque_type_key.def_id.to_def_id(),
+            opaque_type_key.substs,
             cause,
             param_env,
             hidden_ty,
@@ -598,7 +599,8 @@ impl<'tcx> InferCtxt<'tcx> {
 
     pub fn add_item_bounds_for_hidden_type(
         &self,
-        OpaqueTypeKey { def_id, substs }: OpaqueTypeKey<'tcx>,
+        def_id: DefId,
+        substs: ty::SubstsRef<'tcx>,
         cause: ObligationCause<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         hidden_ty: Ty<'tcx>,
@@ -631,7 +633,7 @@ impl<'tcx> InferCtxt<'tcx> {
                     // Replace all other mentions of the same opaque type with the hidden type,
                     // as the bounds must hold on the hidden type after all.
                     ty::Alias(ty::Opaque, ty::AliasTy { def_id: def_id2, substs: substs2, .. })
-                        if def_id.to_def_id() == def_id2 && substs == substs2 =>
+                        if def_id == def_id2 && substs == substs2 =>
                     {
                         hidden_ty
                     }
@@ -640,7 +642,7 @@ impl<'tcx> InferCtxt<'tcx> {
                     ty::Alias(
                         ty::Projection,
                         ty::AliasTy { def_id: def_id2, substs: substs2, .. },
-                    ) if def_id.to_def_id() == def_id2 && substs == substs2 => hidden_ty,
+                    ) if def_id == def_id2 && substs == substs2 => hidden_ty,
                     _ => ty,
                 },
                 lt_op: |lt| lt,
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
index 4258f9f6bd2..106849190e0 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
@@ -835,13 +835,15 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
 
     pub(super) fn add_item_bounds_for_hidden_type(
         &mut self,
-        opaque_type_key: OpaqueTypeKey<'tcx>,
+        opaque_def_id: DefId,
+        opaque_substs: ty::SubstsRef<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         hidden_ty: Ty<'tcx>,
     ) {
         let mut obligations = Vec::new();
         self.infcx.add_item_bounds_for_hidden_type(
-            opaque_type_key,
+            opaque_def_id,
+            opaque_substs,
             ObligationCause::dummy(),
             param_env,
             hidden_ty,
@@ -872,7 +874,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                         ecx.eq(param_env, a, b)?;
                     }
                     ecx.eq(param_env, candidate_ty, ty)?;
-                    ecx.add_item_bounds_for_hidden_type(candidate_key, param_env, candidate_ty);
+                    ecx.add_item_bounds_for_hidden_type(
+                        candidate_key.def_id.to_def_id(),
+                        candidate_key.substs,
+                        param_env,
+                        candidate_ty,
+                    );
                     ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
                 },
                 |r| CandidateKind::Candidate { name: "opaque type storage".into(), result: *r },
diff --git a/compiler/rustc_trait_selection/src/solve/opaques.rs b/compiler/rustc_trait_selection/src/solve/opaques.rs
index 538c16c8ce2..16194f5ad69 100644
--- a/compiler/rustc_trait_selection/src/solve/opaques.rs
+++ b/compiler/rustc_trait_selection/src/solve/opaques.rs
@@ -20,8 +20,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 let Some(opaque_ty_def_id) = opaque_ty.def_id.as_local() else {
                     return Err(NoSolution);
                 };
-                let opaque_ty =
-                    ty::OpaqueTypeKey { def_id: opaque_ty_def_id, substs: opaque_ty.substs };
                 // FIXME: at some point we should call queries without defining
                 // new opaque types but having the existing opaque type definitions.
                 // This will require moving this below "Prefer opaques registered already".
@@ -41,7 +39,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                     Ok(()) => {}
                 }
                 // Prefer opaques registered already.
-                let matches = self.unify_existing_opaque_tys(goal.param_env, opaque_ty, expected);
+                let opaque_type_key =
+                    ty::OpaqueTypeKey { def_id: opaque_ty_def_id, substs: opaque_ty.substs };
+                let matches =
+                    self.unify_existing_opaque_tys(goal.param_env, opaque_type_key, expected);
                 if !matches.is_empty() {
                     if let Some(response) = self.try_merge_responses(&matches) {
                         return Ok(response);
@@ -50,11 +51,24 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                     }
                 }
                 // Otherwise, define a new opaque type
-                self.insert_hidden_type(opaque_ty, goal.param_env, expected)?;
-                self.add_item_bounds_for_hidden_type(opaque_ty, goal.param_env, expected);
+                self.insert_hidden_type(opaque_type_key, goal.param_env, expected)?;
+                self.add_item_bounds_for_hidden_type(
+                    opaque_ty.def_id,
+                    opaque_ty.substs,
+                    goal.param_env,
+                    expected,
+                );
                 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
             }
             (Reveal::UserFacing, SolverMode::Coherence) => {
+                // An impossible opaque type bound is the only way this goal will fail
+                // e.g. assigning `impl Copy := NotCopy`
+                self.add_item_bounds_for_hidden_type(
+                    opaque_ty.def_id,
+                    opaque_ty.substs,
+                    goal.param_env,
+                    expected,
+                );
                 self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
             }
             (Reveal::All, _) => {
diff --git a/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs b/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
index b97e444c6d0..386b77d4d16 100644
--- a/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
+++ b/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
@@ -1,6 +1,8 @@
 // Regression test for issue #76202
 // Tests that we don't ICE when we have a trait impl on a TAIT.
 
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
 // check-pass
 
 #![feature(type_alias_impl_trait)]