Auto merge of #112466 - lcnr:opaque-type-cleanup, r=compiler-errors
opaque type cleanup the commits are pretty self-contained. r? `@compiler-errors` cc `@oli-obk`
This commit is contained in:
commit
34d64ab7a2
7 changed files with 208 additions and 179 deletions
|
@ -15,8 +15,8 @@ use rustc_middle::traits::solve::{
|
|||
};
|
||||
use rustc_middle::traits::DefiningAnchor;
|
||||
use rustc_middle::ty::{
|
||||
self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
||||
TypeVisitor,
|
||||
self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable,
|
||||
TypeVisitableExt, TypeVisitor,
|
||||
};
|
||||
use rustc_span::DUMMY_SP;
|
||||
use std::ops::ControlFlow;
|
||||
|
@ -191,16 +191,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||
.with_opaque_type_inference(canonical_input.value.anchor)
|
||||
.build_with_canonical(DUMMY_SP, &canonical_input);
|
||||
|
||||
for &(a, b) in &input.predefined_opaques_in_body.opaque_types {
|
||||
let InferOk { value: (), obligations } = infcx
|
||||
.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
|
||||
// item bounds, unless we use them in a normalizes-to goal,
|
||||
// which is handled in `EvalCtxt::unify_existing_opaque_tys`.
|
||||
let _ = obligations;
|
||||
}
|
||||
let mut ecx = EvalCtxt {
|
||||
infcx,
|
||||
var_values,
|
||||
|
@ -211,6 +201,15 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||
tainted: Ok(()),
|
||||
};
|
||||
|
||||
for &(key, ty) in &input.predefined_opaques_in_body.opaque_types {
|
||||
ecx.insert_hidden_type(key, input.goal.param_env, ty)
|
||||
.expect("failed to prepopulate opaque types");
|
||||
}
|
||||
|
||||
if !ecx.nested_goals.is_empty() {
|
||||
panic!("prepopulating opaque types shouldn't add goals: {:?}", ecx.nested_goals);
|
||||
}
|
||||
|
||||
let result = ecx.compute_goal(input.goal);
|
||||
|
||||
// When creating a query response we clone the opaque type constraints
|
||||
|
@ -729,18 +728,42 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
self.infcx.opaque_type_origin(def_id).is_some()
|
||||
}
|
||||
|
||||
pub(super) fn register_opaque_ty(
|
||||
pub(super) fn insert_hidden_type(
|
||||
&mut self,
|
||||
a: ty::OpaqueTypeKey<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
opaque_type_key: OpaqueTypeKey<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
hidden_ty: Ty<'tcx>,
|
||||
) -> Result<(), NoSolution> {
|
||||
let InferOk { value: (), obligations } =
|
||||
self.infcx.register_hidden_type_in_new_solver(a, param_env, b)?;
|
||||
self.add_goals(obligations.into_iter().map(|obligation| obligation.into()));
|
||||
let mut obligations = Vec::new();
|
||||
self.infcx.insert_hidden_type(
|
||||
opaque_type_key,
|
||||
&ObligationCause::dummy(),
|
||||
param_env,
|
||||
hidden_ty,
|
||||
true,
|
||||
&mut obligations,
|
||||
)?;
|
||||
self.add_goals(obligations.into_iter().map(|o| o.into()));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn add_item_bounds_for_hidden_type(
|
||||
&mut self,
|
||||
opaque_type_key: OpaqueTypeKey<'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,
|
||||
ObligationCause::dummy(),
|
||||
param_env,
|
||||
hidden_ty,
|
||||
&mut obligations,
|
||||
);
|
||||
self.add_goals(obligations.into_iter().map(|o| o.into()));
|
||||
}
|
||||
|
||||
// Do something for each opaque/hidden pair defined with `def_id` in the
|
||||
// current inference context.
|
||||
pub(super) fn unify_existing_opaque_tys(
|
||||
|
@ -762,15 +785,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
ecx.eq(param_env, a, b)?;
|
||||
}
|
||||
ecx.eq(param_env, candidate_ty, ty)?;
|
||||
let mut obl = vec![];
|
||||
ecx.infcx.add_item_bounds_for_hidden_type(
|
||||
candidate_key,
|
||||
ObligationCause::dummy(),
|
||||
param_env,
|
||||
candidate_ty,
|
||||
&mut obl,
|
||||
);
|
||||
ecx.add_goals(obl.into_iter().map(Into::into));
|
||||
ecx.add_item_bounds_for_hidden_type(candidate_key, param_env, candidate_ty);
|
||||
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ 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,
|
||||
|
@ -321,12 +320,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
param_env: ty::ParamEnv<'tcx>,
|
||||
opaque_types: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)],
|
||||
) -> Result<(), NoSolution> {
|
||||
for &(a, b) in opaque_types {
|
||||
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;
|
||||
for &(key, ty) in opaque_types {
|
||||
self.insert_hidden_type(key, param_env, ty)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -50,7 +50,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
// Otherwise, define a new opaque type
|
||||
self.register_opaque_ty(opaque_ty, expected, goal.param_env)?;
|
||||
self.insert_hidden_type(opaque_ty, goal.param_env, expected)?;
|
||||
self.add_item_bounds_for_hidden_type(opaque_ty, goal.param_env, expected);
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
}
|
||||
(Reveal::UserFacing, SolverMode::Coherence) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue