Use map_bound(_ref) instead of Binder::bind when possible
This commit is contained in:
parent
a78a62fc99
commit
dd5c9bf139
24 changed files with 173 additions and 143 deletions
|
@ -642,7 +642,8 @@ impl AutoTraitFinder<'tcx> {
|
|||
// We check this by calling is_of_param on the relevant types
|
||||
// from the various possible predicates
|
||||
|
||||
match predicate.skip_binders() {
|
||||
let bound_predicate = predicate.bound_atom(select.infcx().tcx);
|
||||
match bound_predicate.skip_binder() {
|
||||
ty::PredicateAtom::Trait(p, _) => {
|
||||
if self.is_param_no_infer(p.trait_ref.substs)
|
||||
&& !only_projections
|
||||
|
@ -650,10 +651,10 @@ impl AutoTraitFinder<'tcx> {
|
|||
{
|
||||
self.add_user_pred(computed_preds, predicate);
|
||||
}
|
||||
predicates.push_back(ty::Binder::bind(p));
|
||||
predicates.push_back(bound_predicate.map_bound_ref(|_| p));
|
||||
}
|
||||
ty::PredicateAtom::Projection(p) => {
|
||||
let p = ty::Binder::bind(p);
|
||||
let p = bound_predicate.map_bound_ref(|_| p);
|
||||
debug!(
|
||||
"evaluate_nested_obligations: examining projection predicate {:?}",
|
||||
predicate
|
||||
|
@ -783,13 +784,13 @@ impl AutoTraitFinder<'tcx> {
|
|||
}
|
||||
}
|
||||
ty::PredicateAtom::RegionOutlives(binder) => {
|
||||
let binder = ty::Binder::bind(binder);
|
||||
let binder = bound_predicate.map_bound_ref(|_| binder);
|
||||
if select.infcx().region_outlives_predicate(&dummy_cause, binder).is_err() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ty::PredicateAtom::TypeOutlives(binder) => {
|
||||
let binder = ty::Binder::bind(binder);
|
||||
let binder = bound_predicate.map_bound_ref(|_| binder);
|
||||
match (
|
||||
binder.no_bound_vars(),
|
||||
binder.map_bound_ref(|pred| pred.0).no_bound_vars(),
|
||||
|
|
|
@ -255,9 +255,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
return;
|
||||
}
|
||||
|
||||
match obligation.predicate.skip_binders() {
|
||||
let bound_predicate = obligation.predicate.bound_atom(self.tcx);
|
||||
match bound_predicate.skip_binder() {
|
||||
ty::PredicateAtom::Trait(trait_predicate, _) => {
|
||||
let trait_predicate = ty::Binder::bind(trait_predicate);
|
||||
let trait_predicate = bound_predicate.map_bound_ref(|_| trait_predicate);
|
||||
let trait_predicate = self.resolve_vars_if_possible(&trait_predicate);
|
||||
|
||||
if self.tcx.sess.has_errors() && trait_predicate.references_error() {
|
||||
|
@ -531,7 +532,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
ty::PredicateAtom::RegionOutlives(predicate) => {
|
||||
let predicate = ty::Binder::bind(predicate);
|
||||
let predicate = bound_predicate.map_bound_ref(|_| predicate);
|
||||
let predicate = self.resolve_vars_if_possible(&predicate);
|
||||
let err = self
|
||||
.region_outlives_predicate(&obligation.cause, predicate)
|
||||
|
@ -1078,9 +1079,10 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// FIXME: It should be possible to deal with `ForAll` in a cleaner way.
|
||||
let (cond, error) = match (cond.skip_binders(), error.skip_binders()) {
|
||||
let bound_error = error.bound_atom(self.tcx);
|
||||
let (cond, error) = match (cond.skip_binders(), bound_error.skip_binder()) {
|
||||
(ty::PredicateAtom::Trait(..), ty::PredicateAtom::Trait(error, _)) => {
|
||||
(cond, ty::Binder::bind(error))
|
||||
(cond, bound_error.map_bound_ref(|_| error))
|
||||
}
|
||||
_ => {
|
||||
// FIXME: make this work in other cases too.
|
||||
|
@ -1089,9 +1091,10 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
};
|
||||
|
||||
for obligation in super::elaborate_predicates(self.tcx, std::iter::once(cond)) {
|
||||
if let ty::PredicateAtom::Trait(implication, _) = obligation.predicate.skip_binders() {
|
||||
let bound_predicate = obligation.predicate.bound_atom(self.tcx);
|
||||
if let ty::PredicateAtom::Trait(implication, _) = bound_predicate.skip_binder() {
|
||||
let error = error.to_poly_trait_ref();
|
||||
let implication = ty::Binder::bind(implication.trait_ref);
|
||||
let implication = bound_predicate.map_bound_ref(|_| implication.trait_ref);
|
||||
// FIXME: I'm just not taking associated types at all here.
|
||||
// Eventually I'll need to implement param-env-aware
|
||||
// `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic.
|
||||
|
@ -1169,12 +1172,13 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
//
|
||||
// this can fail if the problem was higher-ranked, in which
|
||||
// cause I have no idea for a good error message.
|
||||
if let ty::PredicateAtom::Projection(data) = predicate.skip_binders() {
|
||||
let bound_predicate = predicate.bound_atom(self.tcx);
|
||||
if let ty::PredicateAtom::Projection(data) = bound_predicate.skip_binder() {
|
||||
let mut selcx = SelectionContext::new(self);
|
||||
let (data, _) = self.replace_bound_vars_with_fresh_vars(
|
||||
obligation.cause.span,
|
||||
infer::LateBoundRegionConversionTime::HigherRankedType,
|
||||
&ty::Binder::bind(data),
|
||||
&bound_predicate.map_bound_ref(|_| data),
|
||||
);
|
||||
let mut obligations = vec![];
|
||||
let normalized_ty = super::normalize_projection_type(
|
||||
|
@ -1455,10 +1459,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
return;
|
||||
}
|
||||
|
||||
let mut err = match predicate.skip_binders() {
|
||||
let bound_predicate = predicate.bound_atom(self.tcx);
|
||||
let mut err = match bound_predicate.skip_binder() {
|
||||
ty::PredicateAtom::Trait(data, _) => {
|
||||
let trait_ref = ty::Binder::bind(data.trait_ref);
|
||||
let self_ty = trait_ref.skip_binder().self_ty();
|
||||
let self_ty = data.trait_ref.self_ty();
|
||||
let trait_ref = bound_predicate.map_bound_ref(|_| data.trait_ref);
|
||||
debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind(), trait_ref);
|
||||
|
||||
if predicate.references_error() {
|
||||
|
@ -1582,7 +1587,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282)
|
||||
}
|
||||
ty::PredicateAtom::Projection(data) => {
|
||||
let trait_ref = ty::Binder::bind(data).to_poly_trait_ref(self.tcx);
|
||||
let trait_ref = bound_predicate.map_bound_ref(|_| data).to_poly_trait_ref(self.tcx);
|
||||
let self_ty = trait_ref.skip_binder().self_ty();
|
||||
let ty = data.ty;
|
||||
if predicate.references_error() {
|
||||
|
|
|
@ -353,7 +353,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
// This means we need to pass it the bound version of our
|
||||
// predicate.
|
||||
ty::PredicateAtom::Trait(trait_ref, _constness) => {
|
||||
let trait_obligation = obligation.with(Binder::bind(trait_ref));
|
||||
let trait_obligation = obligation.with(binder.map_bound_ref(|_| trait_ref));
|
||||
|
||||
self.process_trait_obligation(
|
||||
obligation,
|
||||
|
@ -362,7 +362,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
)
|
||||
}
|
||||
ty::PredicateAtom::Projection(data) => {
|
||||
let project_obligation = obligation.with(Binder::bind(data));
|
||||
let project_obligation = obligation.with(binder.map_bound_ref(|_| data));
|
||||
|
||||
self.process_projection_obligation(
|
||||
project_obligation,
|
||||
|
|
|
@ -623,7 +623,8 @@ fn prune_cache_value_obligations<'a, 'tcx>(
|
|||
.obligations
|
||||
.iter()
|
||||
.filter(|obligation| {
|
||||
match obligation.predicate.skip_binders() {
|
||||
let bound_predicate = obligation.predicate.bound_atom(infcx.tcx);
|
||||
match bound_predicate.skip_binder() {
|
||||
// We found a `T: Foo<X = U>` predicate, let's check
|
||||
// if `U` references any unresolved type
|
||||
// variables. In principle, we only care if this
|
||||
|
@ -633,9 +634,9 @@ fn prune_cache_value_obligations<'a, 'tcx>(
|
|||
// indirect obligations (e.g., we project to `?0`,
|
||||
// but we have `T: Foo<X = ?1>` and `?1: Bar<X =
|
||||
// ?0>`).
|
||||
ty::PredicateAtom::Projection(data) => {
|
||||
infcx.unresolved_type_vars(&ty::Binder::bind(data.ty)).is_some()
|
||||
}
|
||||
ty::PredicateAtom::Projection(data) => infcx
|
||||
.unresolved_type_vars(&bound_predicate.map_bound_ref(|_| data.ty))
|
||||
.is_some(),
|
||||
|
||||
// We are only interested in `T: Foo<X = U>` predicates, whre
|
||||
// `U` references one of `unresolved_type_vars`. =)
|
||||
|
@ -907,8 +908,9 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
|
|||
let infcx = selcx.infcx();
|
||||
for predicate in env_predicates {
|
||||
debug!(?predicate);
|
||||
let bound_predicate = predicate.bound_atom(infcx.tcx);
|
||||
if let ty::PredicateAtom::Projection(data) = predicate.skip_binders() {
|
||||
let data = ty::Binder::bind(data);
|
||||
let data = bound_predicate.map_bound_ref(|_| data);
|
||||
let same_def_id = data.projection_def_id() == obligation.predicate.item_def_id;
|
||||
|
||||
let is_match = same_def_id
|
||||
|
|
|
@ -449,16 +449,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
let result = ensure_sufficient_stack(|| {
|
||||
match obligation.predicate.skip_binders() {
|
||||
let bound_predicate = obligation.predicate.bound_atom(self.infcx().tcx);
|
||||
match bound_predicate.skip_binder() {
|
||||
ty::PredicateAtom::Trait(t, _) => {
|
||||
let t = ty::Binder::bind(t);
|
||||
let t = bound_predicate.map_bound_ref(|_| t);
|
||||
debug_assert!(!t.has_escaping_bound_vars());
|
||||
let obligation = obligation.with(t);
|
||||
self.evaluate_trait_predicate_recursively(previous_stack, obligation)
|
||||
}
|
||||
|
||||
ty::PredicateAtom::Subtype(p) => {
|
||||
let p = ty::Binder::bind(p);
|
||||
let p = bound_predicate.map_bound_ref(|_| p);
|
||||
// Does this code ever run?
|
||||
match self.infcx.subtype_predicate(&obligation.cause, obligation.param_env, p) {
|
||||
Some(Ok(InferOk { mut obligations, .. })) => {
|
||||
|
@ -502,7 +503,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
ty::PredicateAtom::Projection(data) => {
|
||||
let data = ty::Binder::bind(data);
|
||||
let data = bound_predicate.map_bound_ref(|_| data);
|
||||
let project_obligation = obligation.with(data);
|
||||
match project::poly_project_and_unify_type(self, &project_obligation) {
|
||||
Ok(Ok(Some(mut subobligations))) => {
|
||||
|
@ -1174,8 +1175,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(idx, bound)| {
|
||||
if let ty::PredicateAtom::Trait(pred, _) = bound.skip_binders() {
|
||||
let bound = ty::Binder::bind(pred.trait_ref);
|
||||
let bound_predicate = bound.bound_atom(self.infcx.tcx);
|
||||
if let ty::PredicateAtom::Trait(pred, _) = bound_predicate.skip_binder() {
|
||||
let bound = bound_predicate.map_bound_ref(|_| pred.trait_ref);
|
||||
if self.infcx.probe(|_| {
|
||||
match self.match_projection(
|
||||
obligation,
|
||||
|
@ -1529,16 +1531,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None,
|
||||
|
||||
ty::Tuple(tys) => {
|
||||
Where(ty::Binder::bind(tys.last().into_iter().map(|k| k.expect_ty()).collect()))
|
||||
}
|
||||
ty::Tuple(tys) => Where(
|
||||
obligation
|
||||
.predicate
|
||||
.map_bound_ref(|_| tys.last().into_iter().map(|k| k.expect_ty()).collect()),
|
||||
),
|
||||
|
||||
ty::Adt(def, substs) => {
|
||||
let sized_crit = def.sized_constraint(self.tcx());
|
||||
// (*) binder moved here
|
||||
Where(ty::Binder::bind(
|
||||
sized_crit.iter().map(|ty| ty.subst(self.tcx(), substs)).collect(),
|
||||
))
|
||||
Where(obligation.predicate.map_bound_ref(|_| {
|
||||
sized_crit.iter().map(|ty| ty.subst(self.tcx(), substs)).collect()
|
||||
}))
|
||||
}
|
||||
|
||||
ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => None,
|
||||
|
@ -1590,12 +1594,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
ty::Array(element_ty, _) => {
|
||||
// (*) binder moved here
|
||||
Where(ty::Binder::bind(vec![element_ty]))
|
||||
Where(obligation.predicate.map_bound_ref(|_| vec![*element_ty]))
|
||||
}
|
||||
|
||||
ty::Tuple(tys) => {
|
||||
// (*) binder moved here
|
||||
Where(ty::Binder::bind(tys.iter().map(|k| k.expect_ty()).collect()))
|
||||
Where(
|
||||
obligation
|
||||
.predicate
|
||||
.map_bound_ref(|_| tys.iter().map(|k| k.expect_ty()).collect()),
|
||||
)
|
||||
}
|
||||
|
||||
ty::Closure(_, substs) => {
|
||||
|
@ -1605,7 +1613,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// Not yet resolved.
|
||||
Ambiguous
|
||||
} else {
|
||||
Where(ty::Binder::bind(substs.as_closure().upvar_tys().collect()))
|
||||
Where(
|
||||
obligation
|
||||
.predicate
|
||||
.map_bound_ref(|_| substs.as_closure().upvar_tys().collect()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue