change binders from tuple structs to named fields
This commit is contained in:
parent
8d1fa473dd
commit
f2975810a5
@ -1007,7 +1007,10 @@ pub fn expect_const(self) {
|
||||
/// `Decodable` and `Encodable` are implemented for `Binder<T>` using the `impl_binder_encode_decode!` macro.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
#[derive(HashStable, Lift)]
|
||||
pub struct Binder<'tcx, T>(T, &'tcx List<BoundVariableKind>);
|
||||
pub struct Binder<'tcx, T> {
|
||||
value: T,
|
||||
bound_vars: &'tcx List<BoundVariableKind>,
|
||||
}
|
||||
|
||||
impl<'tcx, T> Binder<'tcx, T>
|
||||
where
|
||||
@ -1023,15 +1026,15 @@ pub fn dummy(value: T) -> Binder<'tcx, T> {
|
||||
!value.has_escaping_bound_vars(),
|
||||
"`{value:?}` has escaping bound vars, so it cannot be wrapped in a dummy binder."
|
||||
);
|
||||
Binder(value, ty::List::empty())
|
||||
Binder { value, bound_vars: ty::List::empty() }
|
||||
}
|
||||
|
||||
pub fn bind_with_vars(value: T, vars: &'tcx List<BoundVariableKind>) -> Binder<'tcx, T> {
|
||||
pub fn bind_with_vars(value: T, bound_vars: &'tcx List<BoundVariableKind>) -> Binder<'tcx, T> {
|
||||
if cfg!(debug_assertions) {
|
||||
let mut validator = ValidateBoundVars::new(vars);
|
||||
let mut validator = ValidateBoundVars::new(bound_vars);
|
||||
value.visit_with(&mut validator);
|
||||
}
|
||||
Binder(value, vars)
|
||||
Binder { value, bound_vars }
|
||||
}
|
||||
}
|
||||
|
||||
@ -1053,30 +1056,30 @@ impl<'tcx, T> Binder<'tcx, T> {
|
||||
/// - comparing the self type of a PolyTraitRef to see if it is equal to
|
||||
/// a type parameter `X`, since the type `X` does not reference any regions
|
||||
pub fn skip_binder(self) -> T {
|
||||
self.0
|
||||
self.value
|
||||
}
|
||||
|
||||
pub fn bound_vars(&self) -> &'tcx List<BoundVariableKind> {
|
||||
self.1
|
||||
self.bound_vars
|
||||
}
|
||||
|
||||
pub fn as_ref(&self) -> Binder<'tcx, &T> {
|
||||
Binder(&self.0, self.1)
|
||||
Binder { value: &self.value, bound_vars: self.bound_vars }
|
||||
}
|
||||
|
||||
pub fn as_deref(&self) -> Binder<'tcx, &T::Target>
|
||||
where
|
||||
T: Deref,
|
||||
{
|
||||
Binder(&self.0, self.1)
|
||||
Binder { value: &self.value, bound_vars: self.bound_vars }
|
||||
}
|
||||
|
||||
pub fn map_bound_ref_unchecked<F, U>(&self, f: F) -> Binder<'tcx, U>
|
||||
where
|
||||
F: FnOnce(&T) -> U,
|
||||
{
|
||||
let value = f(&self.0);
|
||||
Binder(value, self.1)
|
||||
let value = f(&self.value);
|
||||
Binder { value, bound_vars: self.bound_vars }
|
||||
}
|
||||
|
||||
pub fn map_bound_ref<F, U: TypeVisitable<TyCtxt<'tcx>>>(&self, f: F) -> Binder<'tcx, U>
|
||||
@ -1090,12 +1093,13 @@ pub fn map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>>(self, f: F) -> Binder<'tcx,
|
||||
where
|
||||
F: FnOnce(T) -> U,
|
||||
{
|
||||
let value = f(self.0);
|
||||
let Binder { value, bound_vars } = self;
|
||||
let value = f(value);
|
||||
if cfg!(debug_assertions) {
|
||||
let mut validator = ValidateBoundVars::new(self.1);
|
||||
let mut validator = ValidateBoundVars::new(bound_vars);
|
||||
value.visit_with(&mut validator);
|
||||
}
|
||||
Binder(value, self.1)
|
||||
Binder { value, bound_vars }
|
||||
}
|
||||
|
||||
pub fn try_map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>, E>(
|
||||
@ -1105,12 +1109,13 @@ pub fn try_map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>, E>(
|
||||
where
|
||||
F: FnOnce(T) -> Result<U, E>,
|
||||
{
|
||||
let value = f(self.0)?;
|
||||
let Binder { value, bound_vars } = self;
|
||||
let value = f(value)?;
|
||||
if cfg!(debug_assertions) {
|
||||
let mut validator = ValidateBoundVars::new(self.1);
|
||||
let mut validator = ValidateBoundVars::new(bound_vars);
|
||||
value.visit_with(&mut validator);
|
||||
}
|
||||
Ok(Binder(value, self.1))
|
||||
Ok(Binder { value, bound_vars })
|
||||
}
|
||||
|
||||
/// Wraps a `value` in a binder, using the same bound variables as the
|
||||
@ -1126,11 +1131,7 @@ pub fn rebind<U>(&self, value: U) -> Binder<'tcx, U>
|
||||
where
|
||||
U: TypeVisitable<TyCtxt<'tcx>>,
|
||||
{
|
||||
if cfg!(debug_assertions) {
|
||||
let mut validator = ValidateBoundVars::new(self.bound_vars());
|
||||
value.visit_with(&mut validator);
|
||||
}
|
||||
Binder(value, self.1)
|
||||
Binder::bind_with_vars(value, self.bound_vars)
|
||||
}
|
||||
|
||||
/// Unwraps and returns the value within, but only if it contains
|
||||
@ -1147,7 +1148,7 @@ pub fn no_bound_vars(self) -> Option<T>
|
||||
where
|
||||
T: TypeVisitable<TyCtxt<'tcx>>,
|
||||
{
|
||||
if self.0.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
|
||||
if self.value.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
|
||||
}
|
||||
|
||||
/// Splits the contents into two things that share the same binder
|
||||
@ -1160,22 +1161,23 @@ pub fn split<U, V, F>(self, f: F) -> (Binder<'tcx, U>, Binder<'tcx, V>)
|
||||
where
|
||||
F: FnOnce(T) -> (U, V),
|
||||
{
|
||||
let (u, v) = f(self.0);
|
||||
(Binder(u, self.1), Binder(v, self.1))
|
||||
let Binder { value, bound_vars } = self;
|
||||
let (u, v) = f(value);
|
||||
(Binder { value: u, bound_vars }, Binder { value: v, bound_vars })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T> Binder<'tcx, Option<T>> {
|
||||
pub fn transpose(self) -> Option<Binder<'tcx, T>> {
|
||||
let bound_vars = self.1;
|
||||
self.0.map(|v| Binder(v, bound_vars))
|
||||
let Binder { value, bound_vars } = self;
|
||||
value.map(|value| Binder { value, bound_vars })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: IntoIterator> Binder<'tcx, T> {
|
||||
pub fn iter(self) -> impl Iterator<Item = ty::Binder<'tcx, T::Item>> {
|
||||
let bound_vars = self.1;
|
||||
self.0.into_iter().map(|v| Binder(v, bound_vars))
|
||||
let Binder { value, bound_vars } = self;
|
||||
value.into_iter().map(|value| Binder { value, bound_vars })
|
||||
}
|
||||
}
|
||||
|
||||
@ -1184,7 +1186,7 @@ impl<'tcx, T> IntoDiagnosticArg for Binder<'tcx, T>
|
||||
T: IntoDiagnosticArg,
|
||||
{
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
self.0.into_diagnostic_arg()
|
||||
self.value.into_diagnostic_arg()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -538,19 +538,21 @@ fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFl
|
||||
/// [`subst_identity`](EarlyBinder::subst_identity) or [`skip_binder`](EarlyBinder::skip_binder).
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
#[derive(Encodable, Decodable, HashStable)]
|
||||
pub struct EarlyBinder<T>(T);
|
||||
pub struct EarlyBinder<T> {
|
||||
value: T,
|
||||
}
|
||||
|
||||
/// For early binders, you should first call `subst` before using any visitors.
|
||||
impl<'tcx, T> !TypeFoldable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {}
|
||||
impl<'tcx, T> !TypeVisitable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {}
|
||||
|
||||
impl<T> EarlyBinder<T> {
|
||||
pub fn bind(inner: T) -> EarlyBinder<T> {
|
||||
EarlyBinder(inner)
|
||||
pub fn bind(value: T) -> EarlyBinder<T> {
|
||||
EarlyBinder { value }
|
||||
}
|
||||
|
||||
pub fn as_ref(&self) -> EarlyBinder<&T> {
|
||||
EarlyBinder(&self.0)
|
||||
EarlyBinder { value: &self.value }
|
||||
}
|
||||
|
||||
pub fn map_bound_ref<F, U>(&self, f: F) -> EarlyBinder<U>
|
||||
@ -564,20 +566,20 @@ pub fn map_bound<F, U>(self, f: F) -> EarlyBinder<U>
|
||||
where
|
||||
F: FnOnce(T) -> U,
|
||||
{
|
||||
let value = f(self.0);
|
||||
EarlyBinder(value)
|
||||
let value = f(self.value);
|
||||
EarlyBinder { value }
|
||||
}
|
||||
|
||||
pub fn try_map_bound<F, U, E>(self, f: F) -> Result<EarlyBinder<U>, E>
|
||||
where
|
||||
F: FnOnce(T) -> Result<U, E>,
|
||||
{
|
||||
let value = f(self.0)?;
|
||||
Ok(EarlyBinder(value))
|
||||
let value = f(self.value)?;
|
||||
Ok(EarlyBinder { value })
|
||||
}
|
||||
|
||||
pub fn rebind<U>(&self, value: U) -> EarlyBinder<U> {
|
||||
EarlyBinder(value)
|
||||
EarlyBinder { value }
|
||||
}
|
||||
|
||||
/// Skips the binder and returns the "bound" value.
|
||||
@ -592,19 +594,20 @@ pub fn rebind<U>(&self, value: U) -> EarlyBinder<U> {
|
||||
/// See also [`Binder::skip_binder`](super::Binder::skip_binder), which is
|
||||
/// the analogous operation on [`super::Binder`].
|
||||
pub fn skip_binder(self) -> T {
|
||||
self.0
|
||||
self.value
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> EarlyBinder<Option<T>> {
|
||||
pub fn transpose(self) -> Option<EarlyBinder<T>> {
|
||||
self.0.map(|v| EarlyBinder(v))
|
||||
self.value.map(|value| EarlyBinder { value })
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> EarlyBinder<(T, U)> {
|
||||
pub fn transpose_tuple2(self) -> (EarlyBinder<T>, EarlyBinder<U>) {
|
||||
(EarlyBinder(self.0.0), EarlyBinder(self.0.1))
|
||||
let EarlyBinder { value: (lhs, rhs) } = self;
|
||||
(EarlyBinder { value: lhs }, EarlyBinder { value: rhs })
|
||||
}
|
||||
}
|
||||
|
||||
@ -617,13 +620,13 @@ pub fn subst_iter(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
substs: &'s [GenericArg<'tcx>],
|
||||
) -> SubstIter<'s, 'tcx, I> {
|
||||
SubstIter { it: self.0.into_iter(), tcx, substs }
|
||||
SubstIter { it: self.value.into_iter(), tcx, substs }
|
||||
}
|
||||
|
||||
/// Similar to [`subst_identity`](EarlyBinder::subst_identity),
|
||||
/// but on an iterator of `TypeFoldable` values.
|
||||
pub fn subst_identity_iter(self) -> I::IntoIter {
|
||||
self.0.into_iter()
|
||||
self.value.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
@ -640,7 +643,7 @@ impl<'tcx, I: IntoIterator> Iterator for SubstIter<'_, 'tcx, I>
|
||||
type Item = I::Item;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
Some(EarlyBinder(self.it.next()?).subst(self.tcx, self.substs))
|
||||
Some(EarlyBinder { value: self.it.next()? }.subst(self.tcx, self.substs))
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
@ -654,7 +657,7 @@ impl<'tcx, I: IntoIterator> DoubleEndedIterator for SubstIter<'_, 'tcx, I>
|
||||
I::Item: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
Some(EarlyBinder(self.it.next_back()?).subst(self.tcx, self.substs))
|
||||
Some(EarlyBinder { value: self.it.next_back()? }.subst(self.tcx, self.substs))
|
||||
}
|
||||
}
|
||||
|
||||
@ -675,13 +678,13 @@ pub fn subst_iter_copied(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
substs: &'s [GenericArg<'tcx>],
|
||||
) -> SubstIterCopied<'s, 'tcx, I> {
|
||||
SubstIterCopied { it: self.0.into_iter(), tcx, substs }
|
||||
SubstIterCopied { it: self.value.into_iter(), tcx, substs }
|
||||
}
|
||||
|
||||
/// Similar to [`subst_identity`](EarlyBinder::subst_identity),
|
||||
/// but on an iterator of values that deref to a `TypeFoldable`.
|
||||
pub fn subst_identity_iter_copied(self) -> impl Iterator<Item = <I::Item as Deref>::Target> {
|
||||
self.0.into_iter().map(|v| *v)
|
||||
self.value.into_iter().map(|v| *v)
|
||||
}
|
||||
}
|
||||
|
||||
@ -699,7 +702,7 @@ impl<'tcx, I: IntoIterator> Iterator for SubstIterCopied<'_, 'tcx, I>
|
||||
type Item = <I::Item as Deref>::Target;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
Some(EarlyBinder(*self.it.next()?).subst(self.tcx, self.substs))
|
||||
self.it.next().map(|value| EarlyBinder { value: *value }.subst(self.tcx, self.substs))
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
@ -714,7 +717,7 @@ impl<'tcx, I: IntoIterator> DoubleEndedIterator for SubstIterCopied<'_, 'tcx, I>
|
||||
<I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
Some(EarlyBinder(*self.it.next_back()?).subst(self.tcx, self.substs))
|
||||
self.it.next_back().map(|value| EarlyBinder { value: *value }.subst(self.tcx, self.substs))
|
||||
}
|
||||
}
|
||||
|
||||
@ -732,7 +735,7 @@ pub struct EarlyBinderIter<T> {
|
||||
|
||||
impl<T: IntoIterator> EarlyBinder<T> {
|
||||
pub fn transpose_iter(self) -> EarlyBinderIter<T::IntoIter> {
|
||||
EarlyBinderIter { t: self.0.into_iter() }
|
||||
EarlyBinderIter { t: self.value.into_iter() }
|
||||
}
|
||||
}
|
||||
|
||||
@ -740,7 +743,7 @@ impl<T: Iterator> Iterator for EarlyBinderIter<T> {
|
||||
type Item = EarlyBinder<T::Item>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.t.next().map(|i| EarlyBinder(i))
|
||||
self.t.next().map(|value| EarlyBinder { value })
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
@ -751,7 +754,7 @@ fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> ty::EarlyBinder<T> {
|
||||
pub fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> T {
|
||||
let mut folder = SubstFolder { tcx, substs, binders_passed: 0 };
|
||||
self.0.fold_with(&mut folder)
|
||||
self.value.fold_with(&mut folder)
|
||||
}
|
||||
|
||||
/// Makes the identity substitution `T0 => T0, ..., TN => TN`.
|
||||
@ -763,12 +766,12 @@ pub fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> T {
|
||||
/// - Inside of the body of `foo`, we treat `T` as a placeholder by calling
|
||||
/// `subst_identity` to discharge the `EarlyBinder`.
|
||||
pub fn subst_identity(self) -> T {
|
||||
self.0
|
||||
self.value
|
||||
}
|
||||
|
||||
/// Returns the inner value, but only if it contains no bound vars.
|
||||
pub fn no_bound_vars(self) -> Option<T> {
|
||||
if !self.0.has_param() { Some(self.0) } else { None }
|
||||
if !self.value.has_param() { Some(self.value) } else { None }
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user