Use OpaqueTypeKey in query response

This commit is contained in:
Michael Goulet 2023-05-10 23:41:00 +00:00
parent cba14074bb
commit 6f27876f62
3 changed files with 24 additions and 8 deletions

View File

@ -153,20 +153,22 @@ fn make_query_response<T>(
/// Used by the new solver as that one takes the opaque types at the end of a probe /// Used by the new solver as that one takes the opaque types at the end of a probe
/// to deal with multiple candidates without having to recompute them. /// to deal with multiple candidates without having to recompute them.
pub fn clone_opaque_types_for_query_response(&self) -> Vec<(Ty<'tcx>, Ty<'tcx>)> { pub fn clone_opaque_types_for_query_response(
&self,
) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
self.inner self.inner
.borrow() .borrow()
.opaque_type_storage .opaque_type_storage
.opaque_types .opaque_types
.iter() .iter()
.map(|(k, v)| (self.tcx.mk_opaque(k.def_id.to_def_id(), k.substs), v.hidden_type.ty)) .map(|(k, v)| (*k, v.hidden_type.ty))
.collect() .collect()
} }
fn take_opaque_types_for_query_response(&self) -> Vec<(Ty<'tcx>, Ty<'tcx>)> { fn take_opaque_types_for_query_response(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
std::mem::take(&mut self.inner.borrow_mut().opaque_type_storage.opaque_types) std::mem::take(&mut self.inner.borrow_mut().opaque_type_storage.opaque_types)
.into_iter() .into_iter()
.map(|(k, v)| (self.tcx.mk_opaque(k.def_id.to_def_id(), k.substs), v.hidden_type.ty)) .map(|(k, v)| (k, v.hidden_type.ty))
.collect() .collect()
} }
@ -507,8 +509,22 @@ fn query_response_substitution_guess<R>(
let a = substitute_value(self.tcx, &result_subst, a); let a = substitute_value(self.tcx, &result_subst, a);
let b = substitute_value(self.tcx, &result_subst, b); let b = substitute_value(self.tcx, &result_subst, b);
debug!(?a, ?b, "constrain opaque type"); debug!(?a, ?b, "constrain opaque type");
obligations // We use equate here instead of, for example, just registering the
.extend(self.at(cause, param_env).eq(DefineOpaqueTypes::Yes, a, b)?.obligations); // opaque type's hidden value directly, because we may be instantiating
// a query response that was canonicalized in an InferCtxt that had
// a different defining anchor. In that case, we may have inferred
// `NonLocalOpaque := LocalOpaque` but can only instantiate it in
// the other direction as `LocalOpaque := NonLocalOpaque`. Using eq
// here allows us to try both directions (in `InferCtxt::handle_opaque_type`).
obligations.extend(
self.at(cause, param_env)
.eq(
DefineOpaqueTypes::Yes,
self.tcx.mk_opaque(a.def_id.to_def_id(), a.substs),
b,
)?
.obligations,
);
} }
Ok(InferOk { value: result_subst, obligations }) Ok(InferOk { value: result_subst, obligations })

View File

@ -280,7 +280,7 @@ pub struct QueryResponse<'tcx, R> {
/// should get its hidden type inferred. So we bubble the opaque type /// should get its hidden type inferred. So we bubble the opaque type
/// and the type it was compared against upwards and let the query caller /// and the type it was compared against upwards and let the query caller
/// handle it. /// handle it.
pub opaque_types: Vec<(Ty<'tcx>, Ty<'tcx>)>, pub opaque_types: Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>,
pub value: R, pub value: R,
} }

View File

@ -124,7 +124,7 @@ fn deref(&self) -> &Self::Target {
pub struct ExternalConstraintsData<'tcx> { pub struct ExternalConstraintsData<'tcx> {
// FIXME: implement this. // FIXME: implement this.
pub region_constraints: QueryRegionConstraints<'tcx>, pub region_constraints: QueryRegionConstraints<'tcx>,
pub opaque_types: Vec<(Ty<'tcx>, Ty<'tcx>)>, pub opaque_types: Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>,
} }
// FIXME: Having to clone `region_constraints` for folding feels bad and // FIXME: Having to clone `region_constraints` for folding feels bad and