From dd5c9bf1392bdc697740e62a1924b7942cdfd86a Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Wed, 7 Oct 2020 20:02:06 -0400 Subject: [PATCH] Use map_bound(_ref) instead of Binder::bind when possible --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 26 +++++------ compiler/rustc_infer/src/infer/combine.rs | 6 ++- .../rustc_infer/src/infer/nll_relate/mod.rs | 4 +- compiler/rustc_infer/src/traits/util.rs | 5 ++- compiler/rustc_middle/src/ty/_match.rs | 3 +- compiler/rustc_middle/src/ty/print/pretty.rs | 7 ++- .../rustc_middle/src/ty/structural_impls.rs | 2 +- compiler/rustc_middle/src/ty/sty.rs | 21 +++++---- .../src/traits/auto_trait.rs | 11 ++--- .../src/traits/error_reporting/mod.rs | 31 +++++++------ .../src/traits/fulfill.rs | 4 +- .../src/traits/project.rs | 12 +++--- .../src/traits/select/mod.rs | 42 +++++++++++------- compiler/rustc_traits/src/chalk/lowering.rs | 34 ++++++--------- compiler/rustc_typeck/src/astconv/mod.rs | 7 +-- compiler/rustc_typeck/src/check/closure.rs | 3 +- compiler/rustc_typeck/src/check/coercion.rs | 5 ++- compiler/rustc_typeck/src/check/dropck.rs | 14 +++--- compiler/rustc_typeck/src/check/intrinsic.rs | 4 +- .../rustc_typeck/src/check/method/probe.rs | 43 ++++++++++--------- .../rustc_typeck/src/check/method/suggest.rs | 8 ++-- compiler/rustc_typeck/src/check/mod.rs | 5 ++- compiler/rustc_typeck/src/lib.rs | 2 +- src/librustdoc/clean/auto_trait.rs | 17 +++++--- 24 files changed, 173 insertions(+), 143 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index e78a4ea2e3c..e1f675e3ae9 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -673,17 +673,9 @@ fn codegen_emcc_try( fn gen_fn<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, name: &str, - inputs: Vec>, - output: Ty<'tcx>, + rust_fn_sig: ty::PolyFnSig<'tcx>, codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>), ) -> &'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 llfn = cx.declare_fn(name, &fn_abi); 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. let tcx = cx.tcx; 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), tcx.mk_unit(), false, hir::Unsafety::Unsafe, 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(), tcx.mk_unit(), false, @@ -725,7 +719,15 @@ fn get_rust_try_fn<'ll, 'tcx>( Abi::Rust, ))); 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)); rust_try } diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 6a1715ef818..afa6a2a8166 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -551,7 +551,8 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { where 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( @@ -833,7 +834,8 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { where 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>> { diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 2fb9f638e36..b1ec7a7902d 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -636,7 +636,7 @@ where if let (Some(a), Some(b)) = (a.no_bound_vars(), b.no_bound_vars()) { // Fast path for the common case. self.relate(a, b)?; - return Ok(ty::Binder::bind(a)); + return Ok(ty::Binder::dummy(a)); } if self.ambient_covariance() { @@ -1004,6 +1004,6 @@ where self.first_free_index.shift_in(1); let result = self.relate(a.skip_binder(), a.skip_binder())?; self.first_free_index.shift_out(1); - Ok(ty::Binder::bind(result)) + Ok(a.map_bound(|_| result)) } } diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 1b7269706a7..043d24c9767 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -126,14 +126,15 @@ impl Elaborator<'tcx> { fn elaborate(&mut self, obligation: &PredicateObligation<'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, _) => { // Get predicates declared on the trait. let predicates = tcx.super_predicates_of(data.def_id()); let obligations = predicates.predicates.iter().map(|&(pred, _)| { 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.cause.clone(), ) diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index 27bccc0bcaf..5f5593eb0d8 100644 --- a/compiler/rustc_middle/src/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs @@ -118,6 +118,7 @@ impl TypeRelation<'tcx> for Match<'tcx> { where 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)) } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 08f88eed66f..20dc49991b4 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -618,10 +618,9 @@ pub trait PrettyPrinter<'tcx>: // may contain unbound variables. We therefore do this manually. // // FIXME(lcnr): Find out why exactly this is the case :) - if let ty::PredicateAtom::Trait(pred, _) = - predicate.bound_atom(self.tcx()).skip_binder() - { - let trait_ref = ty::Binder::bind(pred.trait_ref); + let bound_predicate = predicate.bound_atom(self.tcx()); + if let ty::PredicateAtom::Trait(pred, _) = bound_predicate.skip_binder() { + let trait_ref = bound_predicate.map_bound(|_| pred.trait_ref); // Don't print +Sized, but rather +?Sized if absent. if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() { is_sized = true; diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 597ceac9386..5f326d700ee 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -549,7 +549,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateAtom<'a> { impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder { type Lifted = ty::Binder; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - 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)) } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 870cc4eee05..932cadee100 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -702,15 +702,19 @@ impl<'tcx> Binder> { pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> { use crate::ty::ToPredicate; match self.skip_binder() { - ExistentialPredicate::Trait(tr) => { - Binder(tr).with_self_ty(tcx, self_ty).without_const().to_predicate(tcx) - } + ExistentialPredicate::Trait(tr) => self + .map_bound_ref(|_| tr) + .with_self_ty(tcx, self_ty) + .without_const() + .to_predicate(tcx), 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) => { - let trait_ref = - Binder(ty::TraitRef { def_id: did, substs: tcx.mk_substs_trait(self_ty, &[]) }); + let trait_ref = self.map_bound_ref(|_| ty::TraitRef { + def_id: did, + substs: tcx.mk_substs_trait(self_ty, &[]), + }); trait_ref.without_const().to_predicate(tcx) } } @@ -775,7 +779,7 @@ impl<'tcx> List> { impl<'tcx> Binder<&'tcx List>> { pub fn principal(&self) -> Option>> { - self.skip_binder().principal().map(Binder::bind) + self.map_bound_ref(|b| b.principal()).transpose() } pub fn principal_def_id(&self) -> Option { @@ -858,8 +862,7 @@ impl<'tcx> PolyTraitRef<'tcx> { } pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> { - // Note that we preserve binding levels - Binder(ty::TraitPredicate { trait_ref: self.skip_binder() }) + self.map_bound(|trait_ref| ty::TraitPredicate { trait_ref }) } } diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index e40067202e1..96a0c339e18 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -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(), diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 05e3ed34351..3c4394e7d03 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -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() { diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 97dd180b27b..01217457eb4 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -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, diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 8dbf7ec51c6..295ba6041fb 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -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` 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` and `?1: Bar`). - 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` 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 diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 4d347380c6c..29c9c29d208 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -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()), + ) } } diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 391251b6fa5..2ca94c6444a 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -762,27 +762,19 @@ impl<'tcx> LowerInto<'tcx, Option, ) -> Option>> { - match self.bound_atom(interner.tcx).skip_binder() { - ty::PredicateAtom::Trait(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::TraitBound( - predicate.trait_ref.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)), - )) - } + let (predicate, binders, _named_regions) = + collect_bound_vars(interner, interner.tcx, &self.bound_atom(interner.tcx)); + match predicate { + ty::PredicateAtom::Trait(predicate, _) => Some(chalk_ir::Binders::new( + binders, + 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::TypeOutlives(_predicate) => None, ty::PredicateAtom::WellFormed(_ty) => None, diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 170ca2ce744..cea7eaec9a7 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1095,9 +1095,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { obligation.predicate ); - match obligation.predicate.skip_binders() { + let bound_predicate = obligation.predicate.bound_atom(tcx); + match bound_predicate.skip_binder() { 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( tcx.associated_items(pred.def_id()) .in_definition_order() @@ -1106,7 +1107,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ); } 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 // `trait_object_dummy_self`, so check for that. let references_self = diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs index 8bdd933644a..500cc92921b 100644 --- a/compiler/rustc_typeck/src/check/closure.rs +++ b/compiler/rustc_typeck/src/check/closure.rs @@ -192,6 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { obligation.predicate ); + let bound_predicate = obligation.predicate.bound_atom(self.tcx); if let ty::PredicateAtom::Projection(proj_predicate) = obligation.predicate.skip_binders() { @@ -199,7 +200,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // the complete signature. self.deduce_sig_from_projection( Some(obligation.cause.span), - ty::Binder::bind(proj_predicate), + bound_predicate.map_bound_ref(|_| proj_predicate), ) } else { None diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index db32a736181..0eb5593e8bd 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -583,7 +583,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { while !queue.is_empty() { let obligation = queue.remove(0); 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, _) if traits.contains(&trait_pred.def_id()) => { @@ -594,7 +595,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { has_unsized_tuple_coercion = true; } } - ty::Binder::bind(trait_pred) + bound_predicate.map_bound_ref(|_| trait_pred) } _ => { coercion.obligations.push(obligation); diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs index ae94a6df5fd..c777b87d488 100644 --- a/compiler/rustc_typeck/src/check/dropck.rs +++ b/compiler/rustc_typeck/src/check/dropck.rs @@ -226,13 +226,15 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( // could be extended easily also to the other `Predicate`. let predicate_matches_closure = |p: Predicate<'tcx>| { 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()) { - (ty::PredicateAtom::Trait(a, _), ty::PredicateAtom::Trait(b, _)) => { - relator.relate(ty::Binder::bind(a), ty::Binder::bind(b)).is_ok() - } - (ty::PredicateAtom::Projection(a), ty::PredicateAtom::Projection(b)) => { - relator.relate(ty::Binder::bind(a), ty::Binder::bind(b)).is_ok() - } + (ty::PredicateAtom::Trait(a, _), ty::PredicateAtom::Trait(b, _)) => relator + .relate(bound_predicate.map_bound_ref(|_| a), bound_p.map_bound_ref(|_| b)) + .is_ok(), + (ty::PredicateAtom::Projection(a), ty::PredicateAtom::Projection(b)) => relator + .relate(bound_predicate.map_bound_ref(|_| a), bound_p.map_bound_ref(|_| b)) + .is_ok(), _ => predicate == p, } }; diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs index 2ee867c2dd6..f40a250200e 100644 --- a/compiler/rustc_typeck/src/check/intrinsic.rs +++ b/compiler/rustc_typeck/src/check/intrinsic.rs @@ -328,14 +328,14 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { kw::Try => { 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), tcx.mk_unit(), false, hir::Unsafety::Normal, 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(), tcx.mk_unit(), false, diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index c1ba29284da..e6e7e229f88 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -796,29 +796,30 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // FIXME: do we want to commit to this behavior for param bounds? debug!("assemble_inherent_candidates_from_param(param_ty={:?})", param_ty); - let bounds = - self.param_env.caller_bounds().iter().map(ty::Predicate::skip_binders).filter_map( - |predicate| match predicate { - ty::PredicateAtom::Trait(trait_predicate, _) => { - match trait_predicate.trait_ref.self_ty().kind() { - ty::Param(ref p) if *p == param_ty => { - Some(ty::Binder::bind(trait_predicate.trait_ref)) - } - _ => None, + let tcx = self.tcx; + let bounds = self.param_env.caller_bounds().iter().filter_map(|predicate| { + let bound_predicate = predicate.bound_atom(tcx); + match bound_predicate.skip_binder() { + ty::PredicateAtom::Trait(trait_predicate, _) => { + match trait_predicate.trait_ref.self_ty().kind() { + ty::Param(ref p) if *p == param_ty => { + Some(bound_predicate.map_bound_ref(|_| trait_predicate.trait_ref)) } + _ => None, } - ty::PredicateAtom::Subtype(..) - | ty::PredicateAtom::Projection(..) - | ty::PredicateAtom::RegionOutlives(..) - | ty::PredicateAtom::WellFormed(..) - | ty::PredicateAtom::ObjectSafe(..) - | ty::PredicateAtom::ClosureKind(..) - | ty::PredicateAtom::TypeOutlives(..) - | ty::PredicateAtom::ConstEvaluatable(..) - | ty::PredicateAtom::ConstEquate(..) - | ty::PredicateAtom::TypeWellFormedFromEnv(..) => None, - }, - ); + } + ty::PredicateAtom::Subtype(..) + | ty::PredicateAtom::Projection(..) + | ty::PredicateAtom::RegionOutlives(..) + | ty::PredicateAtom::WellFormed(..) + | ty::PredicateAtom::ObjectSafe(..) + | ty::PredicateAtom::ClosureKind(..) + | ty::PredicateAtom::TypeOutlives(..) + | ty::PredicateAtom::ConstEvaluatable(..) + | ty::PredicateAtom::ConstEquate(..) + | ty::PredicateAtom::TypeWellFormedFromEnv(..) => None, + } + }); self.elaborate_bounds(bounds, |this, poly_trait_ref, item| { let trait_ref = this.erase_late_bound_regions(&poly_trait_ref); diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index e33a4e98c59..d1d6d002d4c 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -637,9 +637,10 @@ impl<'a, 'tcx> FnCtxt<'a, '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) => { - let pred = ty::Binder::bind(pred); + let pred = bound_predicate.map_bound_ref(|_| pred); // `::Item = String`. let trait_ref = 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())) } ty::PredicateAtom::Trait(poly_trait_ref, _) => { - let poly_trait_ref = ty::Binder::bind(poly_trait_ref); - let p = poly_trait_ref.skip_binder().trait_ref; + let p = poly_trait_ref.trait_ref; let self_ty = p.self_ty(); let path = p.print_only_trait_path(); let obligation = format!("{}: {}", self_ty, path); diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index 24ffe944128..124ba91f74c 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -850,7 +850,8 @@ fn bounds_from_generic_predicates<'tcx>( let mut projections = vec![]; for (predicate, _) in predicates.predicates { debug!("predicate {:?}", predicate); - match predicate.skip_binders() { + let bound_predicate = predicate.bound_atom(tcx); + match bound_predicate.skip_binder() { ty::PredicateAtom::Trait(trait_predicate, _) => { let entry = types.entry(trait_predicate.self_ty()).or_default(); let def_id = trait_predicate.def_id(); @@ -861,7 +862,7 @@ fn bounds_from_generic_predicates<'tcx>( } } ty::PredicateAtom::Projection(projection_pred) => { - projections.push(ty::Binder::bind(projection_pred)); + projections.push(bound_predicate.map_bound_ref(|_| projection_pred)); } _ => {} } diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index 7efda54fbe0..c1fa39e96eb 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -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, false, diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 1ea1a091069..f6a4dfd85a5 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -315,13 +315,16 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { tcx: TyCtxt<'tcx>, pred: ty::Predicate<'tcx>, ) -> FxHashSet { - let regions = match pred.skip_binders() { - ty::PredicateAtom::Trait(poly_trait_pred, _) => { - tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(poly_trait_pred)) - } - ty::PredicateAtom::Projection(poly_proj_pred) => { - tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(poly_proj_pred)) - } + let bound_predicate = pred.bound_atom(tcx); + let regions = match bound_predicate.skip_binder() { + ty::PredicateAtom::Trait(poly_trait_pred, _) => tcx + .collect_referenced_late_bound_regions( + &bound_predicate.map_bound_ref(|_| poly_trait_pred), + ), + ty::PredicateAtom::Projection(poly_proj_pred) => tcx + .collect_referenced_late_bound_regions( + &bound_predicate.map_bound_ref(|_| poly_proj_pred), + ), _ => return FxHashSet::default(), };