Error(DelaySpanBugEmitted),
}
+impl TyKind<'tcx> {
+ #[inline]
+ pub fn is_primitive(&self) -> bool {
+ match self {
+ Bool | Char | Int(_) | Uint(_) | Float(_) => true,
+ _ => false,
+ }
+ }
+}
+
/// A type that is not publicly constructable. This prevents people from making `TyKind::Error`
/// except through `tcx.err*()`.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
/// Struct returned by `split()`. Note that these are subslices of the
/// parent slice and not canonical substs themselves.
struct SplitClosureSubsts<'tcx> {
+ parent: &'tcx [GenericArg<'tcx>],
closure_kind_ty: GenericArg<'tcx>,
closure_sig_as_fn_ptr_ty: GenericArg<'tcx>,
tupled_upvars_ty: GenericArg<'tcx>,
/// ordering.
fn split(self) -> SplitClosureSubsts<'tcx> {
match self.substs[..] {
- [.., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => {
- SplitClosureSubsts { closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty }
+ [ref parent @ .., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => {
+ SplitClosureSubsts {
+ parent,
+ closure_kind_ty,
+ closure_sig_as_fn_ptr_ty,
+ tupled_upvars_ty,
+ }
}
_ => bug!("closure substs missing synthetics"),
}
self.substs.len() >= 3 && matches!(self.split().tupled_upvars_ty.expect_ty().kind, Tuple(_))
}
+ /// Returns the substitutions of the closure's parent.
+ pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] {
+ self.split().parent
+ }
+
#[inline]
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
- self.split().tupled_upvars_ty.expect_ty().tuple_fields()
+ self.tupled_upvars_ty().tuple_fields()
+ }
+
+ /// Returns the tuple type representing the upvars for this closure.
+ #[inline]
+ pub fn tupled_upvars_ty(self) -> Ty<'tcx> {
+ self.split().tupled_upvars_ty.expect_ty()
}
/// Returns the closure kind for this closure; may return a type
}
struct SplitGeneratorSubsts<'tcx> {
+ parent: &'tcx [GenericArg<'tcx>],
resume_ty: GenericArg<'tcx>,
yield_ty: GenericArg<'tcx>,
return_ty: GenericArg<'tcx>,
impl<'tcx> GeneratorSubsts<'tcx> {
fn split(self) -> SplitGeneratorSubsts<'tcx> {
match self.substs[..] {
- [.., resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty] => {
- SplitGeneratorSubsts { resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty }
+ [ref parent @ .., resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty] => {
+ SplitGeneratorSubsts {
+ parent,
+ resume_ty,
+ yield_ty,
+ return_ty,
+ witness,
+ tupled_upvars_ty,
+ }
}
_ => bug!("generator substs missing synthetics"),
}
self.substs.len() >= 5 && matches!(self.split().tupled_upvars_ty.expect_ty().kind, Tuple(_))
}
+ /// Returns the substitutions of the generator's parent.
+ pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] {
+ self.split().parent
+ }
+
/// This describes the types that can be contained in a generator.
/// It will be a type variable initially and unified in the last stages of typeck of a body.
/// It contains a tuple of all the types that could end up on a generator frame.
#[inline]
pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
- self.split().tupled_upvars_ty.expect_ty().tuple_fields()
+ self.tupled_upvars_ty().tuple_fields()
+ }
+
+ /// Returns the tuple type representing the upvars for this generator.
+ #[inline]
+ pub fn tupled_upvars_ty(self) -> Ty<'tcx> {
+ self.split().tupled_upvars_ty.expect_ty()
}
/// Returns the type representing the resume type of the generator.
Binder(tr).with_self_ty(tcx, self_ty).without_const().to_predicate(tcx)
}
ExistentialPredicate::Projection(p) => {
- ty::PredicateKind::Projection(Binder(p.with_self_ty(tcx, self_ty)))
- .to_predicate(tcx)
+ Binder(p.with_self_ty(tcx, self_ty)).to_predicate(tcx)
}
ExistentialPredicate::AutoTrait(did) => {
let trait_ref =
Binder(value)
}
+ /// Wraps `value` in a binder without actually binding any currently
+ /// unbound variables.
+ ///
+ /// Note that this will shift all debrujin indices of escaping bound variables
+ /// by 1 to avoid accidential captures.
+ pub fn wrap_nonbinding(tcx: TyCtxt<'tcx>, value: T) -> Binder<T>
+ where
+ T: TypeFoldable<'tcx>,
+ {
+ if value.has_escaping_bound_vars() {
+ Binder::bind(super::fold::shift_vars(tcx, &value, 1))
+ } else {
+ Binder::dummy(value)
+ }
+ }
+
/// Skips the binder and returns the "bound" value. This is a
/// risky thing to do because it's easy to get confused about
/// De Bruijn indices and the like. It is usually better to
}
}
+impl<T> Binder<Option<T>> {
+ pub fn transpose(self) -> Option<Binder<T>> {
+ match self.0 {
+ Some(v) => Some(Binder(v)),
+ None => None,
+ }
+ }
+}
+
/// Represents the projection of an associated type. In explicit UFCS
/// form this would be written `<T as Trait<..>>::N`.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
#[inline]
pub fn is_primitive(&self) -> bool {
- match self.kind {
- Bool | Char | Int(_) | Uint(_) | Float(_) => true,
- _ => false,
- }
+ self.kind.is_primitive()
}
#[inline]