summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/ty/subst.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src/ty/subst.rs')
-rw-r--r--compiler/rustc_middle/src/ty/subst.rs61
1 files changed, 38 insertions, 23 deletions
diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs
index 43f95635a..4d5f5b865 100644
--- a/compiler/rustc_middle/src/ty/subst.rs
+++ b/compiler/rustc_middle/src/ty/subst.rs
@@ -11,6 +11,7 @@ use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
use rustc_hir::def_id::DefId;
use rustc_macros::HashStable;
use rustc_serialize::{self, Decodable, Encodable};
+use rustc_span::sym;
use rustc_type_ir::WithCachedTypeInfo;
use smallvec::SmallVec;
@@ -451,6 +452,10 @@ impl<'tcx> InternalSubsts<'tcx> {
pub fn truncate_to(&self, tcx: TyCtxt<'tcx>, generics: &ty::Generics) -> SubstsRef<'tcx> {
tcx.mk_substs_from_iter(self.iter().take(generics.count()))
}
+
+ pub fn host_effect_param(&'tcx self) -> Option<ty::Const<'tcx>> {
+ self.consts().rfind(|x| matches!(x.kind(), ty::ConstKind::Param(p) if p.name == sym::host))
+ }
}
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for SubstsRef<'tcx> {
@@ -538,15 +543,21 @@ impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>> for &'tcx
/// [`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>(pub 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(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>
@@ -560,20 +571,20 @@ impl<T> EarlyBinder<T> {
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.
@@ -582,22 +593,26 @@ impl<T> EarlyBinder<T> {
/// arguments of an `FnSig`). Otherwise, consider using
/// [`subst_identity`](EarlyBinder::subst_identity).
///
+ /// To skip the binder on `x: &EarlyBinder<T>` to obtain `&T`, leverage
+ /// [`EarlyBinder::as_ref`](EarlyBinder::as_ref): `x.as_ref().skip_binder()`.
+ ///
/// 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 })
}
}
@@ -610,13 +625,13 @@ where
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()
}
}
@@ -633,7 +648,7 @@ where
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>) {
@@ -647,7 +662,7 @@ where
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))
}
}
@@ -668,13 +683,13 @@ where
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)
}
}
@@ -692,7 +707,7 @@ where
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>) {
@@ -707,7 +722,7 @@ where
<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))
}
}
@@ -725,7 +740,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() }
}
}
@@ -733,7 +748,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>) {
@@ -744,7 +759,7 @@ impl<T: Iterator> Iterator for EarlyBinderIter<T> {
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`.
@@ -756,12 +771,12 @@ impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> ty::EarlyBinder<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 }
}
}