diff options
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/infer/canonical.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/tcx.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/query/on_disk_cache.rs | 42 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/codec.rs | 58 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 23 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/generic_args.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/predicate.rs | 186 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/print/pretty.rs | 27 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/region.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/structural_impls.rs | 32 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/sty.rs | 296 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/visit.rs | 98 |
12 files changed, 138 insertions, 642 deletions
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 49bf03e9c75..dba71d88f40 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -32,7 +32,7 @@ use std::collections::hash_map::Entry; use crate::infer::MemberConstraint; use crate::mir::ConstraintCategory; use crate::ty::GenericArg; -use crate::ty::{self, List, Region, Ty, TyCtxt, TypeFlags, TypeVisitableExt}; +use crate::ty::{self, List, Ty, TyCtxt, TypeFlags, TypeVisitableExt}; pub type Canonical<'tcx, V> = ir::Canonical<TyCtxt<'tcx>, V>; pub type CanonicalVarInfo<'tcx> = ir::CanonicalVarInfo<TyCtxt<'tcx>>; @@ -141,7 +141,7 @@ impl<'tcx, R> QueryResponse<'tcx, R> { } pub type QueryOutlivesConstraint<'tcx> = - (ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>, ConstraintCategory<'tcx>); + (ty::OutlivesPredicate<'tcx, GenericArg<'tcx>>, ConstraintCategory<'tcx>); TrivialTypeTraversalImpls! { crate::infer::canonical::Certainty, diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index e1ae2e08666..c421c937dc3 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -295,7 +295,7 @@ impl BorrowKind { } impl BinOp { - pub fn to_hir_binop(self) -> hir::BinOpKind { + pub(crate) fn to_hir_binop(self) -> hir::BinOpKind { match self { BinOp::Add => hir::BinOpKind::Add, BinOp::Sub => hir::BinOpKind::Sub, diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs index 2dcb58729ff..941911c2230 100644 --- a/compiler/rustc_middle/src/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/query/on_disk_cache.rs @@ -154,24 +154,25 @@ impl EncodedSourceFileId { impl<'sess> OnDiskCache<'sess> { /// Creates a new `OnDiskCache` instance from the serialized data in `data`. - pub fn new(sess: &'sess Session, data: Mmap, start_pos: usize) -> Self { - debug_assert!(sess.opts.incremental.is_some()); - - // Wrap in a scope so we can borrow `data`. - let footer: Footer = { - let mut decoder = MemDecoder::new(&data, start_pos); - - // Decode the *position* of the footer, which can be found in the - // last 8 bytes of the file. - let footer_pos = decoder - .with_position(decoder.len() - IntEncodedWithFixedSize::ENCODED_SIZE, |decoder| { - IntEncodedWithFixedSize::decode(decoder).0 as usize - }); - // Decode the file footer, which contains all the lookup tables, etc. - decoder.with_position(footer_pos, |decoder| decode_tagged(decoder, TAG_FILE_FOOTER)) - }; + /// + /// The serialized cache has some basic integrity checks, if those checks indicate that the + /// on-disk data is corrupt, an error is returned. + pub fn new(sess: &'sess Session, data: Mmap, start_pos: usize) -> Result<Self, ()> { + assert!(sess.opts.incremental.is_some()); + + let mut decoder = MemDecoder::new(&data, start_pos)?; + + // Decode the *position* of the footer, which can be found in the + // last 8 bytes of the file. + let footer_pos = decoder + .with_position(decoder.len() - IntEncodedWithFixedSize::ENCODED_SIZE, |decoder| { + IntEncodedWithFixedSize::decode(decoder).0 as usize + }); + // Decode the file footer, which contains all the lookup tables, etc. + let footer: Footer = + decoder.with_position(footer_pos, |decoder| decode_tagged(decoder, TAG_FILE_FOOTER)); - Self { + Ok(Self { serialized_data: RwLock::new(Some(data)), file_index_to_stable_id: footer.file_index_to_stable_id, file_index_to_file: Default::default(), @@ -184,7 +185,7 @@ impl<'sess> OnDiskCache<'sess> { expn_data: footer.expn_data, foreign_expn_data: footer.foreign_expn_data, hygiene_context: Default::default(), - } + }) } pub fn new_empty(source_map: &'sess SourceMap) -> Self { @@ -437,7 +438,8 @@ impl<'sess> OnDiskCache<'sess> { let serialized_data = self.serialized_data.read(); let mut decoder = CacheDecoder { tcx, - opaque: MemDecoder::new(serialized_data.as_deref().unwrap_or(&[]), pos.to_usize()), + opaque: MemDecoder::new(serialized_data.as_deref().unwrap_or(&[]), pos.to_usize()) + .unwrap(), source_map: self.source_map, file_index_to_file: &self.file_index_to_file, file_index_to_stable_id: &self.file_index_to_stable_id, @@ -558,7 +560,7 @@ impl<'a, 'tcx> TyDecoder for CacheDecoder<'a, 'tcx> { { debug_assert!(pos < self.opaque.len()); - let new_opaque = MemDecoder::new(self.opaque.data(), pos); + let new_opaque = self.opaque.split_at(pos); let old_opaque = mem::replace(&mut self.opaque, new_opaque); let r = f(self); self.opaque = old_opaque; diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index c0effe9804c..07652b47929 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -115,18 +115,11 @@ impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for Ty<'tcx> { } } -impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> - for ty::Binder<'tcx, ty::PredicateKind<'tcx>> -{ - fn encode(&self, e: &mut E) { - self.bound_vars().encode(e); - encode_with_shorthand(e, &self.skip_binder(), TyEncoder::predicate_shorthands); - } -} - impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ty::Predicate<'tcx> { fn encode(&self, e: &mut E) { - self.kind().encode(e); + let kind = self.kind(); + kind.bound_vars().encode(e); + encode_with_shorthand(e, &kind.skip_binder(), TyEncoder::predicate_shorthands); } } @@ -233,13 +226,11 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for Ty<'tcx> { } } -impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> - for ty::Binder<'tcx, ty::PredicateKind<'tcx>> -{ - fn decode(decoder: &mut D) -> ty::Binder<'tcx, ty::PredicateKind<'tcx>> { +impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Predicate<'tcx> { + fn decode(decoder: &mut D) -> ty::Predicate<'tcx> { let bound_vars = Decodable::decode(decoder); // Handle shorthands first, if we have a usize > 0x80. - ty::Binder::bind_with_vars( + let predicate_kind = ty::Binder::bind_with_vars( if decoder.positioned_at_shorthand() { let pos = decoder.read_usize(); assert!(pos >= SHORTHAND_OFFSET); @@ -250,13 +241,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> <ty::PredicateKind<'tcx> as Decodable<D>>::decode(decoder) }, bound_vars, - ) - } -} - -impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Predicate<'tcx> { - fn decode(decoder: &mut D) -> ty::Predicate<'tcx> { - let predicate_kind = Decodable::decode(decoder); + ); decoder.interner().mk_predicate(predicate_kind) } } @@ -599,32 +584,3 @@ macro_rules! implement_ty_decoder { } } } - -macro_rules! impl_binder_encode_decode { - ($($t:ty),+ $(,)?) => { - $( - impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ty::Binder<'tcx, $t> { - fn encode(&self, e: &mut E) { - self.bound_vars().encode(e); - self.as_ref().skip_binder().encode(e); - } - } - impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Binder<'tcx, $t> { - fn decode(decoder: &mut D) -> Self { - let bound_vars = Decodable::decode(decoder); - ty::Binder::bind_with_vars(Decodable::decode(decoder), bound_vars) - } - } - )* - } -} - -impl_binder_encode_decode! { - &'tcx ty::List<Ty<'tcx>>, - ty::FnSig<'tcx>, - ty::Predicate<'tcx>, - ty::TraitPredicate<'tcx>, - ty::ExistentialPredicate<'tcx>, - ty::TraitRef<'tcx>, - ty::ExistentialTraitRef<'tcx>, -} diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 8185c99c2fd..896114e2483 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -31,8 +31,7 @@ use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, ConstData, GenericParamDefKind, ImplPolarity, List, ListWithCachedTypeInfo, ParamConst, ParamTy, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicatePolarity, - Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, TypeVisitable, - Visibility, + Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, Visibility, }; use crate::ty::{GenericArg, GenericArgs, GenericArgsRef}; use rustc_ast::{self as ast, attr}; @@ -96,9 +95,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type GenericArg = ty::GenericArg<'tcx>; type Term = ty::Term<'tcx>; - type Binder<T: TypeVisitable<TyCtxt<'tcx>>> = Binder<'tcx, T>; - type BoundVars = &'tcx List<ty::BoundVariableKind>; - type BoundVar = ty::BoundVariableKind; + type BoundVarKinds = &'tcx List<ty::BoundVariableKind>; + type BoundVarKind = ty::BoundVariableKind; type CanonicalVars = CanonicalVarInfos<'tcx>; type PredefinedOpaques = solve::PredefinedOpaques<'tcx>; @@ -123,7 +121,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type Abi = abi::Abi; type Const = ty::Const<'tcx>; - type AliasConst = ty::UnevaluatedConst<'tcx>; type PlaceholderConst = ty::PlaceholderConst; type ParamConst = ty::ParamConst; type BoundConst = ty::BoundVar; @@ -138,15 +135,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type ParamEnv = ty::ParamEnv<'tcx>; type Predicate = Predicate<'tcx>; - type TraitPredicate = ty::TraitPredicate<'tcx>; - type RegionOutlivesPredicate = ty::RegionOutlivesPredicate<'tcx>; - type TypeOutlivesPredicate = ty::TypeOutlivesPredicate<'tcx>; - type ProjectionPredicate = ty::ProjectionPredicate<'tcx>; - type NormalizesTo = ty::NormalizesTo<'tcx>; - type SubtypePredicate = ty::SubtypePredicate<'tcx>; - - type CoercePredicate = ty::CoercePredicate<'tcx>; - type ClosureKind = ty::ClosureKind; + type Clause = Clause<'tcx>; type Clauses = ty::Clauses<'tcx>; @@ -245,6 +234,10 @@ impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for abi::Abi { } impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety { + fn is_safe(self) -> bool { + matches!(self, hir::Safety::Safe) + } + fn prefix_str(self) -> &'static str { self.prefix_str() } diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index 3d263e62de6..cb11bb3ef16 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -51,6 +51,14 @@ impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArg fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::GenericArgsRef<'tcx> { GenericArgs::identity_for_item(tcx, def_id) } + + fn extend_with_error( + tcx: TyCtxt<'tcx>, + def_id: DefId, + original_args: &[ty::GenericArg<'tcx>], + ) -> ty::GenericArgsRef<'tcx> { + ty::GenericArgs::extend_with_error(tcx, def_id, original_args) + } } impl<'tcx> rustc_type_ir::inherent::IntoKind for GenericArg<'tcx> { diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index be91249a25f..293cc0a7eca 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -1,15 +1,13 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::intern::Interned; use rustc_hir::def_id::DefId; -use rustc_macros::{ - extension, HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, -}; +use rustc_macros::{extension, HashStable}; use rustc_type_ir as ir; use std::cmp::Ordering; use crate::ty::{ - self, Binder, DebruijnIndex, EarlyBinder, PredicatePolarity, Term, Ty, TyCtxt, TypeFlags, - Upcast, UpcastFrom, WithCachedTypeInfo, + self, DebruijnIndex, EarlyBinder, PredicatePolarity, Ty, TyCtxt, TypeFlags, Upcast, UpcastFrom, + WithCachedTypeInfo, }; pub type TraitRef<'tcx> = ir::TraitRef<TyCtxt<'tcx>>; @@ -24,6 +22,15 @@ pub type PredicateKind<'tcx> = ir::PredicateKind<TyCtxt<'tcx>>; pub type NormalizesTo<'tcx> = ir::NormalizesTo<TyCtxt<'tcx>>; pub type CoercePredicate<'tcx> = ir::CoercePredicate<TyCtxt<'tcx>>; pub type SubtypePredicate<'tcx> = ir::SubtypePredicate<TyCtxt<'tcx>>; +pub type OutlivesPredicate<'tcx, T> = ir::OutlivesPredicate<TyCtxt<'tcx>, T>; +pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<'tcx, ty::Region<'tcx>>; +pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<'tcx, Ty<'tcx>>; +pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>; +pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<'tcx, RegionOutlivesPredicate<'tcx>>; +pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicate<'tcx>>; +pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>; +pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>; +pub type PolyProjectionPredicate<'tcx> = ty::Binder<'tcx, ProjectionPredicate<'tcx>>; /// A statement that can be proven by a trait solver. This includes things that may /// show up in where clauses, such as trait predicates and projection predicates, @@ -155,6 +162,8 @@ pub struct Clause<'tcx>( pub(super) Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>, ); +impl<'tcx> rustc_type_ir::inherent::Clause<TyCtxt<'tcx>> for Clause<'tcx> {} + impl<'tcx> Clause<'tcx> { pub fn as_predicate(self) -> Predicate<'tcx> { Predicate(self.0) @@ -231,34 +240,6 @@ impl<'tcx> ExistentialPredicate<'tcx> { pub type PolyExistentialPredicate<'tcx> = ty::Binder<'tcx, ExistentialPredicate<'tcx>>; -impl<'tcx> PolyExistentialPredicate<'tcx> { - /// Given an existential predicate like `?Self: PartialEq<u32>` (e.g., derived from `dyn PartialEq<u32>`), - /// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self` - /// has been replaced with `self_ty` (e.g., `self_ty: PartialEq<u32>`, in our example). - pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Clause<'tcx> { - match self.skip_binder() { - ExistentialPredicate::Trait(tr) => { - self.rebind(tr).with_self_ty(tcx, self_ty).upcast(tcx) - } - ExistentialPredicate::Projection(p) => { - self.rebind(p.with_self_ty(tcx, self_ty)).upcast(tcx) - } - ExistentialPredicate::AutoTrait(did) => { - let generics = tcx.generics_of(did); - let trait_ref = if generics.own_params.len() == 1 { - ty::TraitRef::new(tcx, did, [self_ty]) - } else { - // If this is an ill-formed auto trait, then synthesize - // new error args for the missing generics. - let err_args = ty::GenericArgs::extend_with_error(tcx, did, &[self_ty.into()]); - ty::TraitRef::new(tcx, did, err_args) - }; - self.rebind(trait_ref).upcast(tcx) - } - } - } -} - impl<'tcx> ty::List<ty::PolyExistentialPredicate<'tcx>> { /// Returns the "principal `DefId`" of this set of existential predicates. /// @@ -322,49 +303,9 @@ impl<'tcx> ty::List<ty::PolyExistentialPredicate<'tcx>> { } pub type PolyTraitRef<'tcx> = ty::Binder<'tcx, TraitRef<'tcx>>; - -impl<'tcx> PolyTraitRef<'tcx> { - pub fn self_ty(&self) -> ty::Binder<'tcx, Ty<'tcx>> { - self.map_bound_ref(|tr| tr.self_ty()) - } - - pub fn def_id(&self) -> DefId { - self.skip_binder().def_id - } -} - pub type PolyExistentialTraitRef<'tcx> = ty::Binder<'tcx, ExistentialTraitRef<'tcx>>; - -impl<'tcx> PolyExistentialTraitRef<'tcx> { - pub fn def_id(&self) -> DefId { - self.skip_binder().def_id - } - - /// Object types don't have a self type specified. Therefore, when - /// we convert the principal trait-ref into a normal trait-ref, - /// you must give *some* self type. A common choice is `mk_err()` - /// or some placeholder type. - pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::PolyTraitRef<'tcx> { - self.map_bound(|trait_ref| trait_ref.with_self_ty(tcx, self_ty)) - } -} - pub type PolyExistentialProjection<'tcx> = ty::Binder<'tcx, ExistentialProjection<'tcx>>; -impl<'tcx> PolyExistentialProjection<'tcx> { - pub fn with_self_ty( - &self, - tcx: TyCtxt<'tcx>, - self_ty: Ty<'tcx>, - ) -> ty::PolyProjectionPredicate<'tcx> { - self.map_bound(|p| p.with_self_ty(tcx, self_ty)) - } - - pub fn item_def_id(&self) -> DefId { - self.skip_binder().def_id - } -} - impl<'tcx> Clause<'tcx> { /// Performs a instantiation suitable for going from a /// poly-trait-ref to supertraits that must hold if that @@ -471,73 +412,6 @@ impl<'tcx> Clause<'tcx> { } } -pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>; - -impl<'tcx> PolyTraitPredicate<'tcx> { - pub fn def_id(self) -> DefId { - // Ok to skip binder since trait `DefId` does not care about regions. - self.skip_binder().def_id() - } - - pub fn self_ty(self) -> ty::Binder<'tcx, Ty<'tcx>> { - self.map_bound(|trait_ref| trait_ref.self_ty()) - } - - #[inline] - pub fn polarity(self) -> PredicatePolarity { - self.skip_binder().polarity - } -} - -/// `A: B` -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct OutlivesPredicate<A, B>(pub A, pub B); -pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>; -pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>; -pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<'tcx, RegionOutlivesPredicate<'tcx>>; -pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicate<'tcx>>; - -pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>; - -pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>; - -pub type PolyProjectionPredicate<'tcx> = Binder<'tcx, ProjectionPredicate<'tcx>>; - -impl<'tcx> PolyProjectionPredicate<'tcx> { - /// Returns the `DefId` of the trait of the associated item being projected. - #[inline] - pub fn trait_def_id(&self, tcx: TyCtxt<'tcx>) -> DefId { - self.skip_binder().projection_term.trait_def_id(tcx) - } - - /// Get the [PolyTraitRef] required for this projection to be well formed. - /// Note that for generic associated types the predicates of the associated - /// type also need to be checked. - #[inline] - pub fn required_poly_trait_ref(&self, tcx: TyCtxt<'tcx>) -> PolyTraitRef<'tcx> { - // Note: unlike with `TraitRef::to_poly_trait_ref()`, - // `self.0.trait_ref` is permitted to have escaping regions. - // This is because here `self` has a `Binder` and so does our - // return value, so we are preserving the number of binding - // levels. - self.map_bound(|predicate| predicate.projection_term.trait_ref(tcx)) - } - - pub fn term(&self) -> Binder<'tcx, Term<'tcx>> { - self.map_bound(|predicate| predicate.term) - } - - /// The `DefId` of the `TraitItem` for the associated type. - /// - /// Note that this is not the `DefId` of the `TraitRef` containing this - /// associated type, which is in `tcx.associated_item(projection_def_id()).container`. - pub fn projection_def_id(&self) -> DefId { - // Ok to skip binder since trait `DefId` does not care about regions. - self.skip_binder().projection_term.def_id - } -} - pub trait ToPolyTraitRef<'tcx> { fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>; } @@ -554,8 +428,8 @@ impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PredicateKind<'tcx>> for Predicate<'tcx> { } } -impl<'tcx> UpcastFrom<TyCtxt<'tcx>, Binder<'tcx, PredicateKind<'tcx>>> for Predicate<'tcx> { - fn upcast_from(from: Binder<'tcx, PredicateKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self { +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, PredicateKind<'tcx>>> for Predicate<'tcx> { + fn upcast_from(from: ty::Binder<'tcx, PredicateKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self { tcx.mk_predicate(from) } } @@ -566,8 +440,8 @@ impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ClauseKind<'tcx>> for Predicate<'tcx> { } } -impl<'tcx> UpcastFrom<TyCtxt<'tcx>, Binder<'tcx, ClauseKind<'tcx>>> for Predicate<'tcx> { - fn upcast_from(from: Binder<'tcx, ClauseKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self { +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ClauseKind<'tcx>>> for Predicate<'tcx> { + fn upcast_from(from: ty::Binder<'tcx, ClauseKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self { tcx.mk_predicate(from.map_bound(PredicateKind::Clause)) } } @@ -580,12 +454,12 @@ impl<'tcx> UpcastFrom<TyCtxt<'tcx>, Clause<'tcx>> for Predicate<'tcx> { impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ClauseKind<'tcx>> for Clause<'tcx> { fn upcast_from(from: ClauseKind<'tcx>, tcx: TyCtxt<'tcx>) -> Self { - tcx.mk_predicate(Binder::dummy(PredicateKind::Clause(from))).expect_clause() + tcx.mk_predicate(ty::Binder::dummy(PredicateKind::Clause(from))).expect_clause() } } -impl<'tcx> UpcastFrom<TyCtxt<'tcx>, Binder<'tcx, ClauseKind<'tcx>>> for Clause<'tcx> { - fn upcast_from(from: Binder<'tcx, ClauseKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self { +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, ClauseKind<'tcx>>> for Clause<'tcx> { + fn upcast_from(from: ty::Binder<'tcx, ClauseKind<'tcx>>, tcx: TyCtxt<'tcx>) -> Self { tcx.mk_predicate(from.map_bound(|clause| PredicateKind::Clause(clause))).expect_clause() } } @@ -609,22 +483,22 @@ impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for Clause<'tcx> { } } -impl<'tcx> UpcastFrom<TyCtxt<'tcx>, Binder<'tcx, TraitRef<'tcx>>> for Predicate<'tcx> { - fn upcast_from(from: Binder<'tcx, TraitRef<'tcx>>, tcx: TyCtxt<'tcx>) -> Self { +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, TraitRef<'tcx>>> for Predicate<'tcx> { + fn upcast_from(from: ty::Binder<'tcx, TraitRef<'tcx>>, tcx: TyCtxt<'tcx>) -> Self { let pred: PolyTraitPredicate<'tcx> = from.upcast(tcx); pred.upcast(tcx) } } -impl<'tcx> UpcastFrom<TyCtxt<'tcx>, Binder<'tcx, TraitRef<'tcx>>> for Clause<'tcx> { - fn upcast_from(from: Binder<'tcx, TraitRef<'tcx>>, tcx: TyCtxt<'tcx>) -> Self { +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, TraitRef<'tcx>>> for Clause<'tcx> { + fn upcast_from(from: ty::Binder<'tcx, TraitRef<'tcx>>, tcx: TyCtxt<'tcx>) -> Self { let pred: PolyTraitPredicate<'tcx> = from.upcast(tcx); pred.upcast(tcx) } } -impl<'tcx> UpcastFrom<TyCtxt<'tcx>, Binder<'tcx, TraitRef<'tcx>>> for PolyTraitPredicate<'tcx> { - fn upcast_from(from: Binder<'tcx, TraitRef<'tcx>>, _tcx: TyCtxt<'tcx>) -> Self { +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, ty::Binder<'tcx, TraitRef<'tcx>>> for PolyTraitPredicate<'tcx> { + fn upcast_from(from: ty::Binder<'tcx, TraitRef<'tcx>>, _tcx: TyCtxt<'tcx>) -> Self { from.map_bound(|trait_ref| TraitPredicate { trait_ref, polarity: PredicatePolarity::Positive, @@ -664,10 +538,8 @@ impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyRegionOutlivesPredicate<'tcx>> for Predi } } -impl<'tcx> UpcastFrom<TyCtxt<'tcx>, OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>> - for Predicate<'tcx> -{ - fn upcast_from(from: OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>, tcx: TyCtxt<'tcx>) -> Self { +impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TypeOutlivesPredicate<'tcx>> for Predicate<'tcx> { + fn upcast_from(from: TypeOutlivesPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self { ty::Binder::dummy(PredicateKind::Clause(ClauseKind::TypeOutlives(from))).upcast(tcx) } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 0dbb17e9db4..a1ead1bb59f 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2860,10 +2860,9 @@ where } } -impl<'tcx, T, U, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::OutlivesPredicate<T, U> +impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::OutlivesPredicate<'tcx, T> where T: Print<'tcx, P>, - U: Print<'tcx, P>, { fn print(&self, cx: &mut P) -> Result<(), PrintError> { define_scoped_cx!(cx); @@ -2934,12 +2933,13 @@ impl<'tcx> ty::TraitRef<'tcx> { } } +#[extension(pub trait PrintPolyTraitRefExt<'tcx>)] impl<'tcx> ty::Binder<'tcx, ty::TraitRef<'tcx>> { - pub fn print_only_trait_path(self) -> ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>> { + fn print_only_trait_path(self) -> ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>> { self.map_bound(|tr| tr.print_only_trait_path()) } - pub fn print_trait_sugared(self) -> ty::Binder<'tcx, TraitRefPrintSugared<'tcx>> { + fn print_trait_sugared(self) -> ty::Binder<'tcx, TraitRefPrintSugared<'tcx>> { self.map_bound(|tr| tr.print_trait_sugared()) } } @@ -2960,8 +2960,9 @@ impl<'tcx> ty::TraitPredicate<'tcx> { } } +#[extension(pub trait PrintPolyTraitPredicateExt<'tcx>)] impl<'tcx> ty::PolyTraitPredicate<'tcx> { - pub fn print_modifiers_and_trait_path( + fn print_modifiers_and_trait_path( self, ) -> ty::Binder<'tcx, TraitPredPrintModifiersAndPath<'tcx>> { self.map_bound(TraitPredPrintModifiersAndPath) @@ -3014,21 +3015,7 @@ forward_display_to_print! { ty::Region<'tcx>, Ty<'tcx>, &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, - ty::Const<'tcx>, - - // HACK(eddyb) these are exhaustive instead of generic, - // because `for<'tcx>` isn't possible yet. - ty::PolyExistentialProjection<'tcx>, - ty::PolyExistentialTraitRef<'tcx>, - ty::Binder<'tcx, ty::TraitRef<'tcx>>, - ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, - ty::Binder<'tcx, TraitRefPrintSugared<'tcx>>, - ty::Binder<'tcx, ty::FnSig<'tcx>>, - ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, - ty::Binder<'tcx, TraitPredPrintModifiersAndPath<'tcx>>, - ty::Binder<'tcx, ty::ProjectionPredicate<'tcx>>, - ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>, - ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>> + ty::Const<'tcx> } define_print! { diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index 551e2ea2295..d7da37385e1 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -384,6 +384,10 @@ impl<'tcx> rustc_type_ir::inherent::BoundVarLike<TyCtxt<'tcx>> for BoundRegion { fn var(self) -> BoundVar { self.var } + + fn assert_eq(self, var: ty::BoundVariableKind) { + assert_eq!(self.kind, var.expect_region()) + } } impl core::fmt::Debug for BoundRegion { diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 81d92a2a448..af3aa3b56f7 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -387,38 +387,6 @@ impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::AdtDef<'tcx> { } } -impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> TypeFoldable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> { - fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( - self, - folder: &mut F, - ) -> Result<Self, F::Error> { - folder.try_fold_binder(self) - } -} - -impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> { - fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result { - visitor.visit_binder(self) - } -} - -impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> { - fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( - self, - folder: &mut F, - ) -> Result<Self, F::Error> { - self.try_map_bound(|ty| ty.try_fold_with(folder)) - } -} - -impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeSuperVisitable<TyCtxt<'tcx>> - for ty::Binder<'tcx, T> -{ - fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result { - self.as_ref().skip_binder().visit_with(visitor) - } -} - impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> { fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( self, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 2d9d178449e..40f3db89df5 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -3,17 +3,16 @@ #![allow(rustc::usage_of_ty_tykind)] use crate::infer::canonical::Canonical; -use crate::ty::visit::ValidateBoundVars; use crate::ty::InferTy::*; use crate::ty::{ self, AdtDef, BoundRegionKind, Discr, Region, Ty, TyCtxt, TypeFlags, TypeSuperVisitable, - TypeVisitable, TypeVisitableExt, TypeVisitor, + TypeVisitable, TypeVisitor, }; use crate::ty::{GenericArg, GenericArgs, GenericArgsRef}; use crate::ty::{List, ParamEnv}; use hir::def::{CtorKind, DefKind}; use rustc_data_structures::captures::Captures; -use rustc_errors::{DiagArgValue, ErrorGuaranteed, IntoDiagArg, MultiSpan}; +use rustc_errors::{ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::LangItem; @@ -21,11 +20,11 @@ use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; -use rustc_target::spec::abi::{self, Abi}; +use rustc_target::spec::abi; use std::assert_matches::debug_assert_matches; use std::borrow::Cow; use std::iter; -use std::ops::{ControlFlow, Deref, Range}; +use std::ops::{ControlFlow, Range}; use ty::util::IntTypeExt; use rustc_type_ir::TyKind::*; @@ -40,6 +39,7 @@ pub type TyKind<'tcx> = ir::TyKind<TyCtxt<'tcx>>; pub type TypeAndMut<'tcx> = ir::TypeAndMut<TyCtxt<'tcx>>; pub type AliasTy<'tcx> = ir::AliasTy<TyCtxt<'tcx>>; pub type FnSig<'tcx> = ir::FnSig<TyCtxt<'tcx>>; +pub type Binder<'tcx, T> = ir::Binder<TyCtxt<'tcx>, T>; pub trait Article { fn article(&self) -> &'static str; @@ -373,7 +373,7 @@ impl<'tcx> CoroutineClosureArgs<'tcx> { self.split().signature_parts_ty } - pub fn coroutine_closure_sig(self) -> ty::Binder<'tcx, CoroutineClosureSignature<'tcx>> { + pub fn coroutine_closure_sig(self) -> Binder<'tcx, CoroutineClosureSignature<'tcx>> { let interior = self.coroutine_witness_ty(); let ty::FnPtr(sig) = self.signature_parts_ty().kind() else { bug!() }; sig.map_bound(|sig| { @@ -401,6 +401,45 @@ impl<'tcx> CoroutineClosureArgs<'tcx> { pub fn coroutine_witness_ty(self) -> Ty<'tcx> { self.split().coroutine_witness_ty } + + pub fn has_self_borrows(&self) -> bool { + match self.coroutine_captures_by_ref_ty().kind() { + ty::FnPtr(sig) => sig + .skip_binder() + .visit_with(&mut HasRegionsBoundAt { binder: ty::INNERMOST }) + .is_break(), + ty::Error(_) => true, + _ => bug!(), + } + } +} +/// Unlike `has_escaping_bound_vars` or `outermost_exclusive_binder`, this will +/// detect only regions bound *at* the debruijn index. +struct HasRegionsBoundAt { + binder: ty::DebruijnIndex, +} +// FIXME: Could be optimized to not walk into components with no escaping bound vars. +impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasRegionsBoundAt { + type Result = ControlFlow<()>; + fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>( + &mut self, + t: &ty::Binder<'tcx, T>, + ) -> Self::Result { + self.binder.shift_in(1); + t.super_visit_with(self)?; + self.binder.shift_out(1); + ControlFlow::Continue(()) + } + + fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result { + if let ty::ReBound(binder, _) = *r + && self.binder == binder + { + ControlFlow::Break(()) + } else { + ControlFlow::Continue(()) + } + } } #[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)] @@ -898,203 +937,6 @@ impl BoundVariableKind { } } -/// Binder is a binder for higher-ranked lifetimes or types. It is part of the -/// compiler's representation for things like `for<'a> Fn(&'a isize)` -/// (which would be represented by the type `PolyTraitRef == -/// Binder<'tcx, TraitRef>`). Note that when we instantiate, -/// erase, or otherwise "discharge" these bound vars, we change the -/// type from `Binder<'tcx, T>` to just `T` (see -/// e.g., `liberate_late_bound_regions`). -/// -/// `Decodable` and `Encodable` are implemented for `Binder<T>` using the `impl_binder_encode_decode!` macro. -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -#[derive(HashStable, Lift)] -pub struct Binder<'tcx, T> { - value: T, - bound_vars: &'tcx List<BoundVariableKind>, -} - -impl<'tcx, T> Binder<'tcx, T> -where - T: TypeVisitable<TyCtxt<'tcx>>, -{ - /// Wraps `value` in a binder, asserting that `value` does not - /// contain any bound vars that would be bound by the - /// binder. This is commonly used to 'inject' a value T into a - /// different binding level. - #[track_caller] - pub fn dummy(value: T) -> Binder<'tcx, T> { - assert!( - !value.has_escaping_bound_vars(), - "`{value:?}` has escaping bound vars, so it cannot be wrapped in a dummy binder." - ); - Binder { value, bound_vars: ty::List::empty() } - } - - pub fn bind_with_vars(value: T, bound_vars: &'tcx List<BoundVariableKind>) -> Binder<'tcx, T> { - if cfg!(debug_assertions) { - let mut validator = ValidateBoundVars::new(bound_vars); - value.visit_with(&mut validator); - } - Binder { value, bound_vars } - } -} - -impl<'tcx, T> rustc_type_ir::inherent::BoundVars<TyCtxt<'tcx>> for ty::Binder<'tcx, T> { - fn bound_vars(&self) -> &'tcx List<ty::BoundVariableKind> { - self.bound_vars - } - - fn has_no_bound_vars(&self) -> bool { - self.bound_vars.is_empty() - } -} - -impl<'tcx, T> Binder<'tcx, T> { - /// 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 - /// discharge the binder using `no_bound_vars` or - /// `instantiate_bound_regions` or something like - /// that. `skip_binder` is only valid when you are either - /// extracting data that has nothing to do with bound vars, you - /// are doing some sort of test that does not involve bound - /// regions, or you are being very careful about your depth - /// accounting. - /// - /// Some examples where `skip_binder` is reasonable: - /// - /// - extracting the `DefId` from a PolyTraitRef; - /// - comparing the self type of a PolyTraitRef to see if it is equal to - /// a type parameter `X`, since the type `X` does not reference any regions - pub fn skip_binder(self) -> T { - self.value - } - - pub fn bound_vars(&self) -> &'tcx List<BoundVariableKind> { - self.bound_vars - } - - pub fn as_ref(&self) -> Binder<'tcx, &T> { - Binder { value: &self.value, bound_vars: self.bound_vars } - } - - pub fn as_deref(&self) -> Binder<'tcx, &T::Target> - where - T: Deref, - { - Binder { value: &self.value, bound_vars: self.bound_vars } - } - - pub fn map_bound_ref<F, U: TypeVisitable<TyCtxt<'tcx>>>(&self, f: F) -> Binder<'tcx, U> - where - F: FnOnce(&T) -> U, - { - self.as_ref().map_bound(f) - } - - pub fn map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>>(self, f: F) -> Binder<'tcx, U> - where - F: FnOnce(T) -> U, - { - let Binder { value, bound_vars } = self; - let value = f(value); - if cfg!(debug_assertions) { - let mut validator = ValidateBoundVars::new(bound_vars); - value.visit_with(&mut validator); - } - Binder { value, bound_vars } - } - - pub fn try_map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>, E>( - self, - f: F, - ) -> Result<Binder<'tcx, U>, E> - where - F: FnOnce(T) -> Result<U, E>, - { - let Binder { value, bound_vars } = self; - let value = f(value)?; - if cfg!(debug_assertions) { - let mut validator = ValidateBoundVars::new(bound_vars); - value.visit_with(&mut validator); - } - Ok(Binder { value, bound_vars }) - } - - /// Wraps a `value` in a binder, using the same bound variables as the - /// current `Binder`. This should not be used if the new value *changes* - /// the bound variables. Note: the (old or new) value itself does not - /// necessarily need to *name* all the bound variables. - /// - /// This currently doesn't do anything different than `bind`, because we - /// don't actually track bound vars. However, semantically, it is different - /// because bound vars aren't allowed to change here, whereas they are - /// in `bind`. This may be (debug) asserted in the future. - pub fn rebind<U>(&self, value: U) -> Binder<'tcx, U> - where - U: TypeVisitable<TyCtxt<'tcx>>, - { - Binder::bind_with_vars(value, self.bound_vars) - } - - /// Unwraps and returns the value within, but only if it contains - /// no bound vars at all. (In other words, if this binder -- - /// and indeed any enclosing binder -- doesn't bind anything at - /// all.) Otherwise, returns `None`. - /// - /// (One could imagine having a method that just unwraps a single - /// binder, but permits late-bound vars bound by enclosing - /// binders, but that would require adjusting the debruijn - /// indices, and given the shallow binding structure we often use, - /// would not be that useful.) - pub fn no_bound_vars(self) -> Option<T> - where - T: TypeVisitable<TyCtxt<'tcx>>, - { - // `self.value` is equivalent to `self.skip_binder()` - if self.value.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) } - } - - /// Splits the contents into two things that share the same binder - /// level as the original, returning two distinct binders. - /// - /// `f` should consider bound regions at depth 1 to be free, and - /// anything it produces with bound regions at depth 1 will be - /// bound in the resulting return values. - pub fn split<U, V, F>(self, f: F) -> (Binder<'tcx, U>, Binder<'tcx, V>) - where - F: FnOnce(T) -> (U, V), - { - let Binder { value, bound_vars } = self; - let (u, v) = f(value); - (Binder { value: u, bound_vars }, Binder { value: v, bound_vars }) - } -} - -impl<'tcx, T> Binder<'tcx, Option<T>> { - pub fn transpose(self) -> Option<Binder<'tcx, T>> { - let Binder { value, bound_vars } = self; - value.map(|value| Binder { value, bound_vars }) - } -} - -impl<'tcx, T: IntoIterator> Binder<'tcx, T> { - pub fn iter(self) -> impl Iterator<Item = ty::Binder<'tcx, T::Item>> { - let Binder { value, bound_vars } = self; - value.into_iter().map(|value| Binder { value, bound_vars }) - } -} - -impl<'tcx, T> IntoDiagArg for Binder<'tcx, T> -where - T: IntoDiagArg, -{ - fn into_diag_arg(self) -> DiagArgValue { - self.value.into_diag_arg() - } -} - #[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)] pub struct GenSig<'tcx> { pub resume_ty: Ty<'tcx>, @@ -1103,48 +945,6 @@ pub struct GenSig<'tcx> { } pub type PolyFnSig<'tcx> = Binder<'tcx, FnSig<'tcx>>; - -impl<'tcx> PolyFnSig<'tcx> { - #[inline] - pub fn inputs(&self) -> Binder<'tcx, &'tcx [Ty<'tcx>]> { - self.map_bound_ref(|fn_sig| fn_sig.inputs()) - } - - #[inline] - #[track_caller] - pub fn input(&self, index: usize) -> ty::Binder<'tcx, Ty<'tcx>> { - self.map_bound_ref(|fn_sig| fn_sig.inputs()[index]) - } - - pub fn inputs_and_output(&self) -> ty::Binder<'tcx, &'tcx List<Ty<'tcx>>> { - self.map_bound_ref(|fn_sig| fn_sig.inputs_and_output) - } - - #[inline] - pub fn output(&self) -> ty::Binder<'tcx, Ty<'tcx>> { - self.map_bound_ref(|fn_sig| fn_sig.output()) - } - - pub fn c_variadic(&self) -> bool { - self.skip_binder().c_variadic - } - - pub fn safety(&self) -> hir::Safety { - self.skip_binder().safety - } - - pub fn abi(&self) -> abi::Abi { - self.skip_binder().abi - } - - pub fn is_fn_trait_compatible(&self) -> bool { - matches!( - self.skip_binder(), - ty::FnSig { safety: rustc_hir::Safety::Safe, abi: Abi::Rust, c_variadic: false, .. } - ) - } -} - pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<'tcx, FnSig<'tcx>>>; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] @@ -1203,6 +1003,10 @@ impl<'tcx> rustc_type_ir::inherent::BoundVarLike<TyCtxt<'tcx>> for BoundTy { fn var(self) -> BoundVar { self.var } + + fn assert_eq(self, var: ty::BoundVariableKind) { + assert_eq!(self.kind, var.expect_ty()) + } } #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] @@ -2001,7 +1805,7 @@ impl<'tcx> Ty<'tcx> { FnPtr(f) => *f, Error(_) => { // ignore errors (#54954) - ty::Binder::dummy(ty::FnSig { + Binder::dummy(ty::FnSig { inputs_and_output: ty::List::empty(), c_variadic: false, safety: hir::Safety::Safe, diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 218567bbd59..b1bbfd420e1 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -1,7 +1,6 @@ use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags}; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::sso::SsoHashSet; use rustc_type_ir::fold::TypeFoldable; use std::ops::ControlFlow; @@ -145,103 +144,6 @@ impl<'tcx> TyCtxt<'tcx> { } } -pub struct ValidateBoundVars<'tcx> { - bound_vars: &'tcx ty::List<ty::BoundVariableKind>, - binder_index: ty::DebruijnIndex, - // We may encounter the same variable at different levels of binding, so - // this can't just be `Ty` - visited: SsoHashSet<(ty::DebruijnIndex, Ty<'tcx>)>, -} - -impl<'tcx> ValidateBoundVars<'tcx> { - pub fn new(bound_vars: &'tcx ty::List<ty::BoundVariableKind>) -> Self { - ValidateBoundVars { - bound_vars, - binder_index: ty::INNERMOST, - visited: SsoHashSet::default(), - } - } -} - -impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ValidateBoundVars<'tcx> { - type Result = ControlFlow<()>; - - fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>( - &mut self, - t: &Binder<'tcx, T>, - ) -> Self::Result { - self.binder_index.shift_in(1); - let result = t.super_visit_with(self); - self.binder_index.shift_out(1); - result - } - - fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result { - if t.outer_exclusive_binder() < self.binder_index - || !self.visited.insert((self.binder_index, t)) - { - return ControlFlow::Break(()); - } - match *t.kind() { - ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => { - if self.bound_vars.len() <= bound_ty.var.as_usize() { - bug!("Not enough bound vars: {:?} not found in {:?}", t, self.bound_vars); - } - let list_var = self.bound_vars[bound_ty.var.as_usize()]; - match list_var { - ty::BoundVariableKind::Ty(kind) => { - if kind != bound_ty.kind { - bug!( - "Mismatched type kinds: {:?} doesn't var in list {:?}", - bound_ty.kind, - list_var - ); - } - } - _ => { - bug!("Mismatched bound variable kinds! Expected type, found {:?}", list_var) - } - } - } - - _ => (), - }; - - t.super_visit_with(self) - } - - fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result { - match *r { - ty::ReBound(index, br) if index == self.binder_index => { - if self.bound_vars.len() <= br.var.as_usize() { - bug!("Not enough bound vars: {:?} not found in {:?}", br, self.bound_vars); - } - let list_var = self.bound_vars[br.var.as_usize()]; - match list_var { - ty::BoundVariableKind::Region(kind) => { - if kind != br.kind { - bug!( - "Mismatched region kinds: {:?} doesn't match var ({:?}) in list ({:?})", - br.kind, - list_var, - self.bound_vars - ); - } - } - _ => bug!( - "Mismatched bound variable kinds! Expected region, found {:?}", - list_var - ), - } - } - - _ => (), - }; - - ControlFlow::Continue(()) - } -} - /// Collects all the late-bound regions at the innermost binding level /// into a hash set. struct LateBoundRegionsCollector { |
