about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-05-23 00:36:20 +0000
committerMichael Goulet <michael@errs.io>2023-05-25 03:35:14 +0000
commit980da667fec746b6be52447169bc4ff29855c651 (patch)
treec534fab46ee007842b76d37432998f218b26bfb6
parent97c11ffb227c906465d339b36286e6fb99051e3a (diff)
downloadrust-980da667fec746b6be52447169bc4ff29855c651.tar.gz
rust-980da667fec746b6be52447169bc4ff29855c651.zip
Add InferCtxt::register_hidden_type_in_new_solver
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs1
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs23
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt.rs23
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs31
-rw-r--r--compiler/rustc_trait_selection/src/solve/opaques.rs10
5 files changed, 47 insertions, 41 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index b63f51138c3..cf204cff6b3 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -26,7 +26,6 @@ use rustc_middle::mir::tcx::PlaceTy;
 use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::AssertKind;
 use rustc_middle::mir::*;
-use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::adjustment::PointerCast;
 use rustc_middle::ty::cast::CastTy;
 use rustc_middle::ty::subst::{SubstsRef, UserSubsts};
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 38bb5a3143b..9d5ec228d82 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -557,6 +557,29 @@ impl<'tcx> InferCtxt<'tcx> {
         Ok(InferOk { value: (), obligations })
     }
 
+    /// Registers an opaque's hidden type -- only should be used when the opaque
+    /// can be defined. For something more fallible -- checks the anchors, tries
+    /// to unify opaques in both dirs, etc. -- use `InferCtxt::handle_opaque_type`.
+    pub fn register_hidden_type_in_new_solver(
+        &self,
+        opaque_type_key: OpaqueTypeKey<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        hidden_ty: Ty<'tcx>,
+    ) -> InferResult<'tcx, ()> {
+        assert!(self.tcx.trait_solver_next());
+        let origin = self
+            .opaque_type_origin(opaque_type_key.def_id)
+            .expect("should be called for defining usages only");
+        self.register_hidden_type(
+            opaque_type_key,
+            ObligationCause::dummy(),
+            param_env,
+            hidden_ty,
+            origin,
+            true,
+        )
+    }
+
     pub fn add_item_bounds_for_hidden_type(
         &self,
         OpaqueTypeKey { def_id, substs }: OpaqueTypeKey<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
index 32a8bda2663..f91c6727753 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
@@ -1,4 +1,4 @@
-use rustc_hir::def_id::DefId;
+use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_infer::infer::at::ToTrace;
 use rustc_infer::infer::canonical::CanonicalVarValues;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -192,13 +192,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
 
             for &(a, b) in &input.predefined_opaques_in_body.opaque_types {
                 let InferOk { value: (), obligations } = infcx
-                    .handle_opaque_type(
-                        tcx.mk_opaque(a.def_id.to_def_id(), a.substs),
-                        b,
-                        true,
-                        &ObligationCause::dummy(),
-                        input.goal.param_env,
-                    )
+                    .register_hidden_type_in_new_solver(a, input.goal.param_env, b)
                     .expect("expected opaque type instantiation to succeed");
                 // We're only registering opaques already defined by the caller,
                 // so we're not responsible for proving that they satisfy their
@@ -727,19 +721,18 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         }
     }
 
-    pub(super) fn can_define_opaque_ty(&mut self, def_id: DefId) -> bool {
-        let Some(def_id) = def_id.as_local() else { return false; };
+    pub(super) fn can_define_opaque_ty(&mut self, def_id: LocalDefId) -> bool {
         self.infcx.opaque_type_origin(def_id).is_some()
     }
 
     pub(super) fn register_opaque_ty(
         &mut self,
-        a: Ty<'tcx>,
+        a: ty::OpaqueTypeKey<'tcx>,
         b: Ty<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
     ) -> Result<(), NoSolution> {
         let InferOk { value: (), obligations } =
-            self.infcx.handle_opaque_type(a, b, true, &ObligationCause::dummy(), param_env)?;
+            self.infcx.register_hidden_type_in_new_solver(a, param_env, b)?;
         self.add_goals(obligations.into_iter().map(|obligation| obligation.into()));
         Ok(())
     }
@@ -749,17 +742,15 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     pub(super) fn unify_existing_opaque_tys(
         &mut self,
         param_env: ty::ParamEnv<'tcx>,
-        key: ty::AliasTy<'tcx>,
+        key: ty::OpaqueTypeKey<'tcx>,
         ty: Ty<'tcx>,
     ) -> Vec<CanonicalResponse<'tcx>> {
-        let Some(def_id) = key.def_id.as_local() else { return vec![]; };
-
         // FIXME: Super inefficient to be cloning this...
         let opaques = self.infcx.clone_opaque_types_for_query_response();
 
         let mut values = vec![];
         for (candidate_key, candidate_ty) in opaques {
-            if candidate_key.def_id != def_id {
+            if candidate_key.def_id != key.def_id {
                 continue;
             }
             values.extend(self.probe(|ecx| {
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
index 8d12c7edfe3..fdb209fbff8 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
@@ -15,11 +15,11 @@ use rustc_index::IndexVec;
 use rustc_infer::infer::canonical::query_response::make_query_region_constraints;
 use rustc_infer::infer::canonical::CanonicalVarValues;
 use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints};
+use rustc_infer::infer::InferOk;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::solve::{
     ExternalConstraints, ExternalConstraintsData, MaybeCause, PredefinedOpaquesData, QueryInput,
 };
-use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::{self, BoundVar, GenericArgKind, Ty};
 use rustc_span::DUMMY_SP;
 use std::iter;
@@ -179,13 +179,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         let Response { var_values, external_constraints, certainty } =
             response.substitute(self.tcx(), &substitution);
 
-        let mut nested_goals =
-            self.unify_query_var_values(param_env, &original_values, var_values)?;
+        let nested_goals = self.unify_query_var_values(param_env, &original_values, var_values)?;
 
         let ExternalConstraintsData { region_constraints, opaque_types } =
             external_constraints.deref();
         self.register_region_constraints(region_constraints);
-        nested_goals.extend(self.register_opaque_types(param_env, opaque_types)?);
+        self.register_opaque_types(param_env, opaque_types)?;
 
         Ok((certainty, nested_goals))
     }
@@ -310,24 +309,14 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         &mut self,
         param_env: ty::ParamEnv<'tcx>,
         opaque_types: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)],
-    ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
-        let mut nested_goals = vec![];
+    ) -> Result<(), NoSolution> {
         for &(a, b) in opaque_types {
-            nested_goals.extend(
-                self.infcx
-                    .handle_opaque_type(
-                        self.tcx().mk_opaque(a.def_id.to_def_id(), a.substs),
-                        b,
-                        true,
-                        &ObligationCause::dummy(),
-                        param_env,
-                    )?
-                    .into_obligations()
-                    .into_iter()
-                    .map(Goal::from),
-            );
+            let InferOk { value: (), obligations } =
+                self.infcx.register_hidden_type_in_new_solver(a, param_env, b)?;
+            // It's sound to drop these obligations, since the normalizes-to goal
+            // is responsible for proving these obligations.
+            let _ = obligations;
         }
-
-        Ok(nested_goals)
+        Ok(())
     }
 }
diff --git a/compiler/rustc_trait_selection/src/solve/opaques.rs b/compiler/rustc_trait_selection/src/solve/opaques.rs
index f97f54e760e..54557aeb9a2 100644
--- a/compiler/rustc_trait_selection/src/solve/opaques.rs
+++ b/compiler/rustc_trait_selection/src/solve/opaques.rs
@@ -18,10 +18,15 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         match goal.param_env.reveal() {
             Reveal::UserFacing => match self.solver_mode() {
                 SolverMode::Normal => {
+                    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".
-                    if !self.can_define_opaque_ty(opaque_ty.def_id) {
+                    if !self.can_define_opaque_ty(opaque_ty_def_id) {
                         return Err(NoSolution);
                     }
                     // FIXME: This may have issues when the substs contain aliases...
@@ -47,8 +52,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                         }
                     }
                     // Otherwise, define a new opaque type
-                    let opaque_ty = tcx.mk_opaque(opaque_ty.def_id, opaque_ty.substs);
-                    self.register_opaque_ty(expected, opaque_ty, goal.param_env)?;
+                    self.register_opaque_ty(opaque_ty, expected, goal.param_env)?;
                     self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
                 }
                 SolverMode::Coherence => {