Skip to content

Commit 73496fc

Browse files
Rollup merge of rust-lang#112786 - lcnr:early-binder, r=Nilstrieb
change binders from tuple structs to named fields
2 parents 6c5e212 + 0ceb7d5 commit 73496fc

12 files changed

+83
-78
lines changed

compiler/rustc_middle/src/ty/sty.rs

+32-30
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,10 @@ impl BoundVariableKind {
10071007
/// `Decodable` and `Encodable` are implemented for `Binder<T>` using the `impl_binder_encode_decode!` macro.
10081008
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
10091009
#[derive(HashStable, Lift)]
1010-
pub struct Binder<'tcx, T>(T, &'tcx List<BoundVariableKind>);
1010+
pub struct Binder<'tcx, T> {
1011+
value: T,
1012+
bound_vars: &'tcx List<BoundVariableKind>,
1013+
}
10111014

10121015
impl<'tcx, T> Binder<'tcx, T>
10131016
where
@@ -1023,15 +1026,15 @@ where
10231026
!value.has_escaping_bound_vars(),
10241027
"`{value:?}` has escaping bound vars, so it cannot be wrapped in a dummy binder."
10251028
);
1026-
Binder(value, ty::List::empty())
1029+
Binder { value, bound_vars: ty::List::empty() }
10271030
}
10281031

1029-
pub fn bind_with_vars(value: T, vars: &'tcx List<BoundVariableKind>) -> Binder<'tcx, T> {
1032+
pub fn bind_with_vars(value: T, bound_vars: &'tcx List<BoundVariableKind>) -> Binder<'tcx, T> {
10301033
if cfg!(debug_assertions) {
1031-
let mut validator = ValidateBoundVars::new(vars);
1034+
let mut validator = ValidateBoundVars::new(bound_vars);
10321035
value.visit_with(&mut validator);
10331036
}
1034-
Binder(value, vars)
1037+
Binder { value, bound_vars }
10351038
}
10361039
}
10371040

@@ -1053,30 +1056,30 @@ impl<'tcx, T> Binder<'tcx, T> {
10531056
/// - comparing the self type of a PolyTraitRef to see if it is equal to
10541057
/// a type parameter `X`, since the type `X` does not reference any regions
10551058
pub fn skip_binder(self) -> T {
1056-
self.0
1059+
self.value
10571060
}
10581061

10591062
pub fn bound_vars(&self) -> &'tcx List<BoundVariableKind> {
1060-
self.1
1063+
self.bound_vars
10611064
}
10621065

10631066
pub fn as_ref(&self) -> Binder<'tcx, &T> {
1064-
Binder(&self.0, self.1)
1067+
Binder { value: &self.value, bound_vars: self.bound_vars }
10651068
}
10661069

10671070
pub fn as_deref(&self) -> Binder<'tcx, &T::Target>
10681071
where
10691072
T: Deref,
10701073
{
1071-
Binder(&self.0, self.1)
1074+
Binder { value: &self.value, bound_vars: self.bound_vars }
10721075
}
10731076

10741077
pub fn map_bound_ref_unchecked<F, U>(&self, f: F) -> Binder<'tcx, U>
10751078
where
10761079
F: FnOnce(&T) -> U,
10771080
{
1078-
let value = f(&self.0);
1079-
Binder(value, self.1)
1081+
let value = f(&self.value);
1082+
Binder { value, bound_vars: self.bound_vars }
10801083
}
10811084

10821085
pub fn map_bound_ref<F, U: TypeVisitable<TyCtxt<'tcx>>>(&self, f: F) -> Binder<'tcx, U>
@@ -1090,12 +1093,13 @@ impl<'tcx, T> Binder<'tcx, T> {
10901093
where
10911094
F: FnOnce(T) -> U,
10921095
{
1093-
let value = f(self.0);
1096+
let Binder { value, bound_vars } = self;
1097+
let value = f(value);
10941098
if cfg!(debug_assertions) {
1095-
let mut validator = ValidateBoundVars::new(self.1);
1099+
let mut validator = ValidateBoundVars::new(bound_vars);
10961100
value.visit_with(&mut validator);
10971101
}
1098-
Binder(value, self.1)
1102+
Binder { value, bound_vars }
10991103
}
11001104

11011105
pub fn try_map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>, E>(
@@ -1105,12 +1109,13 @@ impl<'tcx, T> Binder<'tcx, T> {
11051109
where
11061110
F: FnOnce(T) -> Result<U, E>,
11071111
{
1108-
let value = f(self.0)?;
1112+
let Binder { value, bound_vars } = self;
1113+
let value = f(value)?;
11091114
if cfg!(debug_assertions) {
1110-
let mut validator = ValidateBoundVars::new(self.1);
1115+
let mut validator = ValidateBoundVars::new(bound_vars);
11111116
value.visit_with(&mut validator);
11121117
}
1113-
Ok(Binder(value, self.1))
1118+
Ok(Binder { value, bound_vars })
11141119
}
11151120

11161121
/// Wraps a `value` in a binder, using the same bound variables as the
@@ -1126,11 +1131,7 @@ impl<'tcx, T> Binder<'tcx, T> {
11261131
where
11271132
U: TypeVisitable<TyCtxt<'tcx>>,
11281133
{
1129-
if cfg!(debug_assertions) {
1130-
let mut validator = ValidateBoundVars::new(self.bound_vars());
1131-
value.visit_with(&mut validator);
1132-
}
1133-
Binder(value, self.1)
1134+
Binder::bind_with_vars(value, self.bound_vars)
11341135
}
11351136

11361137
/// Unwraps and returns the value within, but only if it contains
@@ -1147,7 +1148,7 @@ impl<'tcx, T> Binder<'tcx, T> {
11471148
where
11481149
T: TypeVisitable<TyCtxt<'tcx>>,
11491150
{
1150-
if self.0.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
1151+
if self.value.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
11511152
}
11521153

11531154
/// Splits the contents into two things that share the same binder
@@ -1160,22 +1161,23 @@ impl<'tcx, T> Binder<'tcx, T> {
11601161
where
11611162
F: FnOnce(T) -> (U, V),
11621163
{
1163-
let (u, v) = f(self.0);
1164-
(Binder(u, self.1), Binder(v, self.1))
1164+
let Binder { value, bound_vars } = self;
1165+
let (u, v) = f(value);
1166+
(Binder { value: u, bound_vars }, Binder { value: v, bound_vars })
11651167
}
11661168
}
11671169

11681170
impl<'tcx, T> Binder<'tcx, Option<T>> {
11691171
pub fn transpose(self) -> Option<Binder<'tcx, T>> {
1170-
let bound_vars = self.1;
1171-
self.0.map(|v| Binder(v, bound_vars))
1172+
let Binder { value, bound_vars } = self;
1173+
value.map(|value| Binder { value, bound_vars })
11721174
}
11731175
}
11741176

11751177
impl<'tcx, T: IntoIterator> Binder<'tcx, T> {
11761178
pub fn iter(self) -> impl Iterator<Item = ty::Binder<'tcx, T::Item>> {
1177-
let bound_vars = self.1;
1178-
self.0.into_iter().map(|v| Binder(v, bound_vars))
1179+
let Binder { value, bound_vars } = self;
1180+
value.into_iter().map(|value| Binder { value, bound_vars })
11791181
}
11801182
}
11811183

@@ -1184,7 +1186,7 @@ where
11841186
T: IntoDiagnosticArg,
11851187
{
11861188
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
1187-
self.0.into_diagnostic_arg()
1189+
self.value.into_diagnostic_arg()
11881190
}
11891191
}
11901192

compiler/rustc_middle/src/ty/subst.rs

+28-25
Original file line numberDiff line numberDiff line change
@@ -538,19 +538,21 @@ impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>> for &'tcx
538538
/// [`subst_identity`](EarlyBinder::subst_identity) or [`skip_binder`](EarlyBinder::skip_binder).
539539
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
540540
#[derive(Encodable, Decodable, HashStable)]
541-
pub struct EarlyBinder<T>(T);
541+
pub struct EarlyBinder<T> {
542+
value: T,
543+
}
542544

543545
/// For early binders, you should first call `subst` before using any visitors.
544546
impl<'tcx, T> !TypeFoldable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {}
545547
impl<'tcx, T> !TypeVisitable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {}
546548

547549
impl<T> EarlyBinder<T> {
548-
pub fn bind(inner: T) -> EarlyBinder<T> {
549-
EarlyBinder(inner)
550+
pub fn bind(value: T) -> EarlyBinder<T> {
551+
EarlyBinder { value }
550552
}
551553

552554
pub fn as_ref(&self) -> EarlyBinder<&T> {
553-
EarlyBinder(&self.0)
555+
EarlyBinder { value: &self.value }
554556
}
555557

556558
pub fn map_bound_ref<F, U>(&self, f: F) -> EarlyBinder<U>
@@ -564,20 +566,20 @@ impl<T> EarlyBinder<T> {
564566
where
565567
F: FnOnce(T) -> U,
566568
{
567-
let value = f(self.0);
568-
EarlyBinder(value)
569+
let value = f(self.value);
570+
EarlyBinder { value }
569571
}
570572

571573
pub fn try_map_bound<F, U, E>(self, f: F) -> Result<EarlyBinder<U>, E>
572574
where
573575
F: FnOnce(T) -> Result<U, E>,
574576
{
575-
let value = f(self.0)?;
576-
Ok(EarlyBinder(value))
577+
let value = f(self.value)?;
578+
Ok(EarlyBinder { value })
577579
}
578580

579581
pub fn rebind<U>(&self, value: U) -> EarlyBinder<U> {
580-
EarlyBinder(value)
582+
EarlyBinder { value }
581583
}
582584

583585
/// Skips the binder and returns the "bound" value.
@@ -592,19 +594,20 @@ impl<T> EarlyBinder<T> {
592594
/// See also [`Binder::skip_binder`](super::Binder::skip_binder), which is
593595
/// the analogous operation on [`super::Binder`].
594596
pub fn skip_binder(self) -> T {
595-
self.0
597+
self.value
596598
}
597599
}
598600

599601
impl<T> EarlyBinder<Option<T>> {
600602
pub fn transpose(self) -> Option<EarlyBinder<T>> {
601-
self.0.map(|v| EarlyBinder(v))
603+
self.value.map(|value| EarlyBinder { value })
602604
}
603605
}
604606

605607
impl<T, U> EarlyBinder<(T, U)> {
606608
pub fn transpose_tuple2(self) -> (EarlyBinder<T>, EarlyBinder<U>) {
607-
(EarlyBinder(self.0.0), EarlyBinder(self.0.1))
609+
let EarlyBinder { value: (lhs, rhs) } = self;
610+
(EarlyBinder { value: lhs }, EarlyBinder { value: rhs })
608611
}
609612
}
610613

@@ -617,13 +620,13 @@ where
617620
tcx: TyCtxt<'tcx>,
618621
substs: &'s [GenericArg<'tcx>],
619622
) -> SubstIter<'s, 'tcx, I> {
620-
SubstIter { it: self.0.into_iter(), tcx, substs }
623+
SubstIter { it: self.value.into_iter(), tcx, substs }
621624
}
622625

623626
/// Similar to [`subst_identity`](EarlyBinder::subst_identity),
624627
/// but on an iterator of `TypeFoldable` values.
625628
pub fn subst_identity_iter(self) -> I::IntoIter {
626-
self.0.into_iter()
629+
self.value.into_iter()
627630
}
628631
}
629632

@@ -640,7 +643,7 @@ where
640643
type Item = I::Item;
641644

642645
fn next(&mut self) -> Option<Self::Item> {
643-
Some(EarlyBinder(self.it.next()?).subst(self.tcx, self.substs))
646+
Some(EarlyBinder { value: self.it.next()? }.subst(self.tcx, self.substs))
644647
}
645648

646649
fn size_hint(&self) -> (usize, Option<usize>) {
@@ -654,7 +657,7 @@ where
654657
I::Item: TypeFoldable<TyCtxt<'tcx>>,
655658
{
656659
fn next_back(&mut self) -> Option<Self::Item> {
657-
Some(EarlyBinder(self.it.next_back()?).subst(self.tcx, self.substs))
660+
Some(EarlyBinder { value: self.it.next_back()? }.subst(self.tcx, self.substs))
658661
}
659662
}
660663

@@ -675,13 +678,13 @@ where
675678
tcx: TyCtxt<'tcx>,
676679
substs: &'s [GenericArg<'tcx>],
677680
) -> SubstIterCopied<'s, 'tcx, I> {
678-
SubstIterCopied { it: self.0.into_iter(), tcx, substs }
681+
SubstIterCopied { it: self.value.into_iter(), tcx, substs }
679682
}
680683

681684
/// Similar to [`subst_identity`](EarlyBinder::subst_identity),
682685
/// but on an iterator of values that deref to a `TypeFoldable`.
683686
pub fn subst_identity_iter_copied(self) -> impl Iterator<Item = <I::Item as Deref>::Target> {
684-
self.0.into_iter().map(|v| *v)
687+
self.value.into_iter().map(|v| *v)
685688
}
686689
}
687690

@@ -699,7 +702,7 @@ where
699702
type Item = <I::Item as Deref>::Target;
700703

701704
fn next(&mut self) -> Option<Self::Item> {
702-
Some(EarlyBinder(*self.it.next()?).subst(self.tcx, self.substs))
705+
self.it.next().map(|value| EarlyBinder { value: *value }.subst(self.tcx, self.substs))
703706
}
704707

705708
fn size_hint(&self) -> (usize, Option<usize>) {
@@ -714,7 +717,7 @@ where
714717
<I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>,
715718
{
716719
fn next_back(&mut self) -> Option<Self::Item> {
717-
Some(EarlyBinder(*self.it.next_back()?).subst(self.tcx, self.substs))
720+
self.it.next_back().map(|value| EarlyBinder { value: *value }.subst(self.tcx, self.substs))
718721
}
719722
}
720723

@@ -732,15 +735,15 @@ pub struct EarlyBinderIter<T> {
732735

733736
impl<T: IntoIterator> EarlyBinder<T> {
734737
pub fn transpose_iter(self) -> EarlyBinderIter<T::IntoIter> {
735-
EarlyBinderIter { t: self.0.into_iter() }
738+
EarlyBinderIter { t: self.value.into_iter() }
736739
}
737740
}
738741

739742
impl<T: Iterator> Iterator for EarlyBinderIter<T> {
740743
type Item = EarlyBinder<T::Item>;
741744

742745
fn next(&mut self) -> Option<Self::Item> {
743-
self.t.next().map(|i| EarlyBinder(i))
746+
self.t.next().map(|value| EarlyBinder { value })
744747
}
745748

746749
fn size_hint(&self) -> (usize, Option<usize>) {
@@ -751,7 +754,7 @@ impl<T: Iterator> Iterator for EarlyBinderIter<T> {
751754
impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> ty::EarlyBinder<T> {
752755
pub fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> T {
753756
let mut folder = SubstFolder { tcx, substs, binders_passed: 0 };
754-
self.0.fold_with(&mut folder)
757+
self.value.fold_with(&mut folder)
755758
}
756759

757760
/// Makes the identity substitution `T0 => T0, ..., TN => TN`.
@@ -763,12 +766,12 @@ impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> ty::EarlyBinder<T> {
763766
/// - Inside of the body of `foo`, we treat `T` as a placeholder by calling
764767
/// `subst_identity` to discharge the `EarlyBinder`.
765768
pub fn subst_identity(self) -> T {
766-
self.0
769+
self.value
767770
}
768771

769772
/// Returns the inner value, but only if it contains no bound vars.
770773
pub fn no_bound_vars(self) -> Option<T> {
771-
if !self.0.has_param() { Some(self.0) } else { None }
774+
if !self.value.has_param() { Some(self.value) } else { None }
772775
}
773776
}
774777

tests/ui/chalkify/bugs/async.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | async fn foo(x: u32) -> u32 {
77
= help: the trait `Future` is not implemented for `[async fn body@$DIR/async.rs:23:29: 25:2]`
88
= note: [async fn body@$DIR/async.rs:23:29: 25:2] must be a future or must implement `IntoFuture` to be awaited
99

10-
error: internal compiler error: projection clauses should be implied from elsewhere. obligation: `Obligation(predicate=Binder(ProjectionPredicate(AliasTy { substs: [[async fn body@$DIR/async.rs:23:29: 25:2]], def_id: ... }, Term::Ty(u32)), []), depth=0)`
10+
error: internal compiler error: projection clauses should be implied from elsewhere. obligation: `Obligation(predicate=Binder { value: ProjectionPredicate(AliasTy { substs: [[async fn body@$DIR/async.rs:23:29: 25:2]], def_id: ... }, Term::Ty(u32)), bound_vars: [] }, depth=0)`
1111
--> $DIR/async.rs:23:25
1212
|
1313
LL | async fn foo(x: u32) -> u32 {

tests/ui/traits/cache-reached-depth-ice.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,5 @@ fn test<X: ?Sized + Send>() {}
4141

4242
fn main() {
4343
test::<A>();
44-
//~^ ERROR evaluate(Binder(TraitPredicate(<A as std::marker::Send>, polarity:Positive), [])) = Ok(EvaluatedToOk)
44+
//~^ ERROR evaluate(Binder { value: TraitPredicate(<A as std::marker::Send>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOk)
4545
}

tests/ui/traits/cache-reached-depth-ice.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: evaluate(Binder(TraitPredicate(<A as std::marker::Send>, polarity:Positive), [])) = Ok(EvaluatedToOk)
1+
error: evaluate(Binder { value: TraitPredicate(<A as std::marker::Send>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOk)
22
--> $DIR/cache-reached-depth-ice.rs:43:5
33
|
44
LL | fn test<X: ?Sized + Send>() {}

tests/ui/traits/issue-83538-tainted-cache-after-cycle.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ fn main() {
5757
// Key is that Vec<First> is "ok" and Third<'_, Ty> is "ok modulo regions":
5858

5959
forward();
60-
//~^ ERROR evaluate(Binder(TraitPredicate(<std::vec::Vec<First> as std::marker::Unpin>, polarity:Positive), [])) = Ok(EvaluatedToOk)
61-
//~| ERROR evaluate(Binder(TraitPredicate(<Third<'_, Ty> as std::marker::Unpin>, polarity:Positive), [])) = Ok(EvaluatedToOkModuloRegions)
60+
//~^ ERROR evaluate(Binder { value: TraitPredicate(<std::vec::Vec<First> as std::marker::Unpin>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOk)
61+
//~| ERROR evaluate(Binder { value: TraitPredicate(<Third<'_, Ty> as std::marker::Unpin>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOkModuloRegions)
6262

6363
reverse();
64-
//~^ ERROR evaluate(Binder(TraitPredicate(<std::vec::Vec<First> as std::marker::Unpin>, polarity:Positive), [])) = Ok(EvaluatedToOk)
65-
//~| ERROR evaluate(Binder(TraitPredicate(<Third<'_, Ty> as std::marker::Unpin>, polarity:Positive), [])) = Ok(EvaluatedToOkModuloRegions)
64+
//~^ ERROR evaluate(Binder { value: TraitPredicate(<std::vec::Vec<First> as std::marker::Unpin>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOk)
65+
//~| ERROR evaluate(Binder { value: TraitPredicate(<Third<'_, Ty> as std::marker::Unpin>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOkModuloRegions)
6666
}

0 commit comments

Comments
 (0)