]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_middle/src/ty/sty.rs
Switch bootstrap cfgs
[rust.git] / compiler / rustc_middle / src / ty / sty.rs
index 9835211a74865f6733e63645f9c28c6335cc476e..a1e906140e0e8211a8f5620f9b05029e1523d0d4 100644 (file)
@@ -8,7 +8,9 @@
 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;
@@ -24,7 +26,7 @@
 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)]
@@ -198,8 +200,7 @@ pub enum TyKind<'tcx> {
     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`.
@@ -1395,7 +1396,7 @@ pub fn for_def(def: &ty::GenericParamDef) -> ParamConst {
 
 /// 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> {
@@ -2072,6 +2073,24 @@ pub fn has_concrete_skeleton(self) -> bool {
         !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.
@@ -2135,18 +2154,9 @@ pub fn ty_adt_def(self) -> Option<&'tcx AdtDef> {
 
     /// 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"),
         }
     }
@@ -2347,7 +2357,7 @@ pub fn is_trivially_sized(self, tcx: TyCtxt<'tcx>) -> bool {
 
             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(),