Use map_bound(_ref) instead of Binder::bind when possible

This commit is contained in:
Jack Huey 2020-10-07 20:02:06 -04:00
parent a78a62fc99
commit dd5c9bf139
24 changed files with 173 additions and 143 deletions

View file

@ -673,17 +673,9 @@ fn codegen_emcc_try(
fn gen_fn<'ll, 'tcx>( fn gen_fn<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
name: &str, name: &str,
inputs: Vec<Ty<'tcx>>, rust_fn_sig: ty::PolyFnSig<'tcx>,
output: Ty<'tcx>,
codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>), codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>),
) -> &'ll Value { ) -> &'ll Value {
let rust_fn_sig = ty::Binder::bind(cx.tcx.mk_fn_sig(
inputs.into_iter(),
output,
false,
hir::Unsafety::Unsafe,
Abi::Rust,
));
let fn_abi = FnAbi::of_fn_ptr(cx, rust_fn_sig, &[]); let fn_abi = FnAbi::of_fn_ptr(cx, rust_fn_sig, &[]);
let llfn = cx.declare_fn(name, &fn_abi); let llfn = cx.declare_fn(name, &fn_abi);
cx.set_frame_pointer_elimination(llfn); cx.set_frame_pointer_elimination(llfn);
@ -710,14 +702,16 @@ fn get_rust_try_fn<'ll, 'tcx>(
// Define the type up front for the signature of the rust_try function. // Define the type up front for the signature of the rust_try function.
let tcx = cx.tcx; let tcx = cx.tcx;
let i8p = tcx.mk_mut_ptr(tcx.types.i8); let i8p = tcx.mk_mut_ptr(tcx.types.i8);
let try_fn_ty = tcx.mk_fn_ptr(ty::Binder::bind(tcx.mk_fn_sig( // `unsafe fn(*mut i8) -> ()`
let try_fn_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig(
iter::once(i8p), iter::once(i8p),
tcx.mk_unit(), tcx.mk_unit(),
false, false,
hir::Unsafety::Unsafe, hir::Unsafety::Unsafe,
Abi::Rust, Abi::Rust,
))); )));
let catch_fn_ty = tcx.mk_fn_ptr(ty::Binder::bind(tcx.mk_fn_sig( // `unsafe fn(*mut i8, *mut i8) -> ()`
let catch_fn_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig(
[i8p, i8p].iter().cloned(), [i8p, i8p].iter().cloned(),
tcx.mk_unit(), tcx.mk_unit(),
false, false,
@ -725,7 +719,15 @@ fn get_rust_try_fn<'ll, 'tcx>(
Abi::Rust, Abi::Rust,
))); )));
let output = tcx.types.i32; let output = tcx.types.i32;
let rust_try = gen_fn(cx, "__rust_try", vec![try_fn_ty, i8p, catch_fn_ty], output, codegen); // `unsafe fn(unsafe fn(*mut i8) -> (), unsafe fn(*mut i8, *mut i8) -> ()) -> i32`
let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig(
vec![try_fn_ty, i8p, catch_fn_ty].into_iter(),
output,
false,
hir::Unsafety::Unsafe,
Abi::Rust,
));
let rust_try = gen_fn(cx, "__rust_try", rust_fn_sig, codegen);
cx.rust_try_fn.set(Some(rust_try)); cx.rust_try_fn.set(Some(rust_try));
rust_try rust_try
} }

View file

@ -551,7 +551,8 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
where where
T: Relate<'tcx>, T: Relate<'tcx>,
{ {
Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?)) let result = self.relate(a.skip_binder(), b.skip_binder())?;
Ok(a.map_bound(|_| result))
} }
fn relate_item_substs( fn relate_item_substs(
@ -833,7 +834,8 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
where where
T: Relate<'tcx>, T: Relate<'tcx>,
{ {
Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?)) let result = self.relate(a.skip_binder(), b.skip_binder())?;
Ok(a.map_bound(|_| result))
} }
fn tys(&mut self, t: Ty<'tcx>, _t: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { fn tys(&mut self, t: Ty<'tcx>, _t: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {

View file

@ -636,7 +636,7 @@ where
if let (Some(a), Some(b)) = (a.no_bound_vars(), b.no_bound_vars()) { if let (Some(a), Some(b)) = (a.no_bound_vars(), b.no_bound_vars()) {
// Fast path for the common case. // Fast path for the common case.
self.relate(a, b)?; self.relate(a, b)?;
return Ok(ty::Binder::bind(a)); return Ok(ty::Binder::dummy(a));
} }
if self.ambient_covariance() { if self.ambient_covariance() {
@ -1004,6 +1004,6 @@ where
self.first_free_index.shift_in(1); self.first_free_index.shift_in(1);
let result = self.relate(a.skip_binder(), a.skip_binder())?; let result = self.relate(a.skip_binder(), a.skip_binder())?;
self.first_free_index.shift_out(1); self.first_free_index.shift_out(1);
Ok(ty::Binder::bind(result)) Ok(a.map_bound(|_| result))
} }
} }

View file

@ -126,14 +126,15 @@ impl Elaborator<'tcx> {
fn elaborate(&mut self, obligation: &PredicateObligation<'tcx>) { fn elaborate(&mut self, obligation: &PredicateObligation<'tcx>) {
let tcx = self.visited.tcx; let tcx = self.visited.tcx;
match obligation.predicate.skip_binders() { let bound_predicate = obligation.predicate.bound_atom(tcx);
match bound_predicate.skip_binder() {
ty::PredicateAtom::Trait(data, _) => { ty::PredicateAtom::Trait(data, _) => {
// Get predicates declared on the trait. // Get predicates declared on the trait.
let predicates = tcx.super_predicates_of(data.def_id()); let predicates = tcx.super_predicates_of(data.def_id());
let obligations = predicates.predicates.iter().map(|&(pred, _)| { let obligations = predicates.predicates.iter().map(|&(pred, _)| {
predicate_obligation( predicate_obligation(
pred.subst_supertrait(tcx, &ty::Binder::bind(data.trait_ref)), pred.subst_supertrait(tcx, &bound_predicate.map_bound(|_| data.trait_ref)),
obligation.param_env, obligation.param_env,
obligation.cause.clone(), obligation.cause.clone(),
) )

View file

@ -118,6 +118,7 @@ impl TypeRelation<'tcx> for Match<'tcx> {
where where
T: Relate<'tcx>, T: Relate<'tcx>,
{ {
Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?)) let result = self.relate(a.skip_binder(), b.skip_binder())?;
Ok(a.map_bound(|_| result))
} }
} }

View file

@ -618,10 +618,9 @@ pub trait PrettyPrinter<'tcx>:
// may contain unbound variables. We therefore do this manually. // may contain unbound variables. We therefore do this manually.
// //
// FIXME(lcnr): Find out why exactly this is the case :) // FIXME(lcnr): Find out why exactly this is the case :)
if let ty::PredicateAtom::Trait(pred, _) = let bound_predicate = predicate.bound_atom(self.tcx());
predicate.bound_atom(self.tcx()).skip_binder() if let ty::PredicateAtom::Trait(pred, _) = bound_predicate.skip_binder() {
{ let trait_ref = bound_predicate.map_bound(|_| pred.trait_ref);
let trait_ref = ty::Binder::bind(pred.trait_ref);
// Don't print +Sized, but rather +?Sized if absent. // Don't print +Sized, but rather +?Sized if absent.
if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() { if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() {
is_sized = true; is_sized = true;

View file

@ -549,7 +549,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateAtom<'a> {
impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<T> { impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<T> {
type Lifted = ty::Binder<T::Lifted>; type Lifted = ty::Binder<T::Lifted>;
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
tcx.lift(self.as_ref().skip_binder()).map(ty::Binder::bind) tcx.lift(self.as_ref().skip_binder()).map(|v| self.map_bound_ref(|_| v))
} }
} }

View file

@ -702,15 +702,19 @@ impl<'tcx> Binder<ExistentialPredicate<'tcx>> {
pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> { pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> {
use crate::ty::ToPredicate; use crate::ty::ToPredicate;
match self.skip_binder() { match self.skip_binder() {
ExistentialPredicate::Trait(tr) => { ExistentialPredicate::Trait(tr) => self
Binder(tr).with_self_ty(tcx, self_ty).without_const().to_predicate(tcx) .map_bound_ref(|_| tr)
} .with_self_ty(tcx, self_ty)
.without_const()
.to_predicate(tcx),
ExistentialPredicate::Projection(p) => { ExistentialPredicate::Projection(p) => {
Binder(p.with_self_ty(tcx, self_ty)).to_predicate(tcx) self.map_bound_ref(|_| p.with_self_ty(tcx, self_ty)).to_predicate(tcx)
} }
ExistentialPredicate::AutoTrait(did) => { ExistentialPredicate::AutoTrait(did) => {
let trait_ref = let trait_ref = self.map_bound_ref(|_| ty::TraitRef {
Binder(ty::TraitRef { def_id: did, substs: tcx.mk_substs_trait(self_ty, &[]) }); def_id: did,
substs: tcx.mk_substs_trait(self_ty, &[]),
});
trait_ref.without_const().to_predicate(tcx) trait_ref.without_const().to_predicate(tcx)
} }
} }
@ -775,7 +779,7 @@ impl<'tcx> List<ExistentialPredicate<'tcx>> {
impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> { impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> {
pub fn principal(&self) -> Option<ty::Binder<ExistentialTraitRef<'tcx>>> { pub fn principal(&self) -> Option<ty::Binder<ExistentialTraitRef<'tcx>>> {
self.skip_binder().principal().map(Binder::bind) self.map_bound_ref(|b| b.principal()).transpose()
} }
pub fn principal_def_id(&self) -> Option<DefId> { pub fn principal_def_id(&self) -> Option<DefId> {
@ -858,8 +862,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
} }
pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> { pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> {
// Note that we preserve binding levels self.map_bound(|trait_ref| ty::TraitPredicate { trait_ref })
Binder(ty::TraitPredicate { trait_ref: self.skip_binder() })
} }
} }

View file

@ -642,7 +642,8 @@ impl AutoTraitFinder<'tcx> {
// We check this by calling is_of_param on the relevant types // We check this by calling is_of_param on the relevant types
// from the various possible predicates // 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, _) => { ty::PredicateAtom::Trait(p, _) => {
if self.is_param_no_infer(p.trait_ref.substs) if self.is_param_no_infer(p.trait_ref.substs)
&& !only_projections && !only_projections
@ -650,10 +651,10 @@ impl AutoTraitFinder<'tcx> {
{ {
self.add_user_pred(computed_preds, predicate); 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) => { ty::PredicateAtom::Projection(p) => {
let p = ty::Binder::bind(p); let p = bound_predicate.map_bound_ref(|_| p);
debug!( debug!(
"evaluate_nested_obligations: examining projection predicate {:?}", "evaluate_nested_obligations: examining projection predicate {:?}",
predicate predicate
@ -783,13 +784,13 @@ impl AutoTraitFinder<'tcx> {
} }
} }
ty::PredicateAtom::RegionOutlives(binder) => { 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() { if select.infcx().region_outlives_predicate(&dummy_cause, binder).is_err() {
return false; return false;
} }
} }
ty::PredicateAtom::TypeOutlives(binder) => { ty::PredicateAtom::TypeOutlives(binder) => {
let binder = ty::Binder::bind(binder); let binder = bound_predicate.map_bound_ref(|_| binder);
match ( match (
binder.no_bound_vars(), binder.no_bound_vars(),
binder.map_bound_ref(|pred| pred.0).no_bound_vars(), binder.map_bound_ref(|pred| pred.0).no_bound_vars(),

View file

@ -255,9 +255,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
return; 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, _) => { 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); let trait_predicate = self.resolve_vars_if_possible(&trait_predicate);
if self.tcx.sess.has_errors() && trait_predicate.references_error() { 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) => { 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 predicate = self.resolve_vars_if_possible(&predicate);
let err = self let err = self
.region_outlives_predicate(&obligation.cause, predicate) .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. // 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, _)) => { (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. // 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)) { 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 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. // FIXME: I'm just not taking associated types at all here.
// Eventually I'll need to implement param-env-aware // Eventually I'll need to implement param-env-aware
// `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic. // `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` 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 // this can fail if the problem was higher-ranked, in which
// cause I have no idea for a good error message. // 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 mut selcx = SelectionContext::new(self);
let (data, _) = self.replace_bound_vars_with_fresh_vars( let (data, _) = self.replace_bound_vars_with_fresh_vars(
obligation.cause.span, obligation.cause.span,
infer::LateBoundRegionConversionTime::HigherRankedType, infer::LateBoundRegionConversionTime::HigherRankedType,
&ty::Binder::bind(data), &bound_predicate.map_bound_ref(|_| data),
); );
let mut obligations = vec![]; let mut obligations = vec![];
let normalized_ty = super::normalize_projection_type( let normalized_ty = super::normalize_projection_type(
@ -1455,10 +1459,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
return; 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, _) => { ty::PredicateAtom::Trait(data, _) => {
let trait_ref = ty::Binder::bind(data.trait_ref); let self_ty = data.trait_ref.self_ty();
let self_ty = trait_ref.skip_binder().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); debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind(), trait_ref);
if predicate.references_error() { 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) self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282)
} }
ty::PredicateAtom::Projection(data) => { 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 self_ty = trait_ref.skip_binder().self_ty();
let ty = data.ty; let ty = data.ty;
if predicate.references_error() { if predicate.references_error() {

View file

@ -353,7 +353,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
// This means we need to pass it the bound version of our // This means we need to pass it the bound version of our
// predicate. // predicate.
ty::PredicateAtom::Trait(trait_ref, _constness) => { 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( self.process_trait_obligation(
obligation, obligation,
@ -362,7 +362,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
) )
} }
ty::PredicateAtom::Projection(data) => { 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( self.process_projection_obligation(
project_obligation, project_obligation,

View file

@ -623,7 +623,8 @@ fn prune_cache_value_obligations<'a, 'tcx>(
.obligations .obligations
.iter() .iter()
.filter(|obligation| { .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 // We found a `T: Foo<X = U>` predicate, let's check
// if `U` references any unresolved type // if `U` references any unresolved type
// variables. In principle, we only care if this // 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`, // indirect obligations (e.g., we project to `?0`,
// but we have `T: Foo<X = ?1>` and `?1: Bar<X = // but we have `T: Foo<X = ?1>` and `?1: Bar<X =
// ?0>`). // ?0>`).
ty::PredicateAtom::Projection(data) => { ty::PredicateAtom::Projection(data) => infcx
infcx.unresolved_type_vars(&ty::Binder::bind(data.ty)).is_some() .unresolved_type_vars(&bound_predicate.map_bound_ref(|_| data.ty))
} .is_some(),
// We are only interested in `T: Foo<X = U>` predicates, whre // We are only interested in `T: Foo<X = U>` predicates, whre
// `U` references one of `unresolved_type_vars`. =) // `U` references one of `unresolved_type_vars`. =)
@ -907,8 +908,9 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
let infcx = selcx.infcx(); let infcx = selcx.infcx();
for predicate in env_predicates { for predicate in env_predicates {
debug!(?predicate); debug!(?predicate);
let bound_predicate = predicate.bound_atom(infcx.tcx);
if let ty::PredicateAtom::Projection(data) = predicate.skip_binders() { 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 same_def_id = data.projection_def_id() == obligation.predicate.item_def_id;
let is_match = same_def_id let is_match = same_def_id

View file

@ -449,16 +449,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
} }
let result = ensure_sufficient_stack(|| { 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, _) => { 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()); debug_assert!(!t.has_escaping_bound_vars());
let obligation = obligation.with(t); let obligation = obligation.with(t);
self.evaluate_trait_predicate_recursively(previous_stack, obligation) self.evaluate_trait_predicate_recursively(previous_stack, obligation)
} }
ty::PredicateAtom::Subtype(p) => { ty::PredicateAtom::Subtype(p) => {
let p = ty::Binder::bind(p); let p = bound_predicate.map_bound_ref(|_| p);
// Does this code ever run? // Does this code ever run?
match self.infcx.subtype_predicate(&obligation.cause, obligation.param_env, p) { match self.infcx.subtype_predicate(&obligation.cause, obligation.param_env, p) {
Some(Ok(InferOk { mut obligations, .. })) => { Some(Ok(InferOk { mut obligations, .. })) => {
@ -502,7 +503,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
} }
ty::PredicateAtom::Projection(data) => { ty::PredicateAtom::Projection(data) => {
let data = ty::Binder::bind(data); let data = bound_predicate.map_bound_ref(|_| data);
let project_obligation = obligation.with(data); let project_obligation = obligation.with(data);
match project::poly_project_and_unify_type(self, &project_obligation) { match project::poly_project_and_unify_type(self, &project_obligation) {
Ok(Ok(Some(mut subobligations))) => { Ok(Ok(Some(mut subobligations))) => {
@ -1174,8 +1175,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.iter() .iter()
.enumerate() .enumerate()
.filter_map(|(idx, bound)| { .filter_map(|(idx, bound)| {
if let ty::PredicateAtom::Trait(pred, _) = bound.skip_binders() { let bound_predicate = bound.bound_atom(self.infcx.tcx);
let bound = ty::Binder::bind(pred.trait_ref); if let ty::PredicateAtom::Trait(pred, _) = bound_predicate.skip_binder() {
let bound = bound_predicate.map_bound_ref(|_| pred.trait_ref);
if self.infcx.probe(|_| { if self.infcx.probe(|_| {
match self.match_projection( match self.match_projection(
obligation, obligation,
@ -1529,16 +1531,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None, ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None,
ty::Tuple(tys) => { ty::Tuple(tys) => Where(
Where(ty::Binder::bind(tys.last().into_iter().map(|k| k.expect_ty()).collect())) obligation
} .predicate
.map_bound_ref(|_| tys.last().into_iter().map(|k| k.expect_ty()).collect()),
),
ty::Adt(def, substs) => { ty::Adt(def, substs) => {
let sized_crit = def.sized_constraint(self.tcx()); let sized_crit = def.sized_constraint(self.tcx());
// (*) binder moved here // (*) binder moved here
Where(ty::Binder::bind( Where(obligation.predicate.map_bound_ref(|_| {
sized_crit.iter().map(|ty| ty.subst(self.tcx(), substs)).collect(), sized_crit.iter().map(|ty| ty.subst(self.tcx(), substs)).collect()
)) }))
} }
ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => None, ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => None,
@ -1590,12 +1594,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::Array(element_ty, _) => { ty::Array(element_ty, _) => {
// (*) binder moved here // (*) binder moved here
Where(ty::Binder::bind(vec![element_ty])) Where(obligation.predicate.map_bound_ref(|_| vec![*element_ty]))
} }
ty::Tuple(tys) => { ty::Tuple(tys) => {
// (*) binder moved here // (*) 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) => { ty::Closure(_, substs) => {
@ -1605,7 +1613,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// Not yet resolved. // Not yet resolved.
Ambiguous Ambiguous
} else { } else {
Where(ty::Binder::bind(substs.as_closure().upvar_tys().collect())) Where(
obligation
.predicate
.map_bound_ref(|_| substs.as_closure().upvar_tys().collect()),
)
} }
} }

View file

@ -762,27 +762,19 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_solve::rust_ir::QuantifiedInlineBound<Ru
self, self,
interner: &RustInterner<'tcx>, interner: &RustInterner<'tcx>,
) -> Option<chalk_solve::rust_ir::QuantifiedInlineBound<RustInterner<'tcx>>> { ) -> Option<chalk_solve::rust_ir::QuantifiedInlineBound<RustInterner<'tcx>>> {
match self.bound_atom(interner.tcx).skip_binder() { let (predicate, binders, _named_regions) =
ty::PredicateAtom::Trait(predicate, _) => { collect_bound_vars(interner, interner.tcx, &self.bound_atom(interner.tcx));
let (predicate, binders, _named_regions) = match predicate {
collect_bound_vars(interner, interner.tcx, &ty::Binder::bind(predicate)); ty::PredicateAtom::Trait(predicate, _) => Some(chalk_ir::Binders::new(
binders,
Some(chalk_ir::Binders::new( chalk_solve::rust_ir::InlineBound::TraitBound(
binders, predicate.trait_ref.lower_into(interner),
chalk_solve::rust_ir::InlineBound::TraitBound( ),
predicate.trait_ref.lower_into(interner), )),
), ty::PredicateAtom::Projection(predicate) => Some(chalk_ir::Binders::new(
)) binders,
} chalk_solve::rust_ir::InlineBound::AliasEqBound(predicate.lower_into(interner)),
ty::PredicateAtom::Projection(predicate) => { )),
let (predicate, binders, _named_regions) =
collect_bound_vars(interner, interner.tcx, &ty::Binder::bind(predicate));
Some(chalk_ir::Binders::new(
binders,
chalk_solve::rust_ir::InlineBound::AliasEqBound(predicate.lower_into(interner)),
))
}
ty::PredicateAtom::TypeOutlives(_predicate) => None, ty::PredicateAtom::TypeOutlives(_predicate) => None,
ty::PredicateAtom::WellFormed(_ty) => None, ty::PredicateAtom::WellFormed(_ty) => None,

View file

@ -1095,9 +1095,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
obligation.predicate obligation.predicate
); );
match obligation.predicate.skip_binders() { let bound_predicate = obligation.predicate.bound_atom(tcx);
match bound_predicate.skip_binder() {
ty::PredicateAtom::Trait(pred, _) => { ty::PredicateAtom::Trait(pred, _) => {
let pred = ty::Binder::bind(pred); let pred = bound_predicate.map_bound_ref(|_| pred);
associated_types.entry(span).or_default().extend( associated_types.entry(span).or_default().extend(
tcx.associated_items(pred.def_id()) tcx.associated_items(pred.def_id())
.in_definition_order() .in_definition_order()
@ -1106,7 +1107,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
); );
} }
ty::PredicateAtom::Projection(pred) => { ty::PredicateAtom::Projection(pred) => {
let pred = ty::Binder::bind(pred); let pred = bound_predicate.map_bound_ref(|_| pred);
// A `Self` within the original bound will be substituted with a // A `Self` within the original bound will be substituted with a
// `trait_object_dummy_self`, so check for that. // `trait_object_dummy_self`, so check for that.
let references_self = let references_self =

View file

@ -192,6 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
obligation.predicate obligation.predicate
); );
let bound_predicate = obligation.predicate.bound_atom(self.tcx);
if let ty::PredicateAtom::Projection(proj_predicate) = if let ty::PredicateAtom::Projection(proj_predicate) =
obligation.predicate.skip_binders() obligation.predicate.skip_binders()
{ {
@ -199,7 +200,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// the complete signature. // the complete signature.
self.deduce_sig_from_projection( self.deduce_sig_from_projection(
Some(obligation.cause.span), Some(obligation.cause.span),
ty::Binder::bind(proj_predicate), bound_predicate.map_bound_ref(|_| proj_predicate),
) )
} else { } else {
None None

View file

@ -583,7 +583,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
while !queue.is_empty() { while !queue.is_empty() {
let obligation = queue.remove(0); let obligation = queue.remove(0);
debug!("coerce_unsized resolve step: {:?}", obligation); debug!("coerce_unsized resolve step: {:?}", obligation);
let trait_pred = match obligation.predicate.skip_binders() { let bound_predicate = obligation.predicate.bound_atom(self.tcx);
let trait_pred = match bound_predicate.skip_binder() {
ty::PredicateAtom::Trait(trait_pred, _) ty::PredicateAtom::Trait(trait_pred, _)
if traits.contains(&trait_pred.def_id()) => if traits.contains(&trait_pred.def_id()) =>
{ {
@ -594,7 +595,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
has_unsized_tuple_coercion = true; has_unsized_tuple_coercion = true;
} }
} }
ty::Binder::bind(trait_pred) bound_predicate.map_bound_ref(|_| trait_pred)
} }
_ => { _ => {
coercion.obligations.push(obligation); coercion.obligations.push(obligation);

View file

@ -226,13 +226,15 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
// could be extended easily also to the other `Predicate`. // could be extended easily also to the other `Predicate`.
let predicate_matches_closure = |p: Predicate<'tcx>| { let predicate_matches_closure = |p: Predicate<'tcx>| {
let mut relator: SimpleEqRelation<'tcx> = SimpleEqRelation::new(tcx, self_param_env); let mut relator: SimpleEqRelation<'tcx> = SimpleEqRelation::new(tcx, self_param_env);
let bound_predicate = predicate.bound_atom(tcx);
let bound_p = p.bound_atom(tcx);
match (predicate.skip_binders(), p.skip_binders()) { match (predicate.skip_binders(), p.skip_binders()) {
(ty::PredicateAtom::Trait(a, _), ty::PredicateAtom::Trait(b, _)) => { (ty::PredicateAtom::Trait(a, _), ty::PredicateAtom::Trait(b, _)) => relator
relator.relate(ty::Binder::bind(a), ty::Binder::bind(b)).is_ok() .relate(bound_predicate.map_bound_ref(|_| a), bound_p.map_bound_ref(|_| b))
} .is_ok(),
(ty::PredicateAtom::Projection(a), ty::PredicateAtom::Projection(b)) => { (ty::PredicateAtom::Projection(a), ty::PredicateAtom::Projection(b)) => relator
relator.relate(ty::Binder::bind(a), ty::Binder::bind(b)).is_ok() .relate(bound_predicate.map_bound_ref(|_| a), bound_p.map_bound_ref(|_| b))
} .is_ok(),
_ => predicate == p, _ => predicate == p,
} }
}; };

View file

@ -328,14 +328,14 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
kw::Try => { kw::Try => {
let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8); let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8);
let try_fn_ty = ty::Binder::bind(tcx.mk_fn_sig( let try_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig(
iter::once(mut_u8), iter::once(mut_u8),
tcx.mk_unit(), tcx.mk_unit(),
false, false,
hir::Unsafety::Normal, hir::Unsafety::Normal,
Abi::Rust, Abi::Rust,
)); ));
let catch_fn_ty = ty::Binder::bind(tcx.mk_fn_sig( let catch_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig(
[mut_u8, mut_u8].iter().cloned(), [mut_u8, mut_u8].iter().cloned(),
tcx.mk_unit(), tcx.mk_unit(),
false, false,

View file

@ -796,29 +796,30 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
// FIXME: do we want to commit to this behavior for param bounds? // FIXME: do we want to commit to this behavior for param bounds?
debug!("assemble_inherent_candidates_from_param(param_ty={:?})", param_ty); debug!("assemble_inherent_candidates_from_param(param_ty={:?})", param_ty);
let bounds = let tcx = self.tcx;
self.param_env.caller_bounds().iter().map(ty::Predicate::skip_binders).filter_map( let bounds = self.param_env.caller_bounds().iter().filter_map(|predicate| {
|predicate| match predicate { let bound_predicate = predicate.bound_atom(tcx);
ty::PredicateAtom::Trait(trait_predicate, _) => { match bound_predicate.skip_binder() {
match trait_predicate.trait_ref.self_ty().kind() { ty::PredicateAtom::Trait(trait_predicate, _) => {
ty::Param(ref p) if *p == param_ty => { match trait_predicate.trait_ref.self_ty().kind() {
Some(ty::Binder::bind(trait_predicate.trait_ref)) ty::Param(ref p) if *p == param_ty => {
} Some(bound_predicate.map_bound_ref(|_| trait_predicate.trait_ref))
_ => None,
} }
_ => None,
} }
ty::PredicateAtom::Subtype(..) }
| ty::PredicateAtom::Projection(..) ty::PredicateAtom::Subtype(..)
| ty::PredicateAtom::RegionOutlives(..) | ty::PredicateAtom::Projection(..)
| ty::PredicateAtom::WellFormed(..) | ty::PredicateAtom::RegionOutlives(..)
| ty::PredicateAtom::ObjectSafe(..) | ty::PredicateAtom::WellFormed(..)
| ty::PredicateAtom::ClosureKind(..) | ty::PredicateAtom::ObjectSafe(..)
| ty::PredicateAtom::TypeOutlives(..) | ty::PredicateAtom::ClosureKind(..)
| ty::PredicateAtom::ConstEvaluatable(..) | ty::PredicateAtom::TypeOutlives(..)
| ty::PredicateAtom::ConstEquate(..) | ty::PredicateAtom::ConstEvaluatable(..)
| ty::PredicateAtom::TypeWellFormedFromEnv(..) => None, | ty::PredicateAtom::ConstEquate(..)
}, | ty::PredicateAtom::TypeWellFormedFromEnv(..) => None,
); }
});
self.elaborate_bounds(bounds, |this, poly_trait_ref, item| { self.elaborate_bounds(bounds, |this, poly_trait_ref, item| {
let trait_ref = this.erase_late_bound_regions(&poly_trait_ref); let trait_ref = this.erase_late_bound_regions(&poly_trait_ref);

View file

@ -637,9 +637,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
}; };
let mut format_pred = |pred: ty::Predicate<'tcx>| { let mut format_pred = |pred: ty::Predicate<'tcx>| {
match pred.skip_binders() { let bound_predicate = pred.bound_atom(tcx);
match bound_predicate.skip_binder() {
ty::PredicateAtom::Projection(pred) => { ty::PredicateAtom::Projection(pred) => {
let pred = ty::Binder::bind(pred); let pred = bound_predicate.map_bound_ref(|_| pred);
// `<Foo as Iterator>::Item = String`. // `<Foo as Iterator>::Item = String`.
let trait_ref = let trait_ref =
pred.skip_binder().projection_ty.trait_ref(self.tcx); pred.skip_binder().projection_ty.trait_ref(self.tcx);
@ -658,8 +659,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Some((obligation, trait_ref.self_ty())) Some((obligation, trait_ref.self_ty()))
} }
ty::PredicateAtom::Trait(poly_trait_ref, _) => { ty::PredicateAtom::Trait(poly_trait_ref, _) => {
let poly_trait_ref = ty::Binder::bind(poly_trait_ref); let p = poly_trait_ref.trait_ref;
let p = poly_trait_ref.skip_binder().trait_ref;
let self_ty = p.self_ty(); let self_ty = p.self_ty();
let path = p.print_only_trait_path(); let path = p.print_only_trait_path();
let obligation = format!("{}: {}", self_ty, path); let obligation = format!("{}: {}", self_ty, path);

View file

@ -850,7 +850,8 @@ fn bounds_from_generic_predicates<'tcx>(
let mut projections = vec![]; let mut projections = vec![];
for (predicate, _) in predicates.predicates { for (predicate, _) in predicates.predicates {
debug!("predicate {:?}", predicate); debug!("predicate {:?}", predicate);
match predicate.skip_binders() { let bound_predicate = predicate.bound_atom(tcx);
match bound_predicate.skip_binder() {
ty::PredicateAtom::Trait(trait_predicate, _) => { ty::PredicateAtom::Trait(trait_predicate, _) => {
let entry = types.entry(trait_predicate.self_ty()).or_default(); let entry = types.entry(trait_predicate.self_ty()).or_default();
let def_id = trait_predicate.def_id(); let def_id = trait_predicate.def_id();
@ -861,7 +862,7 @@ fn bounds_from_generic_predicates<'tcx>(
} }
} }
ty::PredicateAtom::Projection(projection_pred) => { ty::PredicateAtom::Projection(projection_pred) => {
projections.push(ty::Binder::bind(projection_pred)); projections.push(bound_predicate.map_bound_ref(|_| projection_pred));
} }
_ => {} _ => {}
} }

View file

@ -317,7 +317,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: LocalDefId) {
} }
} }
let se_ty = tcx.mk_fn_ptr(ty::Binder::bind(tcx.mk_fn_sig( let se_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig(
[tcx.types.isize, tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))].iter().cloned(), [tcx.types.isize, tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))].iter().cloned(),
tcx.types.isize, tcx.types.isize,
false, false,

View file

@ -315,13 +315,16 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
pred: ty::Predicate<'tcx>, pred: ty::Predicate<'tcx>,
) -> FxHashSet<GenericParamDef> { ) -> FxHashSet<GenericParamDef> {
let regions = match pred.skip_binders() { let bound_predicate = pred.bound_atom(tcx);
ty::PredicateAtom::Trait(poly_trait_pred, _) => { let regions = match bound_predicate.skip_binder() {
tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(poly_trait_pred)) ty::PredicateAtom::Trait(poly_trait_pred, _) => tcx
} .collect_referenced_late_bound_regions(
ty::PredicateAtom::Projection(poly_proj_pred) => { &bound_predicate.map_bound_ref(|_| poly_trait_pred),
tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(poly_proj_pred)) ),
} ty::PredicateAtom::Projection(poly_proj_pred) => tcx
.collect_referenced_late_bound_regions(
&bound_predicate.map_bound_ref(|_| poly_proj_pred),
),
_ => return FxHashSet::default(), _ => return FxHashSet::default(),
}; };