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:
bors 2023-06-11 03:42:14 +00:00
commit 34d64ab7a2
7 changed files with 208 additions and 179 deletions

View file

@ -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)
}));
}

View file

@ -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(())
}

View file

@ -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) => {