Do binder folding eagerly in bound_coroutine_hidden_types
I refuse to fix this in the old solver; its lazy instantiation of binders will be the end of me.
This commit is contained in:
parent
67f1c53c05
commit
bca708b9fa
@ -682,6 +682,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
|
|
||||||
/// Return the set of types that should be taken into account when checking
|
/// Return the set of types that should be taken into account when checking
|
||||||
/// trait bounds on a coroutine's internal state.
|
/// trait bounds on a coroutine's internal state.
|
||||||
|
// FIXME(compiler-errors): We should remove this when the old solver goes away;
|
||||||
|
// and all other usages of this function should go through `bound_coroutine_hidden_types`
|
||||||
|
// instead.
|
||||||
pub fn coroutine_hidden_types(
|
pub fn coroutine_hidden_types(
|
||||||
self,
|
self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
@ -694,6 +697,33 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
.map(|decl| ty::EarlyBinder::bind(decl.ty))
|
.map(|decl| ty::EarlyBinder::bind(decl.ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the set of types that should be taken into account when checking
|
||||||
|
/// trait bounds on a coroutine's internal state. This properly replaces
|
||||||
|
/// `ReErased` with new existential bound lifetimes.
|
||||||
|
pub fn bound_coroutine_hidden_types(
|
||||||
|
self,
|
||||||
|
def_id: DefId,
|
||||||
|
) -> impl Iterator<Item = ty::EarlyBinder<ty::Binder<'tcx, Ty<'tcx>>>> {
|
||||||
|
let coroutine_layout = self.mir_coroutine_witnesses(def_id);
|
||||||
|
coroutine_layout
|
||||||
|
.as_ref()
|
||||||
|
.map_or_else(|| [].iter(), |l| l.field_tys.iter())
|
||||||
|
.filter(|decl| !decl.ignore_for_traits)
|
||||||
|
.map(move |decl| {
|
||||||
|
let mut vars = vec![];
|
||||||
|
let ty = self.fold_regions(decl.ty, |re, debruijn| {
|
||||||
|
assert_eq!(re, self.lifetimes.re_erased);
|
||||||
|
let var = ty::BoundVar::from_usize(vars.len());
|
||||||
|
vars.push(ty::BoundVariableKind::Region(ty::BrAnon));
|
||||||
|
ty::Region::new_bound(self, debruijn, ty::BoundRegion { var, kind: ty::BrAnon })
|
||||||
|
});
|
||||||
|
ty::EarlyBinder::bind(ty::Binder::bind_with_vars(
|
||||||
|
ty,
|
||||||
|
self.mk_bound_variable_kinds(&vars),
|
||||||
|
))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Expands the given impl trait type, stopping if the type is recursive.
|
/// Expands the given impl trait type, stopping if the type is recursive.
|
||||||
#[instrument(skip(self), level = "debug", ret)]
|
#[instrument(skip(self), level = "debug", ret)]
|
||||||
pub fn try_expand_impl_trait_type(
|
pub fn try_expand_impl_trait_type(
|
||||||
@ -998,8 +1028,10 @@ impl<'tcx> OpaqueTypeExpander<'tcx> {
|
|||||||
Some(expanded_ty) => *expanded_ty,
|
Some(expanded_ty) => *expanded_ty,
|
||||||
None => {
|
None => {
|
||||||
if matches!(self.inspect_coroutine_fields, InspectCoroutineFields::Yes) {
|
if matches!(self.inspect_coroutine_fields, InspectCoroutineFields::Yes) {
|
||||||
for bty in self.tcx.coroutine_hidden_types(def_id) {
|
for bty in self.tcx.bound_coroutine_hidden_types(def_id) {
|
||||||
let hidden_ty = bty.instantiate(self.tcx, args);
|
let hidden_ty = self.tcx.instantiate_bound_regions_with_erased(
|
||||||
|
bty.instantiate(self.tcx, args),
|
||||||
|
);
|
||||||
self.fold_ty(hidden_ty);
|
self.fold_ty(hidden_ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use rustc_hir::{def_id::DefId, Movability, Mutability};
|
|||||||
use rustc_infer::traits::query::NoSolution;
|
use rustc_infer::traits::query::NoSolution;
|
||||||
use rustc_middle::traits::solve::Goal;
|
use rustc_middle::traits::solve::Goal;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
|
self, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
|
||||||
};
|
};
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
|
|
||||||
@ -73,8 +73,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
|
|||||||
|
|
||||||
ty::CoroutineWitness(def_id, args) => Ok(ecx
|
ty::CoroutineWitness(def_id, args) => Ok(ecx
|
||||||
.tcx()
|
.tcx()
|
||||||
.coroutine_hidden_types(def_id)
|
.bound_coroutine_hidden_types(def_id)
|
||||||
.map(|bty| replace_erased_lifetimes_with_bound_vars(tcx, bty.instantiate(tcx, args)))
|
.map(|bty| bty.instantiate(tcx, args))
|
||||||
.collect()),
|
.collect()),
|
||||||
|
|
||||||
// For `PhantomData<T>`, we pass `T`.
|
// For `PhantomData<T>`, we pass `T`.
|
||||||
@ -93,26 +93,6 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(in crate::solve) fn replace_erased_lifetimes_with_bound_vars<'tcx>(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
ty: Ty<'tcx>,
|
|
||||||
) -> ty::Binder<'tcx, Ty<'tcx>> {
|
|
||||||
let mut counter = 0;
|
|
||||||
let ty = tcx.fold_regions(ty, |r, current_depth| match r.kind() {
|
|
||||||
ty::ReErased => {
|
|
||||||
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(counter), kind: ty::BrAnon };
|
|
||||||
counter += 1;
|
|
||||||
ty::Region::new_bound(tcx, current_depth, br)
|
|
||||||
}
|
|
||||||
// All free regions should be erased here.
|
|
||||||
r => bug!("unexpected region: {r:?}"),
|
|
||||||
});
|
|
||||||
let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
|
|
||||||
(0..counter).map(|_| ty::BoundVariableKind::Region(ty::BrAnon)),
|
|
||||||
);
|
|
||||||
ty::Binder::bind_with_vars(ty, bound_vars)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(ecx), ret)]
|
#[instrument(level = "debug", skip(ecx), ret)]
|
||||||
pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
|
pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
|
||||||
ecx: &EvalCtxt<'_, 'tcx>,
|
ecx: &EvalCtxt<'_, 'tcx>,
|
||||||
@ -240,13 +220,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
|
|||||||
// impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types
|
// impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types
|
||||||
ty::CoroutineWitness(def_id, args) => Ok(ecx
|
ty::CoroutineWitness(def_id, args) => Ok(ecx
|
||||||
.tcx()
|
.tcx()
|
||||||
.coroutine_hidden_types(def_id)
|
.bound_coroutine_hidden_types(def_id)
|
||||||
.map(|bty| {
|
.map(|bty| bty.instantiate(ecx.tcx(), args))
|
||||||
replace_erased_lifetimes_with_bound_vars(
|
|
||||||
ecx.tcx(),
|
|
||||||
bty.instantiate(ecx.tcx(), args),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect()),
|
.collect()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
|
|||||||
use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData};
|
use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, GenericArgs, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, ToPredicate,
|
self, GenericArgs, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, ToPredicate,
|
||||||
TraitPredicate, Ty, TyCtxt, TypeVisitableExt,
|
TraitPredicate, Ty, TyCtxt,
|
||||||
};
|
};
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
|
|
||||||
@ -1438,10 +1438,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
}
|
}
|
||||||
ty::CoroutineWitness(def_id, args) => {
|
ty::CoroutineWitness(def_id, args) => {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
stack.extend(tcx.coroutine_hidden_types(def_id).map(|bty| {
|
stack.extend(tcx.bound_coroutine_hidden_types(def_id).map(|bty| {
|
||||||
let ty = bty.instantiate(tcx, args);
|
self.infcx.enter_forall_and_leak_universe(bty.instantiate(tcx, args))
|
||||||
debug_assert!(!ty.has_bound_regions());
|
|
||||||
ty
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user