Use bound_coroutine_witnesses in old solver
This commit is contained in:
parent
8282181e42
commit
ad74788670
5 changed files with 27 additions and 81 deletions
|
@ -324,11 +324,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||||
self.features()
|
self.features()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bound_coroutine_hidden_types(
|
fn coroutine_hidden_types(
|
||||||
self,
|
self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>>> {
|
) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>>> {
|
||||||
self.bound_coroutine_hidden_types(def_id)
|
self.coroutine_hidden_types(def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fn_sig(self, def_id: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
|
fn fn_sig(self, def_id: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
|
||||||
|
|
|
@ -725,27 +725,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the set of types that should be taken into account when checking
|
|
||||||
/// 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(
|
|
||||||
self,
|
|
||||||
def_id: DefId,
|
|
||||||
) -> impl Iterator<Item = ty::EarlyBinder<'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(|decl| ty::EarlyBinder::bind(decl.ty))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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. This properly replaces
|
/// trait bounds on a coroutine's internal state. This properly replaces
|
||||||
/// `ReErased` with new existential bound lifetimes.
|
/// `ReErased` with new existential bound lifetimes.
|
||||||
pub fn bound_coroutine_hidden_types(
|
pub fn coroutine_hidden_types(
|
||||||
self,
|
self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>>> {
|
) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>>> {
|
||||||
|
|
|
@ -74,7 +74,7 @@ where
|
||||||
|
|
||||||
ty::CoroutineWitness(def_id, args) => Ok(ecx
|
ty::CoroutineWitness(def_id, args) => Ok(ecx
|
||||||
.cx()
|
.cx()
|
||||||
.bound_coroutine_hidden_types(def_id)
|
.coroutine_hidden_types(def_id)
|
||||||
.instantiate(cx, args)
|
.instantiate(cx, args)
|
||||||
.map_bound(|tys| tys.to_vec())),
|
.map_bound(|tys| tys.to_vec())),
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ where
|
||||||
// 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
|
||||||
.cx()
|
.cx()
|
||||||
.bound_coroutine_hidden_types(def_id)
|
.coroutine_hidden_types(def_id)
|
||||||
.instantiate(ecx.cx(), args)
|
.instantiate(ecx.cx(), args)
|
||||||
.map_bound(|tys| tys.to_vec())),
|
.map_bound(|tys| tys.to_vec())),
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use std::ops::ControlFlow;
|
||||||
use std::{cmp, iter};
|
use std::{cmp, iter};
|
||||||
|
|
||||||
use hir::def::DefKind;
|
use hir::def::DefKind;
|
||||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
|
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_errors::{Diag, EmissionGuarantee};
|
use rustc_errors::{Diag, EmissionGuarantee};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
@ -25,7 +25,6 @@ use rustc_middle::dep_graph::{DepNodeIndex, dep_kinds};
|
||||||
pub use rustc_middle::traits::select::*;
|
pub use rustc_middle::traits::select::*;
|
||||||
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
|
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
|
||||||
use rustc_middle::ty::error::TypeErrorToStringExt;
|
use rustc_middle::ty::error::TypeErrorToStringExt;
|
||||||
use rustc_middle::ty::fold::fold_regions;
|
|
||||||
use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
|
use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, GenericArgsRef, PolyProjectionPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitableExt,
|
self, GenericArgsRef, PolyProjectionPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitableExt,
|
||||||
|
@ -2199,8 +2198,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::CoroutineWitness(def_id, args) => {
|
ty::CoroutineWitness(def_id, args) => {
|
||||||
let hidden_types = bind_coroutine_hidden_types_above(
|
let hidden_types = rebind_coroutine_witness_types(
|
||||||
self.infcx,
|
self.infcx.tcx,
|
||||||
def_id,
|
def_id,
|
||||||
args,
|
args,
|
||||||
obligation.predicate.bound_vars(),
|
obligation.predicate.bound_vars(),
|
||||||
|
@ -2348,7 +2347,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::CoroutineWitness(def_id, args) => {
|
ty::CoroutineWitness(def_id, args) => {
|
||||||
bind_coroutine_hidden_types_above(self.infcx, def_id, args, t.bound_vars())
|
rebind_coroutine_witness_types(self.infcx.tcx, def_id, args, t.bound_vars())
|
||||||
}
|
}
|
||||||
|
|
||||||
// For `PhantomData<T>`, we pass `T`.
|
// For `PhantomData<T>`, we pass `T`.
|
||||||
|
@ -2843,6 +2842,23 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rebind_coroutine_witness_types<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
def_id: DefId,
|
||||||
|
args: ty::GenericArgsRef<'tcx>,
|
||||||
|
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
|
||||||
|
) -> ty::Binder<'tcx, Vec<Ty<'tcx>>> {
|
||||||
|
let bound_coroutine_types = tcx.coroutine_hidden_types(def_id).skip_binder();
|
||||||
|
let shifted_coroutine_types =
|
||||||
|
tcx.shift_bound_var_indices(bound_vars.len(), bound_coroutine_types.skip_binder());
|
||||||
|
ty::Binder::bind_with_vars(
|
||||||
|
ty::EarlyBinder::bind(shifted_coroutine_types.to_vec()).instantiate(tcx, args),
|
||||||
|
tcx.mk_bound_variable_kinds_from_iter(
|
||||||
|
bound_vars.iter().chain(bound_coroutine_types.bound_vars()),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> {
|
impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> {
|
||||||
fn list(&'o self) -> TraitObligationStackList<'o, 'tcx> {
|
fn list(&'o self) -> TraitObligationStackList<'o, 'tcx> {
|
||||||
TraitObligationStackList::with(self)
|
TraitObligationStackList::with(self)
|
||||||
|
@ -3151,56 +3167,3 @@ pub(crate) enum ProjectionMatchesProjection {
|
||||||
Ambiguous,
|
Ambiguous,
|
||||||
No,
|
No,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replace all regions inside the coroutine interior with late bound regions.
|
|
||||||
/// Note that each region slot in the types gets a new fresh late bound region, which means that
|
|
||||||
/// none of the regions inside relate to any other, even if typeck had previously found constraints
|
|
||||||
/// that would cause them to be related.
|
|
||||||
#[instrument(level = "trace", skip(infcx), ret)]
|
|
||||||
fn bind_coroutine_hidden_types_above<'tcx>(
|
|
||||||
infcx: &InferCtxt<'tcx>,
|
|
||||||
def_id: DefId,
|
|
||||||
args: ty::GenericArgsRef<'tcx>,
|
|
||||||
bound_vars: &ty::List<ty::BoundVariableKind>,
|
|
||||||
) -> ty::Binder<'tcx, Vec<Ty<'tcx>>> {
|
|
||||||
let tcx = infcx.tcx;
|
|
||||||
let mut seen_tys = FxHashSet::default();
|
|
||||||
|
|
||||||
let considering_regions = infcx.considering_regions;
|
|
||||||
|
|
||||||
let num_bound_variables = bound_vars.len() as u32;
|
|
||||||
let mut counter = num_bound_variables;
|
|
||||||
|
|
||||||
let hidden_types: Vec<_> = tcx
|
|
||||||
.coroutine_hidden_types(def_id)
|
|
||||||
// Deduplicate tys to avoid repeated work.
|
|
||||||
.filter(|bty| seen_tys.insert(*bty))
|
|
||||||
.map(|mut bty| {
|
|
||||||
// Only remap erased regions if we use them.
|
|
||||||
if considering_regions {
|
|
||||||
bty = bty.map_bound(|ty| {
|
|
||||||
fold_regions(tcx, ty, |r, current_depth| match r.kind() {
|
|
||||||
ty::ReErased => {
|
|
||||||
let br = ty::BoundRegion {
|
|
||||||
var: ty::BoundVar::from_u32(counter),
|
|
||||||
kind: ty::BoundRegionKind::Anon,
|
|
||||||
};
|
|
||||||
counter += 1;
|
|
||||||
ty::Region::new_bound(tcx, current_depth, br)
|
|
||||||
}
|
|
||||||
r => bug!("unexpected region: {r:?}"),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
bty.instantiate(tcx, args)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
|
|
||||||
bound_vars.iter().chain(
|
|
||||||
(num_bound_variables..counter)
|
|
||||||
.map(|_| ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon)),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
ty::Binder::bind_with_vars(hidden_types, bound_vars)
|
|
||||||
}
|
|
||||||
|
|
|
@ -189,7 +189,7 @@ pub trait Interner:
|
||||||
type Features: Features<Self>;
|
type Features: Features<Self>;
|
||||||
fn features(self) -> Self::Features;
|
fn features(self) -> Self::Features;
|
||||||
|
|
||||||
fn bound_coroutine_hidden_types(
|
fn coroutine_hidden_types(
|
||||||
self,
|
self,
|
||||||
def_id: Self::DefId,
|
def_id: Self::DefId,
|
||||||
) -> ty::EarlyBinder<Self, ty::Binder<Self, Self::Tys>>;
|
) -> ty::EarlyBinder<Self, ty::Binder<Self, Self::Tys>>;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue