Rollup merge of #99038 - jackh726:earlybinder-cleanup, r=lcnr
Some more `EarlyBinder` cleanups First commit has a couple unrelated cleanups, but otherwise each commit is self-explanatory r? rust-lang/types
This commit is contained in:
commit
c0bcbe8a6e
12 changed files with 57 additions and 45 deletions
|
@ -85,10 +85,10 @@ impl GenericParamDef {
|
|||
) -> Option<EarlyBinder<ty::GenericArg<'tcx>>> {
|
||||
match self.kind {
|
||||
GenericParamDefKind::Type { has_default, .. } if has_default => {
|
||||
Some(EarlyBinder(tcx.type_of(self.def_id).into()))
|
||||
Some(tcx.bound_type_of(self.def_id).map_bound(|t| t.into()))
|
||||
}
|
||||
GenericParamDefKind::Const { has_default } if has_default => {
|
||||
Some(EarlyBinder(tcx.const_param_default(self.def_id).into()))
|
||||
Some(tcx.bound_const_param_default(self.def_id).map_bound(|c| c.into()))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
|
|
@ -932,6 +932,10 @@ impl<T> EarlyBinder<T> {
|
|||
let value = f(self.0)?;
|
||||
Ok(EarlyBinder(value))
|
||||
}
|
||||
|
||||
pub fn rebind<U>(&self, value: U) -> EarlyBinder<U> {
|
||||
EarlyBinder(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> EarlyBinder<Option<T>> {
|
||||
|
|
|
@ -676,6 +676,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
) -> ty::EarlyBinder<&'tcx ty::List<ty::Predicate<'tcx>>> {
|
||||
ty::EarlyBinder(self.item_bounds(def_id))
|
||||
}
|
||||
|
||||
pub fn bound_const_param_default(self, def_id: DefId) -> ty::EarlyBinder<ty::Const<'tcx>> {
|
||||
ty::EarlyBinder(self.const_param_default(def_id))
|
||||
}
|
||||
}
|
||||
|
||||
struct OpaqueTypeExpander<'tcx> {
|
||||
|
|
|
@ -537,13 +537,12 @@ fn build_call_shim<'tcx>(
|
|||
};
|
||||
|
||||
let def_id = instance.def_id();
|
||||
let sig = tcx.fn_sig(def_id);
|
||||
let mut sig = tcx.erase_late_bound_regions(sig);
|
||||
let sig = tcx.bound_fn_sig(def_id);
|
||||
let sig = sig.map_bound(|sig| tcx.erase_late_bound_regions(sig));
|
||||
|
||||
assert_eq!(sig_substs.is_some(), !instance.has_polymorphic_mir_body());
|
||||
if let Some(sig_substs) = sig_substs {
|
||||
sig = EarlyBinder(sig).subst(tcx, sig_substs);
|
||||
}
|
||||
let mut sig =
|
||||
if let Some(sig_substs) = sig_substs { sig.subst(tcx, sig_substs) } else { sig.0 };
|
||||
|
||||
if let CallKind::Indirect(fnty) = call_kind {
|
||||
// `sig` determines our local decls, and thus the callee type in the `Call` terminator. This
|
||||
|
|
|
@ -12,7 +12,7 @@ use rustc_index::bit_set::GrowableBitSet;
|
|||
use rustc_infer::infer::InferOk;
|
||||
use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
|
||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef};
|
||||
use rustc_middle::ty::{self, EarlyBinder, GenericParamDefKind, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, GenericParamDefKind, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{ToPolyTraitRef, ToPredicate};
|
||||
use rustc_span::def_id::DefId;
|
||||
|
||||
|
@ -555,7 +555,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter());
|
||||
let bound =
|
||||
EarlyBinder(bound.0.kind().skip_binder()).subst(tcx, assoc_ty_substs);
|
||||
bound.map_bound(|b| b.kind().skip_binder()).subst(tcx, assoc_ty_substs);
|
||||
tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars))
|
||||
};
|
||||
let normalized_bound = normalize_with_depth_to(
|
||||
|
|
|
@ -550,7 +550,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
GenericParamDefKind::Const { has_default } => {
|
||||
let ty = tcx.at(self.span).type_of(param.def_id);
|
||||
if !infer_args && has_default {
|
||||
EarlyBinder(tcx.const_param_default(param.def_id))
|
||||
tcx.bound_const_param_default(param.def_id)
|
||||
.subst(tcx, substs.unwrap())
|
||||
.into()
|
||||
} else {
|
||||
|
|
|
@ -1426,7 +1426,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
GenericParamDefKind::Const { has_default } => {
|
||||
if !infer_args && has_default {
|
||||
EarlyBinder(tcx.const_param_default(param.def_id))
|
||||
tcx.bound_const_param_default(param.def_id)
|
||||
.subst(tcx, substs.unwrap())
|
||||
.into()
|
||||
} else {
|
||||
|
|
|
@ -21,9 +21,7 @@ use rustc_middle::middle::stability;
|
|||
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
|
||||
use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
|
||||
use rustc_middle::ty::GenericParamDefKind;
|
||||
use rustc_middle::ty::{
|
||||
self, EarlyBinder, ParamEnvAnd, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitable,
|
||||
};
|
||||
use rustc_middle::ty::{self, ParamEnvAnd, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitable};
|
||||
use rustc_session::lint;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::lev_distance::{
|
||||
|
@ -713,7 +711,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
let (impl_ty, impl_substs) = self.impl_ty_and_substs(impl_def_id);
|
||||
let impl_ty = EarlyBinder(impl_ty).subst(self.tcx, impl_substs);
|
||||
let impl_ty = impl_ty.subst(self.tcx, impl_substs);
|
||||
|
||||
debug!("impl_ty: {:?}", impl_ty);
|
||||
|
||||
|
@ -1811,9 +1809,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
self.erase_late_bound_regions(xform_fn_sig)
|
||||
}
|
||||
|
||||
/// Gets the type of an impl and generate substitutions with placeholders.
|
||||
fn impl_ty_and_substs(&self, impl_def_id: DefId) -> (Ty<'tcx>, SubstsRef<'tcx>) {
|
||||
(self.tcx.type_of(impl_def_id), self.fresh_item_substs(impl_def_id))
|
||||
/// Gets the type of an impl and generate substitutions with inference vars.
|
||||
fn impl_ty_and_substs(
|
||||
&self,
|
||||
impl_def_id: DefId,
|
||||
) -> (ty::EarlyBinder<Ty<'tcx>>, SubstsRef<'tcx>) {
|
||||
(self.tcx.bound_type_of(impl_def_id), self.fresh_item_substs(impl_def_id))
|
||||
}
|
||||
|
||||
fn fresh_item_substs(&self, def_id: DefId) -> SubstsRef<'tcx> {
|
||||
|
|
|
@ -6,7 +6,7 @@ use super::utils::*;
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct ExplicitPredicatesMap<'tcx> {
|
||||
map: FxHashMap<DefId, RequiredPredicates<'tcx>>,
|
||||
map: FxHashMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
|
||||
}
|
||||
|
||||
impl<'tcx> ExplicitPredicatesMap<'tcx> {
|
||||
|
@ -14,11 +14,11 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
|
|||
ExplicitPredicatesMap { map: FxHashMap::default() }
|
||||
}
|
||||
|
||||
pub fn explicit_predicates_of(
|
||||
pub(crate) fn explicit_predicates_of(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
) -> &RequiredPredicates<'tcx> {
|
||||
) -> &ty::EarlyBinder<RequiredPredicates<'tcx>> {
|
||||
self.map.entry(def_id).or_insert_with(|| {
|
||||
let predicates = if def_id.is_local() {
|
||||
tcx.explicit_predicates_of(def_id)
|
||||
|
@ -63,7 +63,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
required_predicates
|
||||
ty::EarlyBinder(required_predicates)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use rustc_data_structures::fx::FxHashMap;
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
|
||||
use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_span::Span;
|
||||
|
||||
use super::explicit::ExplicitPredicatesMap;
|
||||
|
@ -13,20 +13,19 @@ use super::utils::*;
|
|||
/// `global_inferred_outlives`: this is initially the empty map that
|
||||
/// was generated by walking the items in the crate. This will
|
||||
/// now be filled with inferred predicates.
|
||||
pub fn infer_predicates<'tcx>(
|
||||
pub(super) fn infer_predicates<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
explicit_map: &mut ExplicitPredicatesMap<'tcx>,
|
||||
) -> FxHashMap<DefId, RequiredPredicates<'tcx>> {
|
||||
) -> FxHashMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>> {
|
||||
debug!("infer_predicates");
|
||||
|
||||
let mut predicates_added = true;
|
||||
let mut explicit_map = ExplicitPredicatesMap::new();
|
||||
|
||||
let mut global_inferred_outlives = FxHashMap::default();
|
||||
|
||||
// If new predicates were added then we need to re-calculate
|
||||
// all crates since there could be new implied predicates.
|
||||
while predicates_added {
|
||||
predicates_added = false;
|
||||
'outer: loop {
|
||||
let mut predicates_added = false;
|
||||
|
||||
// Visit all the crates and infer predicates
|
||||
for id in tcx.hir().items() {
|
||||
|
@ -53,9 +52,9 @@ pub fn infer_predicates<'tcx>(
|
|||
tcx,
|
||||
field_ty,
|
||||
field_span,
|
||||
&mut global_inferred_outlives,
|
||||
&global_inferred_outlives,
|
||||
&mut item_required_predicates,
|
||||
explicit_map,
|
||||
&mut explicit_map,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -70,12 +69,17 @@ pub fn infer_predicates<'tcx>(
|
|||
// we walk the crates again and re-calculate predicates for all
|
||||
// items.
|
||||
let item_predicates_len: usize =
|
||||
global_inferred_outlives.get(&item_did.to_def_id()).map_or(0, |p| p.len());
|
||||
global_inferred_outlives.get(&item_did.to_def_id()).map_or(0, |p| p.0.len());
|
||||
if item_required_predicates.len() > item_predicates_len {
|
||||
predicates_added = true;
|
||||
global_inferred_outlives.insert(item_did.to_def_id(), item_required_predicates);
|
||||
global_inferred_outlives
|
||||
.insert(item_did.to_def_id(), ty::EarlyBinder(item_required_predicates));
|
||||
}
|
||||
}
|
||||
|
||||
if !predicates_added {
|
||||
break 'outer;
|
||||
}
|
||||
}
|
||||
|
||||
global_inferred_outlives
|
||||
|
@ -85,7 +89,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
|||
tcx: TyCtxt<'tcx>,
|
||||
field_ty: Ty<'tcx>,
|
||||
field_span: Span,
|
||||
global_inferred_outlives: &FxHashMap<DefId, RequiredPredicates<'tcx>>,
|
||||
global_inferred_outlives: &FxHashMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
|
||||
required_predicates: &mut RequiredPredicates<'tcx>,
|
||||
explicit_map: &mut ExplicitPredicatesMap<'tcx>,
|
||||
) {
|
||||
|
@ -133,11 +137,13 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
|||
// 'a` holds for `Foo`.
|
||||
debug!("Adt");
|
||||
if let Some(unsubstituted_predicates) = global_inferred_outlives.get(&def.did()) {
|
||||
for (unsubstituted_predicate, &span) in unsubstituted_predicates {
|
||||
for (unsubstituted_predicate, &span) in &unsubstituted_predicates.0 {
|
||||
// `unsubstituted_predicate` is `U: 'b` in the
|
||||
// example above. So apply the substitution to
|
||||
// get `T: 'a` (or `predicate`):
|
||||
let predicate = EarlyBinder(*unsubstituted_predicate).subst(tcx, substs);
|
||||
let predicate = unsubstituted_predicates
|
||||
.rebind(*unsubstituted_predicate)
|
||||
.subst(tcx, substs);
|
||||
insert_outlives_predicate(
|
||||
tcx,
|
||||
predicate.0,
|
||||
|
@ -224,7 +230,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
|||
/// will give us `U: 'static` and `U: Foo`. The latter we
|
||||
/// can ignore, but we will want to process `U: 'static`,
|
||||
/// applying the substitution as above.
|
||||
pub fn check_explicit_predicates<'tcx>(
|
||||
fn check_explicit_predicates<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
substs: &[GenericArg<'tcx>],
|
||||
|
@ -242,7 +248,7 @@ pub fn check_explicit_predicates<'tcx>(
|
|||
);
|
||||
let explicit_predicates = explicit_map.explicit_predicates_of(tcx, def_id);
|
||||
|
||||
for (outlives_predicate, &span) in explicit_predicates {
|
||||
for (outlives_predicate, &span) in &explicit_predicates.0 {
|
||||
debug!("outlives_predicate = {:?}", &outlives_predicate);
|
||||
|
||||
// Careful: If we are inferring the effects of a `dyn Trait<..>`
|
||||
|
@ -287,7 +293,7 @@ pub fn check_explicit_predicates<'tcx>(
|
|||
continue;
|
||||
}
|
||||
|
||||
let predicate = EarlyBinder(*outlives_predicate).subst(tcx, substs);
|
||||
let predicate = explicit_predicates.rebind(*outlives_predicate).subst(tcx, substs);
|
||||
debug!("predicate = {:?}", &predicate);
|
||||
insert_outlives_predicate(tcx, predicate.0, predicate.1, span, required_predicates);
|
||||
}
|
||||
|
|
|
@ -88,9 +88,7 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> {
|
|||
// for the type.
|
||||
|
||||
// Compute the inferred predicates
|
||||
let mut exp_map = explicit::ExplicitPredicatesMap::new();
|
||||
|
||||
let global_inferred_outlives = implicit_infer::infer_predicates(tcx, &mut exp_map);
|
||||
let global_inferred_outlives = implicit_infer::infer_predicates(tcx);
|
||||
|
||||
// Convert the inferred predicates into the "collected" form the
|
||||
// global data structure expects.
|
||||
|
@ -100,7 +98,7 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> {
|
|||
let predicates = global_inferred_outlives
|
||||
.iter()
|
||||
.map(|(&def_id, set)| {
|
||||
let predicates = &*tcx.arena.alloc_from_iter(set.iter().filter_map(
|
||||
let predicates = &*tcx.arena.alloc_from_iter(set.0.iter().filter_map(
|
||||
|(ty::OutlivesPredicate(kind1, region2), &span)| {
|
||||
match kind1.unpack() {
|
||||
GenericArgKind::Type(ty1) => Some((
|
||||
|
|
|
@ -7,12 +7,12 @@ use std::collections::BTreeMap;
|
|||
|
||||
/// Tracks the `T: 'a` or `'a: 'a` predicates that we have inferred
|
||||
/// must be added to the struct header.
|
||||
pub type RequiredPredicates<'tcx> =
|
||||
pub(crate) type RequiredPredicates<'tcx> =
|
||||
BTreeMap<ty::OutlivesPredicate<GenericArg<'tcx>, ty::Region<'tcx>>, Span>;
|
||||
|
||||
/// Given a requirement `T: 'a` or `'b: 'a`, deduce the
|
||||
/// outlives_component and add it to `required_predicates`
|
||||
pub fn insert_outlives_predicate<'tcx>(
|
||||
pub(crate) fn insert_outlives_predicate<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
kind: GenericArg<'tcx>,
|
||||
outlived_region: Region<'tcx>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue