about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src/solve
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2023-11-09 11:03:28 +0100
committerlcnr <rust@lcnr.de>2023-11-09 11:32:12 +0100
commit1c54494888d79ff17e03a45aeb4d944bfb181ae2 (patch)
tree6414e857301be52e4c2ae0083091a1a4038350cb /compiler/rustc_trait_selection/src/solve
parent1f12f1cc83677a19605c363873456fb42f4268af (diff)
downloadrust-1c54494888d79ff17e03a45aeb4d944bfb181ae2.tar.gz
rust-1c54494888d79ff17e03a45aeb4d944bfb181ae2.zip
only instantiate opaques with rigid types
Diffstat (limited to 'compiler/rustc_trait_selection/src/solve')
-rw-r--r--compiler/rustc_trait_selection/src/solve/mod.rs18
-rw-r--r--compiler/rustc_trait_selection/src/solve/project_goals/opaques.rs21
2 files changed, 22 insertions, 17 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs
index aafcd0694f3..17992d72e25 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -312,26 +312,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             return None;
         }
 
-        let ty::Alias(kind, projection_ty) = *ty.kind() else {
+        let ty::Alias(_, projection_ty) = *ty.kind() else {
             return Some(ty);
         };
 
-        // We do no always define opaque types eagerly to allow non-defining uses in the defining scope.
-        if let (DefineOpaqueTypes::No, ty::AliasKind::Opaque) = (define_opaque_types, kind) {
-            if let Some(def_id) = projection_ty.def_id.as_local() {
-                if self
-                    .unify_existing_opaque_tys(
-                        param_env,
-                        OpaqueTypeKey { def_id, args: projection_ty.args },
-                        self.next_ty_infer(),
-                    )
-                    .is_empty()
-                {
-                    return Some(ty);
-                }
-            }
-        }
-
         // FIXME(@lcnr): If the normalization of the alias adds an inference constraint which
         // causes a previously added goal to fail, then we treat the alias as rigid.
         //
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals/opaques.rs b/compiler/rustc_trait_selection/src/solve/project_goals/opaques.rs
index ebd129f32b9..1fde129c3a0 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals/opaques.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals/opaques.rs
@@ -44,6 +44,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 // Prefer opaques registered already.
                 let opaque_type_key =
                     ty::OpaqueTypeKey { def_id: opaque_ty_def_id, args: opaque_ty.args };
+                // FIXME: This also unifies the previous hidden type with the expected.
+                //
+                // If that fails, we insert `expected` as a new hidden type instead of
+                // eagerly emitting an error.
                 let matches =
                     self.unify_existing_opaque_tys(goal.param_env, opaque_type_key, expected);
                 if !matches.is_empty() {
@@ -53,6 +57,23 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                         return self.flounder(&matches);
                     }
                 }
+
+                let expected = match self.try_normalize_ty(goal.param_env, expected) {
+                    Some(ty) => {
+                        if ty.is_ty_var() {
+                            return self.evaluate_added_goals_and_make_canonical_response(
+                                Certainty::AMBIGUOUS,
+                            );
+                        } else {
+                            ty
+                        }
+                    }
+                    None => {
+                        return self
+                            .evaluate_added_goals_and_make_canonical_response(Certainty::OVERFLOW);
+                    }
+                };
+
                 // Otherwise, define a new opaque type
                 self.insert_hidden_type(opaque_type_key, goal.param_env, expected)?;
                 self.add_item_bounds_for_hidden_type(