X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_middle%2Fsrc%2Fty%2Fsty.rs;h=a1e906140e0e8211a8f5620f9b05029e1523d0d4;hb=22c3a71de1f798822594498559622407ed882d88;hp=9835211a74865f6733e63645f9c28c6335cc476e;hpb=847ac55bec6e7e7d1fc82c89a05b518e99ddd9cb;p=rust.git diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 9835211a748..a1e906140e0 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -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>), /// The projection of an associated type. For example, /// `>::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 { + 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> { - 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> { + pub fn tuple_fields(self) -> &'tcx List> { 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(),