Skip to content

Commit 6f0ea29

Browse files
committed
Auto merge of #77685 - jackh726:binder-map, r=lcnr
Use rebind instead of Binder::bind when possible These are really only the easy places. I just searched for `Binder::bind` and replaced where it straightforward. r? `@lcnr` cc. `@nikomatsakis`
2 parents 03687f8 + f6a53b4 commit 6f0ea29

File tree

24 files changed

+194
-139
lines changed

24 files changed

+194
-139
lines changed

compiler/rustc_codegen_llvm/src/intrinsic.rs

+14-13
Original file line numberDiff line numberDiff line change
@@ -673,17 +673,9 @@ fn codegen_emcc_try(
673673
fn gen_fn<'ll, 'tcx>(
674674
cx: &CodegenCx<'ll, 'tcx>,
675675
name: &str,
676-
inputs: Vec<Ty<'tcx>>,
677-
output: Ty<'tcx>,
676+
rust_fn_sig: ty::PolyFnSig<'tcx>,
678677
codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>),
679678
) -> &'ll Value {
680-
let rust_fn_sig = ty::Binder::bind(cx.tcx.mk_fn_sig(
681-
inputs.into_iter(),
682-
output,
683-
false,
684-
hir::Unsafety::Unsafe,
685-
Abi::Rust,
686-
));
687679
let fn_abi = FnAbi::of_fn_ptr(cx, rust_fn_sig, &[]);
688680
let llfn = cx.declare_fn(name, &fn_abi);
689681
cx.set_frame_pointer_elimination(llfn);
@@ -710,22 +702,31 @@ fn get_rust_try_fn<'ll, 'tcx>(
710702
// Define the type up front for the signature of the rust_try function.
711703
let tcx = cx.tcx;
712704
let i8p = tcx.mk_mut_ptr(tcx.types.i8);
713-
let try_fn_ty = tcx.mk_fn_ptr(ty::Binder::bind(tcx.mk_fn_sig(
705+
// `unsafe fn(*mut i8) -> ()`
706+
let try_fn_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig(
714707
iter::once(i8p),
715708
tcx.mk_unit(),
716709
false,
717710
hir::Unsafety::Unsafe,
718711
Abi::Rust,
719712
)));
720-
let catch_fn_ty = tcx.mk_fn_ptr(ty::Binder::bind(tcx.mk_fn_sig(
713+
// `unsafe fn(*mut i8, *mut i8) -> ()`
714+
let catch_fn_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig(
721715
[i8p, i8p].iter().cloned(),
722716
tcx.mk_unit(),
723717
false,
724718
hir::Unsafety::Unsafe,
725719
Abi::Rust,
726720
)));
727-
let output = tcx.types.i32;
728-
let rust_try = gen_fn(cx, "__rust_try", vec![try_fn_ty, i8p, catch_fn_ty], output, codegen);
721+
// `unsafe fn(unsafe fn(*mut i8) -> (), *mut i8, unsafe fn(*mut i8, *mut i8) -> ()) -> i32`
722+
let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig(
723+
vec![try_fn_ty, i8p, catch_fn_ty].into_iter(),
724+
tcx.types.i32,
725+
false,
726+
hir::Unsafety::Unsafe,
727+
Abi::Rust,
728+
));
729+
let rust_try = gen_fn(cx, "__rust_try", rust_fn_sig, codegen);
729730
cx.rust_try_fn.set(Some(rust_try));
730731
rust_try
731732
}

compiler/rustc_infer/src/infer/nll_relate/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ where
636636
if let (Some(a), Some(b)) = (a.no_bound_vars(), b.no_bound_vars()) {
637637
// Fast path for the common case.
638638
self.relate(a, b)?;
639-
return Ok(ty::Binder::bind(a));
639+
return Ok(ty::Binder::dummy(a));
640640
}
641641

642642
if self.ambient_covariance() {

compiler/rustc_infer/src/traits/util.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,15 @@ impl Elaborator<'tcx> {
126126
fn elaborate(&mut self, obligation: &PredicateObligation<'tcx>) {
127127
let tcx = self.visited.tcx;
128128

129-
match obligation.predicate.skip_binders() {
129+
let bound_predicate = obligation.predicate.bound_atom();
130+
match bound_predicate.skip_binder() {
130131
ty::PredicateAtom::Trait(data, _) => {
131132
// Get predicates declared on the trait.
132133
let predicates = tcx.super_predicates_of(data.def_id());
133134

134135
let obligations = predicates.predicates.iter().map(|&(pred, _)| {
135136
predicate_obligation(
136-
pred.subst_supertrait(tcx, &ty::Binder::bind(data.trait_ref)),
137+
pred.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref)),
137138
obligation.param_env,
138139
obligation.cause.clone(),
139140
)

compiler/rustc_middle/src/ty/mod.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -1056,9 +1056,21 @@ impl<'tcx> Predicate<'tcx> {
10561056
}
10571057
}
10581058

1059+
/// Converts this to a `Binder<PredicateAtom<'tcx>>`. If the value was an
1060+
/// `Atom`, then it is not allowed to contain escaping bound vars.
1061+
pub fn bound_atom(self) -> Binder<PredicateAtom<'tcx>> {
1062+
match self.kind() {
1063+
&PredicateKind::ForAll(binder) => binder,
1064+
&PredicateKind::Atom(atom) => {
1065+
debug_assert!(!atom.has_escaping_bound_vars());
1066+
Binder::dummy(atom)
1067+
}
1068+
}
1069+
}
1070+
10591071
/// Allows using a `Binder<PredicateAtom<'tcx>>` even if the given predicate previously
10601072
/// contained unbound variables by shifting these variables outwards.
1061-
pub fn bound_atom(self, tcx: TyCtxt<'tcx>) -> Binder<PredicateAtom<'tcx>> {
1073+
pub fn bound_atom_with_opt_escaping(self, tcx: TyCtxt<'tcx>) -> Binder<PredicateAtom<'tcx>> {
10621074
match self.kind() {
10631075
&PredicateKind::ForAll(binder) => binder,
10641076
&PredicateKind::Atom(atom) => Binder::wrap_nonbinding(tcx, atom),

compiler/rustc_middle/src/ty/print/pretty.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -618,10 +618,9 @@ pub trait PrettyPrinter<'tcx>:
618618
// may contain unbound variables. We therefore do this manually.
619619
//
620620
// FIXME(lcnr): Find out why exactly this is the case :)
621-
if let ty::PredicateAtom::Trait(pred, _) =
622-
predicate.bound_atom(self.tcx()).skip_binder()
623-
{
624-
let trait_ref = ty::Binder::bind(pred.trait_ref);
621+
let bound_predicate = predicate.bound_atom_with_opt_escaping(self.tcx());
622+
if let ty::PredicateAtom::Trait(pred, _) = bound_predicate.skip_binder() {
623+
let trait_ref = bound_predicate.rebind(pred.trait_ref);
625624
// Don't print +Sized, but rather +?Sized if absent.
626625
if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() {
627626
is_sized = true;

compiler/rustc_middle/src/ty/structural_impls.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateAtom<'a> {
549549
impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<T> {
550550
type Lifted = ty::Binder<T::Lifted>;
551551
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
552-
tcx.lift(self.as_ref().skip_binder()).map(ty::Binder::bind)
552+
tcx.lift(self.as_ref().skip_binder()).map(|v| self.rebind(v))
553553
}
554554
}
555555

compiler/rustc_middle/src/ty/sty.rs

+21-7
Original file line numberDiff line numberDiff line change
@@ -703,14 +703,16 @@ impl<'tcx> Binder<ExistentialPredicate<'tcx>> {
703703
use crate::ty::ToPredicate;
704704
match self.skip_binder() {
705705
ExistentialPredicate::Trait(tr) => {
706-
Binder(tr).with_self_ty(tcx, self_ty).without_const().to_predicate(tcx)
706+
self.rebind(tr).with_self_ty(tcx, self_ty).without_const().to_predicate(tcx)
707707
}
708708
ExistentialPredicate::Projection(p) => {
709-
Binder(p.with_self_ty(tcx, self_ty)).to_predicate(tcx)
709+
self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx)
710710
}
711711
ExistentialPredicate::AutoTrait(did) => {
712-
let trait_ref =
713-
Binder(ty::TraitRef { def_id: did, substs: tcx.mk_substs_trait(self_ty, &[]) });
712+
let trait_ref = self.rebind(ty::TraitRef {
713+
def_id: did,
714+
substs: tcx.mk_substs_trait(self_ty, &[]),
715+
});
714716
trait_ref.without_const().to_predicate(tcx)
715717
}
716718
}
@@ -775,7 +777,7 @@ impl<'tcx> List<ExistentialPredicate<'tcx>> {
775777

776778
impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> {
777779
pub fn principal(&self) -> Option<ty::Binder<ExistentialTraitRef<'tcx>>> {
778-
self.skip_binder().principal().map(Binder::bind)
780+
self.map_bound(|b| b.principal()).transpose()
779781
}
780782

781783
pub fn principal_def_id(&self) -> Option<DefId> {
@@ -858,8 +860,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
858860
}
859861

860862
pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> {
861-
// Note that we preserve binding levels
862-
Binder(ty::TraitPredicate { trait_ref: self.skip_binder() })
863+
self.map_bound(|trait_ref| ty::TraitPredicate { trait_ref })
863864
}
864865
}
865866

@@ -1001,6 +1002,19 @@ impl<T> Binder<T> {
10011002
Binder(f(self.0))
10021003
}
10031004

1005+
/// Wraps a `value` in a binder, using the same bound variables as the
1006+
/// current `Binder`. This should not be used if the new value *changes*
1007+
/// the bound variables. Note: the (old or new) value itself does not
1008+
/// necessarily need to *name* all the bound variables.
1009+
///
1010+
/// This currently doesn't do anything different than `bind`, because we
1011+
/// don't actually track bound vars. However, semantically, it is different
1012+
/// because bound vars aren't allowed to change here, whereas they are
1013+
/// in `bind`. This may be (debug) asserted in the future.
1014+
pub fn rebind<U>(&self, value: U) -> Binder<U> {
1015+
Binder(value)
1016+
}
1017+
10041018
/// Unwraps and returns the value within, but only if it contains
10051019
/// no bound vars at all. (In other words, if this binder --
10061020
/// and indeed any enclosing binder -- doesn't bind anything at

compiler/rustc_trait_selection/src/traits/auto_trait.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -642,18 +642,19 @@ impl AutoTraitFinder<'tcx> {
642642
// We check this by calling is_of_param on the relevant types
643643
// from the various possible predicates
644644

645-
match predicate.skip_binders() {
645+
let bound_predicate = predicate.bound_atom();
646+
match bound_predicate.skip_binder() {
646647
ty::PredicateAtom::Trait(p, _) => {
647648
if self.is_param_no_infer(p.trait_ref.substs)
648649
&& !only_projections
649650
&& is_new_pred
650651
{
651652
self.add_user_pred(computed_preds, predicate);
652653
}
653-
predicates.push_back(ty::Binder::bind(p));
654+
predicates.push_back(bound_predicate.rebind(p));
654655
}
655656
ty::PredicateAtom::Projection(p) => {
656-
let p = ty::Binder::bind(p);
657+
let p = bound_predicate.rebind(p);
657658
debug!(
658659
"evaluate_nested_obligations: examining projection predicate {:?}",
659660
predicate
@@ -783,13 +784,13 @@ impl AutoTraitFinder<'tcx> {
783784
}
784785
}
785786
ty::PredicateAtom::RegionOutlives(binder) => {
786-
let binder = ty::Binder::bind(binder);
787+
let binder = bound_predicate.rebind(binder);
787788
if select.infcx().region_outlives_predicate(&dummy_cause, binder).is_err() {
788789
return false;
789790
}
790791
}
791792
ty::PredicateAtom::TypeOutlives(binder) => {
792-
let binder = ty::Binder::bind(binder);
793+
let binder = bound_predicate.rebind(binder);
793794
match (
794795
binder.no_bound_vars(),
795796
binder.map_bound_ref(|pred| pred.0).no_bound_vars(),

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+18-13
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
255255
return;
256256
}
257257

258-
match obligation.predicate.skip_binders() {
258+
let bound_predicate = obligation.predicate.bound_atom();
259+
match bound_predicate.skip_binder() {
259260
ty::PredicateAtom::Trait(trait_predicate, _) => {
260-
let trait_predicate = ty::Binder::bind(trait_predicate);
261+
let trait_predicate = bound_predicate.rebind(trait_predicate);
261262
let trait_predicate = self.resolve_vars_if_possible(&trait_predicate);
262263

263264
if self.tcx.sess.has_errors() && trait_predicate.references_error() {
@@ -531,7 +532,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
531532
}
532533

533534
ty::PredicateAtom::RegionOutlives(predicate) => {
534-
let predicate = ty::Binder::bind(predicate);
535+
let predicate = bound_predicate.rebind(predicate);
535536
let predicate = self.resolve_vars_if_possible(&predicate);
536537
let err = self
537538
.region_outlives_predicate(&obligation.cause, predicate)
@@ -1078,9 +1079,10 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
10781079
}
10791080

10801081
// FIXME: It should be possible to deal with `ForAll` in a cleaner way.
1081-
let (cond, error) = match (cond.skip_binders(), error.skip_binders()) {
1082+
let bound_error = error.bound_atom();
1083+
let (cond, error) = match (cond.skip_binders(), bound_error.skip_binder()) {
10821084
(ty::PredicateAtom::Trait(..), ty::PredicateAtom::Trait(error, _)) => {
1083-
(cond, ty::Binder::bind(error))
1085+
(cond, bound_error.rebind(error))
10841086
}
10851087
_ => {
10861088
// FIXME: make this work in other cases too.
@@ -1089,9 +1091,10 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
10891091
};
10901092

10911093
for obligation in super::elaborate_predicates(self.tcx, std::iter::once(cond)) {
1092-
if let ty::PredicateAtom::Trait(implication, _) = obligation.predicate.skip_binders() {
1094+
let bound_predicate = obligation.predicate.bound_atom();
1095+
if let ty::PredicateAtom::Trait(implication, _) = bound_predicate.skip_binder() {
10931096
let error = error.to_poly_trait_ref();
1094-
let implication = ty::Binder::bind(implication.trait_ref);
1097+
let implication = bound_predicate.rebind(implication.trait_ref);
10951098
// FIXME: I'm just not taking associated types at all here.
10961099
// Eventually I'll need to implement param-env-aware
10971100
// `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic.
@@ -1169,12 +1172,13 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
11691172
//
11701173
// this can fail if the problem was higher-ranked, in which
11711174
// cause I have no idea for a good error message.
1172-
if let ty::PredicateAtom::Projection(data) = predicate.skip_binders() {
1175+
let bound_predicate = predicate.bound_atom();
1176+
if let ty::PredicateAtom::Projection(data) = bound_predicate.skip_binder() {
11731177
let mut selcx = SelectionContext::new(self);
11741178
let (data, _) = self.replace_bound_vars_with_fresh_vars(
11751179
obligation.cause.span,
11761180
infer::LateBoundRegionConversionTime::HigherRankedType,
1177-
&ty::Binder::bind(data),
1181+
&bound_predicate.rebind(data),
11781182
);
11791183
let mut obligations = vec![];
11801184
let normalized_ty = super::normalize_projection_type(
@@ -1455,10 +1459,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
14551459
return;
14561460
}
14571461

1458-
let mut err = match predicate.skip_binders() {
1462+
let bound_predicate = predicate.bound_atom();
1463+
let mut err = match bound_predicate.skip_binder() {
14591464
ty::PredicateAtom::Trait(data, _) => {
1460-
let trait_ref = ty::Binder::bind(data.trait_ref);
1461-
let self_ty = trait_ref.skip_binder().self_ty();
1465+
let self_ty = data.trait_ref.self_ty();
1466+
let trait_ref = bound_predicate.rebind(data.trait_ref);
14621467
debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind(), trait_ref);
14631468

14641469
if predicate.references_error() {
@@ -1582,7 +1587,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
15821587
self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282)
15831588
}
15841589
ty::PredicateAtom::Projection(data) => {
1585-
let trait_ref = ty::Binder::bind(data).to_poly_trait_ref(self.tcx);
1590+
let trait_ref = bound_predicate.rebind(data).to_poly_trait_ref(self.tcx);
15861591
let self_ty = trait_ref.skip_binder().self_ty();
15871592
let ty = data.ty;
15881593
if predicate.references_error() {

compiler/rustc_trait_selection/src/traits/fulfill.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
353353
// This means we need to pass it the bound version of our
354354
// predicate.
355355
ty::PredicateAtom::Trait(trait_ref, _constness) => {
356-
let trait_obligation = obligation.with(Binder::bind(trait_ref));
356+
let trait_obligation = obligation.with(binder.rebind(trait_ref));
357357

358358
self.process_trait_obligation(
359359
obligation,
@@ -362,7 +362,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
362362
)
363363
}
364364
ty::PredicateAtom::Projection(data) => {
365-
let project_obligation = obligation.with(Binder::bind(data));
365+
let project_obligation = obligation.with(binder.rebind(data));
366366

367367
self.process_projection_obligation(
368368
project_obligation,

compiler/rustc_trait_selection/src/traits/project.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,8 @@ fn prune_cache_value_obligations<'a, 'tcx>(
623623
.obligations
624624
.iter()
625625
.filter(|obligation| {
626-
match obligation.predicate.skip_binders() {
626+
let bound_predicate = obligation.predicate.bound_atom();
627+
match bound_predicate.skip_binder() {
627628
// We found a `T: Foo<X = U>` predicate, let's check
628629
// if `U` references any unresolved type
629630
// variables. In principle, we only care if this
@@ -634,7 +635,7 @@ fn prune_cache_value_obligations<'a, 'tcx>(
634635
// but we have `T: Foo<X = ?1>` and `?1: Bar<X =
635636
// ?0>`).
636637
ty::PredicateAtom::Projection(data) => {
637-
infcx.unresolved_type_vars(&ty::Binder::bind(data.ty)).is_some()
638+
infcx.unresolved_type_vars(&bound_predicate.rebind(data.ty)).is_some()
638639
}
639640

640641
// We are only interested in `T: Foo<X = U>` predicates, whre
@@ -907,8 +908,9 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
907908
let infcx = selcx.infcx();
908909
for predicate in env_predicates {
909910
debug!(?predicate);
911+
let bound_predicate = predicate.bound_atom();
910912
if let ty::PredicateAtom::Projection(data) = predicate.skip_binders() {
911-
let data = ty::Binder::bind(data);
913+
let data = bound_predicate.rebind(data);
912914
let same_def_id = data.projection_def_id() == obligation.predicate.item_def_id;
913915

914916
let is_match = same_def_id

0 commit comments

Comments
 (0)