1
Fork 0

Remove ty::Binder::bind()

Co-authored-by: Noah Lev <camelidcamel@gmail.com>
This commit is contained in:
Yuki Okushi 2021-07-02 18:48:34 +09:00
parent e28a93365a
commit 884053a4b4
No known key found for this signature in database
GPG key ID: DABA5B072961C18A
10 changed files with 26 additions and 122 deletions

View file

@ -754,88 +754,6 @@ impl<'tcx> TyCtxt<'tcx> {
}
}
pub struct BoundVarsCollector<'tcx> {
binder_index: ty::DebruijnIndex,
vars: BTreeMap<u32, ty::BoundVariableKind>,
// We may encounter the same variable at different levels of binding, so
// this can't just be `Ty`
visited: SsoHashSet<(ty::DebruijnIndex, Ty<'tcx>)>,
}
impl<'tcx> BoundVarsCollector<'tcx> {
pub fn new() -> Self {
BoundVarsCollector {
binder_index: ty::INNERMOST,
vars: BTreeMap::new(),
visited: SsoHashSet::default(),
}
}
pub fn into_vars(self, tcx: TyCtxt<'tcx>) -> &'tcx ty::List<ty::BoundVariableKind> {
let max = self.vars.iter().map(|(k, _)| *k).max().unwrap_or_else(|| 0);
for i in 0..max {
if let None = self.vars.get(&i) {
panic!("Unknown variable: {:?}", i);
}
}
tcx.mk_bound_variable_kinds(self.vars.into_iter().map(|(_, v)| v))
}
}
impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> {
type BreakTy = ();
fn visit_binder<T: TypeFoldable<'tcx>>(
&mut self,
t: &Binder<'tcx, T>,
) -> ControlFlow<Self::BreakTy> {
self.binder_index.shift_in(1);
let result = t.super_visit_with(self);
self.binder_index.shift_out(1);
result
}
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
if t.outer_exclusive_binder < self.binder_index
|| !self.visited.insert((self.binder_index, t))
{
return ControlFlow::CONTINUE;
}
use std::collections::btree_map::Entry;
match *t.kind() {
ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => {
match self.vars.entry(bound_ty.var.as_u32()) {
Entry::Vacant(entry) => {
entry.insert(ty::BoundVariableKind::Ty(bound_ty.kind));
}
Entry::Occupied(entry) => match entry.get() {
ty::BoundVariableKind::Ty(_) => {}
_ => bug!("Conflicting bound vars"),
},
}
}
_ => (),
};
t.super_visit_with(self)
}
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
match r {
ty::ReLateBound(index, _br) if *index == self.binder_index => {
// If you hit this, you should be using `Binder::bind_with_vars` or `Binder::rebind`
bug!("Trying to collect bound vars with a bound region: {:?} {:?}", index, _br)
}
_ => (),
};
r.super_visit_with(self)
}
}
pub struct ValidateBoundVars<'tcx> {
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
binder_index: ty::DebruijnIndex,

View file

@ -5,7 +5,6 @@
use self::TyKind::*;
use crate::infer::canonical::Canonical;
use crate::ty::fold::BoundVarsCollector;
use crate::ty::fold::ValidateBoundVars;
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
use crate::ty::InferTy::{self, *};
@ -970,13 +969,6 @@ where
Binder(value, ty::List::empty())
}
/// Wraps `value` in a binder, binding higher-ranked vars (if any).
pub fn bind(value: T, tcx: TyCtxt<'tcx>) -> Binder<'tcx, T> {
let mut collector = BoundVarsCollector::new();
value.visit_with(&mut collector);
Binder(value, collector.into_vars(tcx))
}
pub fn bind_with_vars(value: T, vars: &'tcx List<BoundVariableKind>) -> Binder<'tcx, T> {
if cfg!(debug_assertions) {
let mut validator = ValidateBoundVars::new(vars);

View file

@ -822,12 +822,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
let obligation = Obligation::new(
ObligationCause::dummy(),
param_env,
Binder::bind(
TraitPredicate {
trait_ref: TraitRef::from_method(tcx, trait_id, substs),
},
tcx,
),
Binder::dummy(TraitPredicate { trait_ref }),
);
let implsrc = tcx.infer_ctxt().enter(|infcx| {

View file

@ -1301,7 +1301,7 @@ fn confirm_pointee_candidate<'cx, 'tcx>(
ty: self_ty.ptr_metadata_ty(tcx),
};
confirm_param_env_candidate(selcx, obligation, ty::Binder::bind(predicate, tcx), false)
confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
}
fn confirm_fn_pointer_candidate<'cx, 'tcx>(

View file

@ -1694,7 +1694,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
};
self.one_bound_for_assoc_type(
|| traits::supertraits(tcx, ty::Binder::bind(trait_ref, tcx)),
|| traits::supertraits(tcx, ty::Binder::dummy(trait_ref)),
|| "Self".to_string(),
assoc_ident,
span,

View file

@ -222,12 +222,7 @@ fn compare_predicate_entailment<'tcx>(
let mut selcx = traits::SelectionContext::new(&infcx);
let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_placeholder_substs);
let (impl_m_own_bounds, _) = infcx.replace_bound_vars_with_fresh_vars(
impl_m_span,
infer::HigherRankedType,
ty::Binder::bind(impl_m_own_bounds.predicates, tcx),
);
for predicate in impl_m_own_bounds {
for predicate in impl_m_own_bounds.predicates {
let traits::Normalized { value: predicate, obligations } =
traits::normalize(&mut selcx, param_env, normalize_cause.clone(), predicate);
@ -258,14 +253,14 @@ fn compare_predicate_entailment<'tcx>(
);
let impl_sig =
inh.normalize_associated_types_in(impl_m_span, impl_m_hir_id, param_env, impl_sig);
let impl_fty = tcx.mk_fn_ptr(ty::Binder::bind(impl_sig, tcx));
let impl_fty = tcx.mk_fn_ptr(ty::Binder::dummy(impl_sig));
debug!("compare_impl_method: impl_fty={:?}", impl_fty);
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, tcx.fn_sig(trait_m.def_id));
let trait_sig = trait_sig.subst(tcx, trait_to_placeholder_substs);
let trait_sig =
inh.normalize_associated_types_in(impl_m_span, impl_m_hir_id, param_env, trait_sig);
let trait_fty = tcx.mk_fn_ptr(ty::Binder::bind(trait_sig, tcx));
let trait_fty = tcx.mk_fn_ptr(ty::Binder::dummy(trait_sig));
debug!("compare_impl_method: trait_fty={:?}", trait_fty);

View file

@ -101,6 +101,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
let (method_sig, method_predicates) =
self.normalize_associated_types_in(self.span, (method_sig, method_predicates));
let method_sig = ty::Binder::dummy(method_sig);
// Make sure nobody calls `drop()` explicitly.
self.enforce_illegal_method_limitations(&pick);
@ -119,12 +120,15 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
// We won't add these if we encountered an illegal sized bound, so that we can use
// a custom error in that case.
if illegal_sized_bound.is_none() {
let method_ty = self.tcx.mk_fn_ptr(ty::Binder::bind(method_sig, self.tcx));
self.add_obligations(method_ty, all_substs, method_predicates);
self.add_obligations(self.tcx.mk_fn_ptr(method_sig), all_substs, method_predicates);
}
// Create the final `MethodCallee`.
let callee = MethodCallee { def_id: pick.item.def_id, substs: all_substs, sig: method_sig };
let callee = MethodCallee {
def_id: pick.item.def_id,
substs: all_substs,
sig: method_sig.skip_binder(),
};
ConfirmResult { callee, illegal_sized_bound }
}

View file

@ -404,7 +404,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
obligations.extend(traits::predicates_for_generics(cause.clone(), self.param_env, bounds));
// Also add an obligation for the method type being well-formed.
let method_ty = tcx.mk_fn_ptr(ty::Binder::bind(fn_sig, tcx));
let method_ty = tcx.mk_fn_ptr(ty::Binder::dummy(fn_sig));
debug!(
"lookup_in_trait_adjusted: matched method method_ty={:?} obligation={:?}",
method_ty, obligation

View file

@ -1087,14 +1087,10 @@ fn check_method_receiver<'fcx, 'tcx>(
debug!("check_method_receiver: sig={:?}", sig);
let self_ty = fcx.normalize_associated_types_in(span, self_ty);
let self_ty =
fcx.tcx.liberate_late_bound_regions(method.def_id, ty::Binder::bind(self_ty, fcx.tcx));
let self_ty = fcx.tcx.liberate_late_bound_regions(method.def_id, ty::Binder::dummy(self_ty));
let receiver_ty = sig.inputs()[0];
let receiver_ty = fcx.normalize_associated_types_in(span, receiver_ty);
let receiver_ty =
fcx.tcx.liberate_late_bound_regions(method.def_id, ty::Binder::bind(receiver_ty, fcx.tcx));
if fcx.tcx.features().arbitrary_self_types {
if !receiver_is_valid(fcx, span, receiver_ty, self_ty, true) {

View file

@ -1737,11 +1737,12 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
ty::ReErased => tcx.lifetimes.re_static,
_ => r,
});
let fn_sig = ty::Binder::dummy(fn_sig);
let mut visitor = PlaceholderHirTyCollector::default();
visitor.visit_ty(ty);
let mut diag = bad_placeholder_type(tcx, visitor.0, "return type");
let ret_ty = fn_sig.output();
let ret_ty = fn_sig.skip_binder().output();
if ret_ty != tcx.ty_error() {
if !ret_ty.is_closure() {
let ret_ty_str = match ret_ty.kind() {
@ -1767,7 +1768,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
}
diag.emit();
ty::Binder::bind(fn_sig, tcx)
fn_sig
}
None => <dyn AstConv<'_>>::ty_of_fn(
&icx,
@ -1811,10 +1812,13 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
let ty = tcx.type_of(tcx.hir().get_parent_did(hir_id).to_def_id());
let inputs =
data.fields().iter().map(|f| tcx.type_of(tcx.hir().local_def_id(f.hir_id)));
ty::Binder::bind(
tcx.mk_fn_sig(inputs, ty, false, hir::Unsafety::Normal, abi::Abi::Rust),
tcx,
)
ty::Binder::dummy(tcx.mk_fn_sig(
inputs,
ty,
false,
hir::Unsafety::Normal,
abi::Abi::Rust,
))
}
Expr(&hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => {
@ -2098,7 +2102,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
param.bounds.iter().for_each(|bound| match bound {
hir::GenericBound::Outlives(lt) => {
let bound = <dyn AstConv<'_>>::ast_region_to_region(&icx, &lt, None);
let outlives = ty::Binder::bind(ty::OutlivesPredicate(region, bound), tcx);
let outlives = ty::Binder::dummy(ty::OutlivesPredicate(region, bound));
predicates.insert((outlives.to_predicate(tcx), lt.span));
}
_ => bug!(),