use crate::ty::fold::ValidateBoundVars;
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
use crate::ty::InferTy::{self, *};
-use crate::ty::{self, AdtDef, DefIdTree, Discr, Term, Ty, TyCtxt, TypeFlags, TypeFoldable};
+use crate::ty::{
+ self, AdtDef, DefIdTree, Discr, Term, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitor,
+};
use crate::ty::{DelaySpanBugEmitted, List, ParamEnv};
use polonius_engine::Atom;
use rustc_data_structures::captures::Captures;
use std::cmp::Ordering;
use std::fmt;
use std::marker::PhantomData;
-use std::ops::{Deref, Range};
+use std::ops::{ControlFlow, Deref, Range};
use ty::util::IntTypeExt;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
Never,
/// A tuple type. For example, `(i32, bool)`.
- /// Use `Ty::tuple_fields` to iterate over the field types.
- Tuple(SubstsRef<'tcx>),
+ Tuple(&'tcx List<Ty<'tcx>>),
/// The projection of an associated type. For example,
/// `<T as Trait<..>>::N`.
/// Use this rather than `TyKind`, whenever possible.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
-#[cfg_attr(not(bootstrap), rustc_pass_by_value)]
+#[rustc_pass_by_value]
pub struct Region<'tcx>(pub Interned<'tcx, RegionKind>);
impl<'tcx> Deref for Region<'tcx> {
!matches!(self.kind(), Param(_) | Infer(_) | Error(_))
}
+ /// Checks whether a type recursively contains another type
+ ///
+ /// Example: `Option<()>` contains `()`
+ pub fn contains(self, other: Ty<'tcx>) -> bool {
+ struct ContainsTyVisitor<'tcx>(Ty<'tcx>);
+
+ impl<'tcx> TypeVisitor<'tcx> for ContainsTyVisitor<'tcx> {
+ type BreakTy = ();
+
+ fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
+ if self.0 == t { ControlFlow::BREAK } else { t.super_visit_with(self) }
+ }
+ }
+
+ let cf = self.visit_with(&mut ContainsTyVisitor(other));
+ cf.is_break()
+ }
+
/// Returns the type and mutability of `*ty`.
///
/// The parameter `explicit` indicates if this is an *explicit* dereference.
/// Iterates over tuple fields.
/// Panics when called on anything but a tuple.
- pub fn tuple_fields(self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> {
- match self.kind() {
- Tuple(substs) => substs.iter().map(|field| field.expect_ty()),
- _ => bug!("tuple_fields called on non-tuple"),
- }
- }
-
- /// Get the `i`-th element of a tuple.
- /// Panics when called on anything but a tuple.
- pub fn tuple_element_ty(self, i: usize) -> Option<Ty<'tcx>> {
+ pub fn tuple_fields(self) -> &'tcx List<Ty<'tcx>> {
match self.kind() {
- Tuple(substs) => substs.iter().nth(i).map(|field| field.expect_ty()),
+ Tuple(substs) => substs,
_ => bug!("tuple_fields called on non-tuple"),
}
}
ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => false,
- ty::Tuple(tys) => tys.iter().all(|ty| ty.expect_ty().is_trivially_sized(tcx)),
+ ty::Tuple(tys) => tys.iter().all(|ty| ty.is_trivially_sized(tcx)),
ty::Adt(def, _substs) => def.sized_constraint(tcx).is_empty(),