diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 0bc49a2901505..40909495c01da 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -602,7 +602,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { continue; } - let verify_kind_ty = verify.kind.to_ty(self.tcx()); + let verify_kind_ty = verify.kind.as_ty(); if self.bound_is_met(&verify.bound, var_data, verify_kind_ty, sub) { continue; } diff --git a/src/librustc/infer/outlives/obligations.rs b/src/librustc/infer/outlives/obligations.rs index 45e4a84589eb5..da5afaad0e7bb 100644 --- a/src/librustc/infer/outlives/obligations.rs +++ b/src/librustc/infer/outlives/obligations.rs @@ -321,7 +321,7 @@ where &mut self, origin: infer::SubregionOrigin<'tcx>, region: ty::Region<'tcx>, - param_ty: ty::ParamTy, + param_ty: ty::View<'tcx, ty::ParamTy>, ) { debug!( "param_ty_must_outlive(region={:?}, param_ty={:?}, origin={:?})", @@ -337,7 +337,7 @@ where &mut self, origin: infer::SubregionOrigin<'tcx>, region: ty::Region<'tcx>, - projection_ty: ty::ProjectionTy<'tcx>, + projection_ty: ty::View<'tcx, ty::ProjectionTy<'tcx>>, ) { debug!( "projection_must_outlive(region={:?}, projection_ty={:?}, origin={:?})", @@ -376,8 +376,8 @@ where // #55756) in cases where you have e.g., `>::Item: // 'a` in the environment but `trait Foo<'b> { type Item: 'b // }` in the trait definition. - approx_env_bounds.retain(|bound| match bound.0.kind { - ty::Projection(projection_ty) => self + approx_env_bounds.retain(|bound| match bound.0.into() { + ty::view::Projection(projection_ty) => self .verify_bound .projection_declared_bounds_from_trait(projection_ty) .all(|r| r != bound.1), diff --git a/src/librustc/infer/outlives/verify.rs b/src/librustc/infer/outlives/verify.rs index 8ee8482e79dbc..daa48b96ae856 100644 --- a/src/librustc/infer/outlives/verify.rs +++ b/src/librustc/infer/outlives/verify.rs @@ -2,7 +2,7 @@ use crate::infer::outlives::env::RegionBoundPairs; use crate::infer::{GenericKind, VerifyBound}; use crate::traits; use crate::ty::subst::{InternalSubsts, Subst}; -use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{self, Ty, TyCtxt, View}; use rustc_data_structures::captures::Captures; use rustc_hir::def_id::DefId; @@ -39,22 +39,20 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { } fn type_bound(&self, ty: Ty<'tcx>) -> VerifyBound<'tcx> { - match ty.kind { - ty::Param(p) => self.param_bound(p), - ty::Projection(data) => self.projection_bound(data), + match ty.into() { + ty::view::Param(p) => self.param_bound(p), + ty::view::Projection(data) => self.projection_bound(data), _ => self.recursive_type_bound(ty), } } - fn param_bound(&self, param_ty: ty::ParamTy) -> VerifyBound<'tcx> { + fn param_bound(&self, param_ty: View<'tcx, ty::ParamTy>) -> VerifyBound<'tcx> { debug!("param_bound(param_ty={:?})", param_ty); // Start with anything like `T: 'a` we can scrape from the // environment - let param_bounds = self - .declared_generic_bounds_from_env(GenericKind::Param(param_ty)) - .into_iter() - .map(|outlives| outlives.1); + let param_bounds = + self.declared_generic_bounds_from_env(param_ty).into_iter().map(|outlives| outlives.1); // Add in the default bound of fn body that applies to all in // scope type parameters: @@ -78,9 +76,9 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { /// this list. pub fn projection_approx_declared_bounds_from_env( &self, - projection_ty: ty::ProjectionTy<'tcx>, + projection_ty: ty::View<'tcx, ty::ProjectionTy<'tcx>>, ) -> Vec, ty::Region<'tcx>>> { - let projection_ty = GenericKind::Projection(projection_ty).to_ty(self.tcx); + let projection_ty = projection_ty.as_ty(); let erased_projection_ty = self.tcx.erase_regions(&projection_ty); self.declared_generic_bounds_from_env_with_compare_fn(|ty| { if let ty::Projection(..) = ty.kind { @@ -97,16 +95,18 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { /// exact match. pub fn projection_declared_bounds_from_trait( &self, - projection_ty: ty::ProjectionTy<'tcx>, + projection_ty: ty::View<'tcx, ty::ProjectionTy<'tcx>>, ) -> impl Iterator> + 'cx + Captures<'tcx> { self.declared_projection_bounds_from_trait(projection_ty) } - pub fn projection_bound(&self, projection_ty: ty::ProjectionTy<'tcx>) -> VerifyBound<'tcx> { + pub fn projection_bound( + &self, + projection_ty: ty::View<'tcx, ty::ProjectionTy<'tcx>>, + ) -> VerifyBound<'tcx> { debug!("projection_bound(projection_ty={:?})", projection_ty); - let projection_ty_as_ty = - self.tcx.mk_projection(projection_ty.item_def_id, projection_ty.substs); + let projection_ty_as_ty = projection_ty.as_ty(); // Search the env for where clauses like `P: 'a`. let env_bounds = self @@ -161,9 +161,9 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { /// bounds, but all the bounds it returns can be relied upon. fn declared_generic_bounds_from_env( &self, - generic: GenericKind<'tcx>, + generic: View<'tcx, ty::ParamTy>, ) -> Vec, ty::Region<'tcx>>> { - let generic_ty = generic.to_ty(self.tcx); + let generic_ty = generic.as_ty(); self.declared_generic_bounds_from_env_with_compare_fn(|ty| ty == generic_ty) } @@ -171,8 +171,6 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { &self, compare_ty: impl Fn(Ty<'tcx>) -> bool, ) -> Vec, ty::Region<'tcx>>> { - let tcx = self.tcx; - // To start, collect bounds from user environment. Note that // parameter environments are already elaborated, so we don't // have to worry about that. Comparing using `==` is a bit @@ -198,7 +196,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { "declared_generic_bounds_from_env_with_compare_fn: region_bound_pair = {:?}", (r, p) ); - let p_ty = p.to_ty(tcx); + let p_ty = p.as_ty(); compare_ty(p_ty).then_some(ty::OutlivesPredicate(p_ty, r)) }); @@ -227,7 +225,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { /// `region_bounds_declared_on_associated_item`. fn declared_projection_bounds_from_trait( &self, - projection_ty: ty::ProjectionTy<'tcx>, + projection_ty: ty::View<'tcx, ty::ProjectionTy<'tcx>>, ) -> impl Iterator> + 'cx + Captures<'tcx> { debug!("projection_bounds(projection_ty={:?})", projection_ty); let tcx = self.tcx; diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index f218bf1134f7f..8fc24bbcd95ef 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -184,8 +184,8 @@ pub struct Verify<'tcx> { #[derive(Copy, Clone, PartialEq, Eq, Hash, TypeFoldable)] pub enum GenericKind<'tcx> { - Param(ty::ParamTy), - Projection(ty::ProjectionTy<'tcx>), + Param(ty::View<'tcx, ty::ParamTy>), + Projection(ty::View<'tcx, ty::ProjectionTy<'tcx>>), } /// Describes the things that some `GenericKind` value `G` is known to @@ -875,10 +875,10 @@ impl<'tcx> fmt::Display for GenericKind<'tcx> { } impl<'tcx> GenericKind<'tcx> { - pub fn to_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { + pub fn as_ty(&self) -> Ty<'tcx> { match *self { - GenericKind::Param(ref p) => p.to_ty(tcx), - GenericKind::Projection(ref p) => tcx.mk_projection(p.item_def_id, p.substs), + GenericKind::Param(ref p) => p.as_ty(), + GenericKind::Projection(ref p) => p.as_ty(), } } } diff --git a/src/librustc/traits/query/outlives_bounds.rs b/src/librustc/traits/query/outlives_bounds.rs index 07e57e847b13d..b3f21491fdeb5 100644 --- a/src/librustc/traits/query/outlives_bounds.rs +++ b/src/librustc/traits/query/outlives_bounds.rs @@ -20,8 +20,8 @@ use std::mem; #[derive(Clone, Debug, TypeFoldable, Lift)] pub enum OutlivesBound<'tcx> { RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>), - RegionSubParam(ty::Region<'tcx>, ty::ParamTy), - RegionSubProjection(ty::Region<'tcx>, ty::ProjectionTy<'tcx>), + RegionSubParam(ty::Region<'tcx>, ty::View<'tcx, ty::ParamTy>), + RegionSubProjection(ty::Region<'tcx>, ty::View<'tcx, ty::ProjectionTy<'tcx>>), } impl<'a, 'tcx> HashStable> for OutlivesBound<'tcx> { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index d1e37a4ea1151..994926aec83d4 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -91,6 +91,8 @@ pub use self::trait_def::TraitDef; pub use self::query::queries; +pub use self::view::View; + pub mod adjustment; pub mod binding; pub mod cast; @@ -114,6 +116,7 @@ pub mod steal; pub mod subst; pub mod trait_def; pub mod util; +pub mod view; pub mod walk; mod context; diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs index b397a2c80d59b..51679ff1b19d1 100644 --- a/src/librustc/ty/outlives.rs +++ b/src/librustc/ty/outlives.rs @@ -8,7 +8,7 @@ use smallvec::SmallVec; #[derive(Debug)] pub enum Component<'tcx> { Region(ty::Region<'tcx>), - Param(ty::ParamTy), + Param(ty::View<'tcx, ty::ParamTy>), UnresolvedInferenceVariable(ty::InferTy), // Projections like `T::Foo` are tricky because a constraint like @@ -20,7 +20,7 @@ pub enum Component<'tcx> { // is not in a position to judge which is the best technique, so // we just product the projection as a component and leave it to // the consumer to decide (but see `EscapingProjection` below). - Projection(ty::ProjectionTy<'tcx>), + Projection(ty::View<'tcx, ty::ProjectionTy<'tcx>>), // In the case where a projection has escaping regions -- meaning // regions bound within the type itself -- we always use @@ -60,106 +60,106 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo // with `collect()` because of the need to sometimes skip subtrees // in the `subtys` iterator (e.g., when encountering a // projection). - match ty.kind { - ty::Closure(def_id, ref substs) => { - for upvar_ty in substs.as_closure().upvar_tys(def_id, tcx) { - compute_components(tcx, upvar_ty, out); - } + match ty.into() { + ty::view::Closure(def_id, ref substs) => { + for upvar_ty in substs.as_closure().upvar_tys(def_id, tcx) { + compute_components(tcx, upvar_ty, out); } + } - ty::Generator(def_id, ref substs, _) => { - // Same as the closure case - for upvar_ty in substs.as_generator().upvar_tys(def_id, tcx) { - compute_components(tcx, upvar_ty, out); - } - - // We ignore regions in the generator interior as we don't - // want these to affect region inference + ty::view::Generator(def_id, ref substs, _) => { + // Same as the closure case + for upvar_ty in substs.as_generator().upvar_tys(def_id, tcx) { + compute_components(tcx, upvar_ty, out); } - // All regions are bound inside a witness - ty::GeneratorWitness(..) => (), + // We ignore regions in the generator interior as we don't + // want these to affect region inference + } - // OutlivesTypeParameterEnv -- the actual checking that `X:'a` - // is implied by the environment is done in regionck. - ty::Param(p) => { - out.push(Component::Param(p)); - } + // All regions are bound inside a witness + ty::view::GeneratorWitness(..) => (), + + // OutlivesTypeParameterEnv -- the actual checking that `X:'a` + // is implied by the environment is done in regionck. + ty::view::Param(p) => { + out.push(Component::Param(p)); + } - // For projections, we prefer to generate an obligation like - // `>::Foo: 'a`, because this gives the - // regionck more ways to prove that it holds. However, - // regionck is not (at least currently) prepared to deal with - // higher-ranked regions that may appear in the - // trait-ref. Therefore, if we see any higher-ranke regions, - // we simply fallback to the most restrictive rule, which - // requires that `Pi: 'a` for all `i`. - ty::Projection(ref data) => { - if !data.has_escaping_bound_vars() { - // best case: no escaping regions, so push the - // projection and skip the subtree (thus generating no - // constraints for Pi). This defers the choice between - // the rules OutlivesProjectionEnv, - // OutlivesProjectionTraitDef, and - // OutlivesProjectionComponents to regionck. - out.push(Component::Projection(*data)); - } else { - // fallback case: hard code - // OutlivesProjectionComponents. Continue walking - // through and constrain Pi. - let subcomponents = capture_components(tcx, ty); - out.push(Component::EscapingProjection(subcomponents)); - } + // For projections, we prefer to generate an obligation like + // `>::Foo: 'a`, because this gives the + // regionck more ways to prove that it holds. However, + // regionck is not (at least currently) prepared to deal with + // higher-ranked regions that may appear in the + // trait-ref. Therefore, if we see any higher-ranke regions, + // we simply fallback to the most restrictive rule, which + // requires that `Pi: 'a` for all `i`. + ty::view::Projection(data) => { + if !data.has_escaping_bound_vars() { + // best case: no escaping regions, so push the + // projection and skip the subtree (thus generating no + // constraints for Pi). This defers the choice between + // the rules OutlivesProjectionEnv, + // OutlivesProjectionTraitDef, and + // OutlivesProjectionComponents to regionck. + out.push(Component::Projection(data)); + } else { + // fallback case: hard code + // OutlivesProjectionComponents. Continue walking + // through and constrain Pi. + let subcomponents = capture_components(tcx, ty); + out.push(Component::EscapingProjection(subcomponents)); } + } - ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), + ty::view::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), - // We assume that inference variables are fully resolved. - // So, if we encounter an inference variable, just record - // the unresolved variable as a component. - ty::Infer(infer_ty) => { - out.push(Component::UnresolvedInferenceVariable(infer_ty)); - } + // We assume that inference variables are fully resolved. + // So, if we encounter an inference variable, just record + // the unresolved variable as a component. + ty::view::Infer(infer_ty) => { + out.push(Component::UnresolvedInferenceVariable(infer_ty)); + } - // Most types do not introduce any region binders, nor - // involve any other subtle cases, and so the WF relation - // simply constraints any regions referenced directly by - // the type and then visits the types that are lexically - // contained within. (The comments refer to relevant rules - // from RFC1214.) - ty::Bool | // OutlivesScalar - ty::Char | // OutlivesScalar - ty::Int(..) | // OutlivesScalar - ty::Uint(..) | // OutlivesScalar - ty::Float(..) | // OutlivesScalar - ty::Never | // ... - ty::Adt(..) | // OutlivesNominalType - ty::Opaque(..) | // OutlivesNominalType (ish) - ty::Foreign(..) | // OutlivesNominalType - ty::Str | // OutlivesScalar (ish) - ty::Array(..) | // ... - ty::Slice(..) | // ... - ty::RawPtr(..) | // ... - ty::Ref(..) | // OutlivesReference - ty::Tuple(..) | // ... - ty::FnDef(..) | // OutlivesFunction (*) - ty::FnPtr(_) | // OutlivesFunction (*) - ty::Dynamic(..) | // OutlivesObject, OutlivesFragment (*) - ty::Placeholder(..) | - ty::Bound(..) | - ty::Error => { - // (*) Bare functions and traits are both binders. In the - // RFC, this means we would add the bound regions to the - // "bound regions list". In our representation, no such - // list is maintained explicitly, because bound regions - // themselves can be readily identified. - - push_region_constraints(ty, out); - for subty in ty.walk_shallow() { - compute_components(tcx, subty, out); - } + // Most types do not introduce any region binders, nor + // involve any other subtle cases, and so the WF relation + // simply constraints any regions referenced directly by + // the type and then visits the types that are lexically + // contained within. (The comments refer to relevant rules + // from RFC1214.) + ty::view::Bool | // OutlivesScalar + ty::view::Char | // OutlivesScalar + ty::view::Int(..) | // OutlivesScalar + ty::view::Uint(..) | // OutlivesScalar + ty::view::Float(..) | // OutlivesScalar + ty::view::Never | // ... + ty::view::Adt(..) | // OutlivesNominalType + ty::view::Opaque(..) | // OutlivesNominalType (ish) + ty::view::Foreign(..) | // OutlivesNominalType + ty::view::Str | // OutlivesScalar (ish) + ty::view::Array(..) | // ... + ty::view::Slice(..) | // ... + ty::view::RawPtr(..) | // ... + ty::view::Ref(..) | // OutlivesReference + ty::view::Tuple(..) | // ... + ty::view::FnDef(..) | // OutlivesFunction (*) + ty::view::FnPtr(_) | // OutlivesFunction (*) + ty::view::Dynamic(..) | // OutlivesObject, OutlivesFragment (*) + ty::view::Placeholder(..) | + ty::view::Bound(..) | + ty::view::Error => { + // (*) Bare functions and traits are both binders. In the + // RFC, this means we would add the bound regions to the + // "bound regions list". In our representation, no such + // list is maintained explicitly, because bound regions + // themselves can be readily identified. + + push_region_constraints(ty, out); + for subty in ty.walk_shallow() { + compute_components(tcx, subty, out); } } + } } fn capture_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Vec> { diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 5e24c843025bf..89632b20421f2 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -13,6 +13,7 @@ use rustc_index::vec::{Idx, IndexVec}; use smallvec::SmallVec; use std::fmt; +use std::marker::PhantomData; use std::rc::Rc; use std::sync::Arc; @@ -389,6 +390,13 @@ impl<'tcx, I: Idx, T: Lift<'tcx>> Lift<'tcx> for IndexVec { } } +impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for PhantomData { + type Lifted = PhantomData; + fn lift_to_tcx(&self, _tcx: TyCtxt<'tcx>) -> Option { + Some(PhantomData) + } +} + impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> { type Lifted = ty::TraitRef<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { @@ -1067,3 +1075,13 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { false } } + +impl<'tcx, T> TypeFoldable<'tcx> for PhantomData { + fn super_fold_with>(&self, _folder: &mut F) -> Self { + *self + } + + fn super_visit_with>(&self, _visitor: &mut V) -> bool { + false + } +} diff --git a/src/librustc/ty/view.rs b/src/librustc/ty/view.rs new file mode 100644 index 0000000000000..e709c41f97930 --- /dev/null +++ b/src/librustc/ty/view.rs @@ -0,0 +1,164 @@ +use std::{fmt, marker::PhantomData}; + +use syntax::ast; + +use crate::ty::{ + self, AdtDef, Binder, BoundTy, ExistentialPredicate, InferTy, List, ParamTy, PolyFnSig, + ProjectionTy, Region, SubstsRef, Ty, TypeAndMut, +}; +use rustc_hir::{self as hir, def_id::DefId}; + +pub use self::ViewKind::*; + +/// `View<'tcx, T>` contains a value of `T` but stores the `Ty<'tcx>` ptr that contains the `T` +/// This allows for cheap access to the `Ty<'tcx>` without needing to ask the type interner or +/// losing the `T` type. +#[derive(TypeFoldable, Eq, PartialEq, Hash, Lift)] +pub struct View<'tcx, T> { + ty: Ty<'tcx>, + _marker: PhantomData, +} + +impl Copy for View<'_, T> {} + +impl Clone for View<'_, T> { + fn clone(&self) -> Self { + View { ty: self.ty, _marker: PhantomData } + } +} + +impl<'tcx, T> fmt::Debug for View<'tcx, T> +where + T: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.ty.fmt(f) + } +} + +impl<'tcx, T> fmt::Display for View<'tcx, T> +where + T: fmt::Display + TyDeref<'tcx>, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + (**self).fmt(f) + } +} +impl<'tcx, T> std::ops::Deref for View<'tcx, T> +where + T: TyDeref<'tcx>, +{ + type Target = T; + fn deref(&self) -> &Self::Target { + match T::ty_deref(self.ty) { + Some(t) => t, + // SAFETY verified by `View::new` + None => unsafe { std::hint::unreachable_unchecked() }, + } + } +} + +impl<'tcx, T> View<'tcx, T> +where + T: TyDeref<'tcx>, +{ + pub fn new(ty: Ty<'tcx>) -> Option { + T::ty_deref(ty)?; + Some(View { ty, _marker: PhantomData }) + } +} + +impl<'tcx, T> View<'tcx, T> { + pub fn as_ty(&self) -> Ty<'tcx> { + self.ty + } +} + +/// SAFETY If `Some` is returned for `ty` then `Some` must always be returned for any subsequent +/// call with the same `Ty` value +pub unsafe trait TyDeref<'tcx>: Sized + 'tcx { + fn ty_deref(ty: Ty<'tcx>) -> Option<&'tcx Self>; +} + +macro_rules! impl_ty_deref { + ($ty: ty, $variant: ident) => { + unsafe impl<'tcx> TyDeref<'tcx> for $ty { + fn ty_deref(ty: Ty<'tcx>) -> Option<&'tcx Self> { + match &ty.kind { + ty::$variant(p) => Some(p), + _ => None, + } + } + } + }; +} + +impl_ty_deref! { ty::ParamTy, Param } +impl_ty_deref! { ty::ProjectionTy<'tcx>, Projection } + +/// Mirror of `TyKind`, but with `View` fields where there is need for it +pub enum ViewKind<'tcx> { + Bool, + Char, + Int(ast::IntTy), + Uint(ast::UintTy), + Float(ast::FloatTy), + Adt(&'tcx AdtDef, SubstsRef<'tcx>), + Foreign(DefId), + Str, + Array(Ty<'tcx>, &'tcx ty::Const<'tcx>), + Slice(Ty<'tcx>), + RawPtr(TypeAndMut<'tcx>), + Ref(Region<'tcx>, Ty<'tcx>, hir::Mutability), + FnDef(DefId, SubstsRef<'tcx>), + FnPtr(PolyFnSig<'tcx>), + Dynamic(Binder<&'tcx List>>, ty::Region<'tcx>), + Closure(DefId, SubstsRef<'tcx>), + Generator(DefId, SubstsRef<'tcx>, hir::Movability), + GeneratorWitness(Binder<&'tcx List>>), + Never, + Tuple(SubstsRef<'tcx>), + Projection(View<'tcx, ProjectionTy<'tcx>>), + UnnormalizedProjection(ProjectionTy<'tcx>), + Opaque(DefId, SubstsRef<'tcx>), + Param(View<'tcx, ParamTy>), + Bound(ty::DebruijnIndex, BoundTy), + Placeholder(ty::PlaceholderType), + Infer(InferTy), + Error, +} + +impl<'tcx> From> for ViewKind<'tcx> { + fn from(ty: Ty<'tcx>) -> Self { + match ty.kind { + ty::RawPtr(tm) => Self::RawPtr(tm), + ty::Array(typ, sz) => Self::Array(typ, sz), + ty::Slice(typ) => Self::Slice(typ), + ty::Adt(tid, substs) => Self::Adt(tid, substs), + ty::Dynamic(trait_ty, region) => Self::Dynamic(trait_ty, region), + ty::Tuple(ts) => Self::Tuple(ts), + ty::FnDef(def_id, substs) => Self::FnDef(def_id, substs), + ty::FnPtr(f) => Self::FnPtr(f), + ty::Ref(r, ty, mutbl) => Self::Ref(r, ty, mutbl), + ty::Generator(did, substs, movability) => Self::Generator(did, substs, movability), + ty::GeneratorWitness(types) => Self::GeneratorWitness(types), + ty::Closure(did, substs) => Self::Closure(did, substs), + ty::Projection(_) => Self::Projection(View::new(ty).unwrap()), + ty::UnnormalizedProjection(data) => Self::UnnormalizedProjection(data), + ty::Opaque(did, substs) => Self::Opaque(did, substs), + ty::Bool => Self::Bool, + ty::Char => Self::Char, + ty::Str => Self::Str, + ty::Int(i) => Self::Int(i), + ty::Uint(i) => Self::Uint(i), + ty::Float(f) => Self::Float(f), + ty::Error => Self::Error, + ty::Infer(i) => Self::Infer(i), + ty::Param(_) => Self::Param(View::new(ty).unwrap()), + ty::Bound(b, c) => Self::Bound(b, c), + ty::Placeholder(p) => Self::Placeholder(p), + ty::Never => Self::Never, + ty::Foreign(f) => Self::Foreign(f), + } + } +} diff --git a/src/librustc_data_structures/captures.rs b/src/librustc_data_structures/captures.rs index 26b90ebfd5f11..1e90aa6945b2d 100644 --- a/src/librustc_data_structures/captures.rs +++ b/src/librustc_data_structures/captures.rs @@ -7,4 +7,4 @@ #[allow(unused_lifetimes)] pub trait Captures<'a> {} -impl<'a, T: ?Sized> Captures<'a> for T {} +impl Captures<'_> for T {} diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs index 7d2384f8a7de7..1d3307fe39d11 100644 --- a/src/librustc_mir/borrow_check/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/region_infer/mod.rs @@ -815,7 +815,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { for type_test in &self.type_tests { debug!("check_type_test: {:?}", type_test); - let generic_ty = type_test.generic_kind.to_ty(tcx); + let generic_ty = type_test.generic_kind.as_ty(); if self.eval_verify_bound( tcx, body, @@ -910,7 +910,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let TypeTest { generic_kind, lower_bound, locations, verify_bound: _ } = type_test; - let generic_ty = generic_kind.to_ty(tcx); + let generic_ty = generic_kind.as_ty(); let subject = match self.try_promote_type_test_subject(infcx, generic_ty) { Some(s) => s, None => return false,