about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection
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 /compiler/rustc_trait_selection
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
Diffstat (limited to 'compiler/rustc_trait_selection')
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt.rs13
-rw-r--r--compiler/rustc_trait_selection/src/solve/opaques.rs24
2 files changed, 29 insertions, 8 deletions
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, _) => {