diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 9f6a6a58bb7b3..919187a354af4 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -74,10 +74,10 @@ use crate::traits::solve::{ use crate::ty::predicate::ExistentialPredicateStableCmpExt as _; use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, CanonicalizerState, Clause, ClausePolarity, Clauses, - Const, ConstKind, FnSigKind, GenericArg, GenericArgsUnsized, GenericParamDefKind, List, - ListWithCachedTypeInfo, ParamConst, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, - Predicate, PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, - TyVid, ValTree, ValTreeKind, Visibility, + Const, ConstKind, FlagComputation, FnSigKind, GenericArg, GenericArgsUnsized, + GenericParamDefKind, List, ListWithCachedTypeInfo, ParamConst, Pattern, PatternKind, + PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, Region, RegionKind, ReprOptions, + TraitObjectVisitor, Ty, TyKind, TyVid, ValTree, ValTreeKind, Visibility, }; impl<'tcx> rustc_type_ir::inherent::DefId> for DefId { @@ -141,9 +141,9 @@ pub struct CtxtInterners<'tcx> { /// The arena that types, regions, etc. are allocated from. arena: &'tcx WorkerLocal>, + type_: InternedSet<'tcx, WithCachedTypeInfo>>, // Specifically use a speedy hash algorithm for these hash sets, since // they're accessed quite often. - type_: InternedSet<'tcx, WithCachedTypeInfo>>, const_lists: InternedSet<'tcx, List>>, args: InternedSet<'tcx, GenericArgsUnsized<'tcx>>, type_lists: InternedSet<'tcx, List>>, @@ -211,24 +211,6 @@ impl<'tcx> CtxtInterners<'tcx> { } } - /// Interns a type. (Use `mk_*` functions instead, where possible.) - #[allow(rustc::usage_of_ty_tykind)] - #[inline(never)] - fn intern_ty(&self, kind: TyKind<'tcx>) -> Ty<'tcx> { - Ty(Interned::new_unchecked( - self.type_ - .intern(kind, |kind| { - let flags = ty::FlagComputation::>::for_kind(&kind); - InternedInSet(self.arena.alloc(WithCachedTypeInfo { - internee: kind, - flags: flags.flags, - outer_exclusive_binder: flags.outer_exclusive_binder, - })) - }) - .0, - )) - } - /// Interns a const. (Use `mk_*` functions instead, where possible.) #[allow(rustc::usage_of_ty_tykind)] #[inline(never)] @@ -281,6 +263,183 @@ impl<'tcx> CtxtInterners<'tcx> { .0 } } + + #[inline(always)] + fn intern( + &self, + kind: ty::TyKind<'tcx>, + create_flags: impl FnOnce() -> FlagComputation>, + ) -> Ty<'tcx> { + Ty(Interned::new_unchecked( + self.type_ + .intern(kind, |_| { + let flags = create_flags(); + InternedInSet(self.arena.alloc(WithCachedTypeInfo { + internee: kind, + flags: flags.flags, + outer_exclusive_binder: flags.outer_exclusive_binder, + })) + }) + .0, + )) + } + + #[inline(never)] + fn intern_with_empty_flags(&self, kind: ty::TyKind<'tcx>) -> Ty<'tcx> { + self.intern(kind, || FlagComputation::for_empty_flags()) + } + + #[inline(never)] + pub(super) fn intern_pat(&self, base: Ty<'tcx>, pat: Pattern<'tcx>) -> Ty<'tcx> { + self.intern(Pat(base, pat), || FlagComputation::for_pat(base, pat)) + } + + #[inline(never)] + pub(super) fn intern_coroutine_witness( + &self, + def_id: DefId, + args: ty::GenericArgs<'tcx>, + ) -> Ty<'tcx> { + self.intern(ty::CoroutineWitness(def_id, args), || FlagComputation::for_args(args)) + } + + #[inline(never)] + pub(super) fn intern_infer(&self, infer: ty::InferTy) -> Ty<'tcx> { + self.intern(Infer(infer), || FlagComputation::for_infer(infer)) + } + + #[inline(never)] + pub(super) fn intern_error(&self, error: rustc_errors::ErrorGuaranteed) -> Ty<'tcx> { + self.intern(Error(error), || { + FlagComputation::for_flags(ty::TypeFlags::HAS_NON_REGION_ERROR) + }) + } + + #[inline(never)] + pub(super) fn intern_adt(&self, def: AdtDef<'tcx>, args: ty::GenericArgs<'tcx>) -> Ty<'tcx> { + self.intern(Adt(def, args), || FlagComputation::for_args(args)) + } + + #[inline(never)] + pub(super) fn intern_foreign(&self, def_id: DefId) -> Ty<'tcx> { + self.intern(Foreign(def_id), || FlagComputation::for_empty_flags()) + } + + #[inline(never)] + pub(super) fn intern_array(&self, element: Ty<'tcx>, len: Const<'tcx>) -> Ty<'tcx> { + self.intern(Array(element, len), || FlagComputation::for_array(element, len)) + } + + #[inline(never)] + pub(super) fn intern_slice(&self, element: Ty<'tcx>) -> Ty<'tcx> { + self.intern(Slice(element), || FlagComputation::for_ty(element)) + } + + #[inline(never)] + pub(super) fn intern_raw_ptr( + &self, + pointee: Ty<'tcx>, + mutability: hir::Mutability, + ) -> Ty<'tcx> { + self.intern(RawPtr(pointee, mutability), || FlagComputation::for_ty(pointee)) + } + + #[inline(never)] + pub(super) fn intern_ref( + &self, + region: Region<'tcx>, + pointee: Ty<'tcx>, + mutability: hir::Mutability, + ) -> Ty<'tcx> { + self.intern(Ref(region, pointee, mutability), || FlagComputation::for_ref(region, pointee)) + } + + #[inline(never)] + pub(super) fn intern_fn_def( + &self, + def_id: DefId, + args: Binder<'tcx, ty::GenericArgs<'tcx>>, + ) -> Ty<'tcx> { + self.intern(FnDef(def_id, args), || FlagComputation::for_fn_def(args)) + } + + #[inline(never)] + pub(super) fn intern_fn_ptr( + &self, + sig_tys: Binder<'tcx, ty::FnSigTys>>, + header: ty::FnHeader>, + ) -> Ty<'tcx> { + self.intern(FnPtr(sig_tys, header), || FlagComputation::for_fn_ptr(sig_tys)) + } + + #[inline(never)] + pub(super) fn intern_unsafe_binder( + &self, + bound_ty: ty::UnsafeBinderInner>, + ) -> Ty<'tcx> { + self.intern(UnsafeBinder(bound_ty), || FlagComputation::for_unsafe_binder(bound_ty)) + } + + #[inline(never)] + pub(super) fn intern_dynamic( + &self, + predicates: &'tcx List>, + region: Region<'tcx>, + ) -> Ty<'tcx> { + self.intern(Dynamic(predicates, region), || { + FlagComputation::for_dynamic(predicates, region) + }) + } + + #[inline(never)] + pub(super) fn intern_closure(&self, def_id: DefId, args: ty::GenericArgs<'tcx>) -> Ty<'tcx> { + self.intern(Closure(def_id, args), || FlagComputation::for_args(args)) + } + + #[inline(never)] + pub(super) fn intern_coroutine_closure( + &self, + def_id: DefId, + args: ty::GenericArgs<'tcx>, + ) -> Ty<'tcx> { + self.intern(CoroutineClosure(def_id, args), || FlagComputation::for_args(args)) + } + + #[inline(never)] + pub(super) fn intern_coroutine(&self, def_id: DefId, args: ty::GenericArgs<'tcx>) -> Ty<'tcx> { + self.intern(Coroutine(def_id, args), || FlagComputation::for_coroutine(args)) + } + + #[inline(never)] + pub(super) fn intern_tuple(&self, types: &'tcx List>) -> Ty<'tcx> { + self.intern(Tuple(types), || FlagComputation::for_tys(types)) + } + + #[inline(never)] + pub(super) fn intern_alias(&self, is_rigid: ty::IsRigid, alias: ty::AliasTy<'tcx>) -> Ty<'tcx> { + self.intern(Alias(is_rigid, alias), || FlagComputation::for_alias(is_rigid, alias)) + } + + #[inline(never)] + pub(super) fn intern_param(&self, param: ty::ParamTy) -> Ty<'tcx> { + self.intern(Param(param), || FlagComputation::for_flags(ty::TypeFlags::HAS_TY_PARAM)) + } + + #[inline(never)] + pub(super) fn intern_bound( + &self, + index: ty::BoundVarIndexKind, + bound_ty: ty::BoundTy<'tcx>, + ) -> Ty<'tcx> { + self.intern(Bound(index, bound_ty), || FlagComputation::for_bound(index)) + } + + #[inline(never)] + pub(super) fn intern_placeholder(&self, placeholder: ty::PlaceholderType<'tcx>) -> Ty<'tcx> { + self.intern(Placeholder(placeholder), || { + FlagComputation::for_flags(ty::TypeFlags::HAS_TY_PLACEHOLDER) + }) + } } // For these preinterned values, an alternative would be to have @@ -420,28 +579,30 @@ pub struct CommonConsts<'tcx> { impl<'tcx> CommonTypes<'tcx> { fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> { - let mk = |ty| interners.intern_ty(ty); + let mk = |ty| interners.intern_with_empty_flags(ty); let infer_ty_vars = (0..NUM_PREINTERNED_INFER_TY_VARS) - .map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))) + .map(|n| interners.intern_infer(ty::TyVar(TyVid::from(n)))) + .collect(); + let infer_fresh_tys: Vec<_> = (0..NUM_PREINTERNED_INFER_FRESH_TYS) + .map(|n| interners.intern_infer(ty::FreshTy(n))) .collect(); - let infer_fresh_tys: Vec<_> = - (0..NUM_PREINTERNED_INFER_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect(); + let infer_fresh_int_tys: Vec<_> = (0..NUM_PREINTERNED_INFER_FRESH_INT_TYS) - .map(|n| mk(Infer(ty::FreshIntTy(n)))) + .map(|n| interners.intern_infer(ty::FreshIntTy(n))) .collect(); let infer_fresh_float_tys: Vec<_> = (0..NUM_PREINTERNED_INFER_FRESH_FLOAT_TYS) - .map(|n| mk(Infer(ty::FreshFloatTy(n)))) + .map(|n| interners.intern_infer(ty::FreshFloatTy(n))) .collect(); let bound_bound_anons = (0..NUM_PREINTERNED_BOUND_BOUND_ANONS_I) .map(|i| { (0..NUM_PREINTERNED_BOUND_BOUND_ANONS_V) .map(|v| { - mk(ty::Bound( + interners.intern_bound( ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)), ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon }, - )) + ) }) .collect() }) @@ -449,24 +610,24 @@ impl<'tcx> CommonTypes<'tcx> { let bound_canonical_anons = (0..NUM_PREINTERNED_BOUND_CANONICAL_ANONS) .map(|v| { - mk(ty::Bound( + interners.intern_bound( ty::BoundVarIndexKind::Canonical, ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon }, - )) + ) }) .collect(); let placeholder_root_anons = (0..NUM_PREINTERNED_PLACEHOLDER_ROOT_ANONS) .map(|v| { - mk(ty::Placeholder(PlaceholderType::new_anon( + interners.intern_placeholder(PlaceholderType::new_anon( ty::UniverseIndex::ROOT, ty::BoundVar::from(v), - ))) + )) }) .collect(); CommonTypes { - unit: mk(Tuple(List::empty())), + unit: interners.intern_tuple(List::empty()), bool: mk(Bool), char: mk(Char), never: mk(Never), @@ -487,7 +648,8 @@ impl<'tcx> CommonTypes<'tcx> { f64: mk(Float(ty::FloatTy::F64)), f128: mk(Float(ty::FloatTy::F128)), str_: mk(Str), - self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })), + + self_param: interners.intern_param(ty::ParamTy { index: 0, name: kw::SelfUpper }), trait_object_dummy_self: infer_fresh_tys[0], @@ -767,7 +929,7 @@ pub struct GlobalCtxt<'tcx> { pub arena: &'tcx WorkerLocal>, pub hir_arena: &'tcx WorkerLocal>, - interners: CtxtInterners<'tcx>, + pub(super) interners: CtxtInterners<'tcx>, pub sess: &'tcx Session, crate_types: Vec, @@ -1838,7 +2000,7 @@ macro_rules! sty_debug_print { }; $(let mut $variant = total;)* - for shard in tcx.interners.type_.lock_shards() { + for shard in tcx.interners.type_.lock_shards() { // It seems that ordering doesn't affect anything here. #[allow(rustc::potential_query_instability)] let types = shard.iter(); @@ -2400,11 +2562,49 @@ impl<'tcx> TyCtxt<'tcx> { self.interners.intern_const(kind) } - // Avoid this in favour of more specific `Ty::new_*` methods, where possible. + // FIXME(Jamesbarford) Avoid this in favour of more specific `Ty::new_*` + // methods, where possible. It will also possibly be faster as it will avoid + // this match statement. #[allow(rustc::usage_of_ty_tykind)] #[inline] pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> { - self.interners.intern_ty(st) + match st { + ty::Bool => self.interners.intern_with_empty_flags(ty::Bool), + ty::Char => self.interners.intern_with_empty_flags(ty::Char), + ty::Int(int) => self.interners.intern_with_empty_flags(ty::Int(int)), + ty::Uint(uint) => self.interners.intern_with_empty_flags(ty::Uint(uint)), + ty::Float(float) => self.interners.intern_with_empty_flags(ty::Float(float)), + ty::Adt(def, args) => self.interners.intern_adt(def, args), + ty::Foreign(def_id) => self.interners.intern_foreign(def_id), + ty::Str => self.interners.intern_with_empty_flags(ty::Str), + ty::Array(element, len) => self.interners.intern_array(element, len), + ty::Pat(base, pat) => self.interners.intern_pat(base, pat), + ty::Slice(element) => self.interners.intern_slice(element), + ty::RawPtr(pointee, mutability) => self.interners.intern_raw_ptr(pointee, mutability), + ty::Ref(region, pointee, mutability) => { + self.interners.intern_ref(region, pointee, mutability) + } + ty::FnDef(def_id, args) => self.interners.intern_fn_def(def_id, args), + ty::FnPtr(sig_tys, header) => self.interners.intern_fn_ptr(sig_tys, header), + ty::UnsafeBinder(bound_ty) => self.interners.intern_unsafe_binder(bound_ty), + ty::Dynamic(predicates, region) => self.interners.intern_dynamic(predicates, region), + ty::Closure(def_id, args) => self.interners.intern_closure(def_id, args), + ty::CoroutineClosure(def_id, args) => { + self.interners.intern_coroutine_closure(def_id, args) + } + ty::Coroutine(def_id, args) => self.interners.intern_coroutine(def_id, args), + ty::CoroutineWitness(def_id, args) => { + self.interners.intern_coroutine_witness(def_id, args) + } + ty::Never => self.interners.intern_with_empty_flags(ty::Never), + ty::Tuple(types) => self.interners.intern_tuple(types), + ty::Alias(is_rigid, alias) => self.interners.intern_alias(is_rigid, alias), + ty::Param(param) => self.interners.intern_param(param), + ty::Bound(index, bound_ty) => self.interners.intern_bound(index, bound_ty), + ty::Placeholder(placeholder) => self.interners.intern_placeholder(placeholder), + ty::Infer(infer) => self.interners.intern_infer(infer), + ty::Error(error) => self.interners.intern_error(error), + } } pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index b7719ec0598de..d48d91288b547 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -361,16 +361,9 @@ impl ParamConst { /// Constructors for `Ty` impl<'tcx> Ty<'tcx> { - /// Avoid using this in favour of more specific `new_*` methods, where possible. - /// The more specific methods will often optimize their creation. - #[inline] - fn new(tcx: TyCtxt<'tcx>, st: TyKind<'tcx>) -> Ty<'tcx> { - tcx.mk_ty_from_kind(st) - } - #[inline] pub fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferTy) -> Ty<'tcx> { - Ty::new(tcx, TyKind::Infer(infer)) + tcx.interners.intern_infer(infer) } #[inline] @@ -380,7 +373,7 @@ impl<'tcx> Ty<'tcx> { .infer_ty_vars .get(v.as_usize()) .copied() - .unwrap_or_else(|| Ty::new(tcx, Infer(TyVar(v)))) + .unwrap_or_else(|| tcx.interners.intern_infer(TyVar(v))) } #[inline] @@ -425,7 +418,7 @@ impl<'tcx> Ty<'tcx> { #[inline] pub fn new_param(tcx: TyCtxt<'tcx>, index: u32, name: Symbol) -> Ty<'tcx> { - Ty::new(tcx, Param(ParamTy { index, name })) + tcx.interners.intern_param(ParamTy { index, name }) } #[inline] @@ -441,7 +434,7 @@ impl<'tcx> Ty<'tcx> { { ty } else { - Ty::new(tcx, Bound(ty::BoundVarIndexKind::Bound(index), bound_ty)) + tcx.interners.intern_bound(ty::BoundVarIndexKind::Bound(index), bound_ty) } } @@ -451,12 +444,9 @@ impl<'tcx> Ty<'tcx> { if let Some(ty) = tcx.types.bound_canonical_anons.get(var.as_usize()).copied() { ty } else { - Ty::new( - tcx, - Bound( - ty::BoundVarIndexKind::Canonical, - ty::BoundTy { var, kind: ty::BoundTyKind::Anon }, - ), + tcx.interners.intern_bound( + ty::BoundVarIndexKind::Canonical, + ty::BoundTy { var, kind: ty::BoundTyKind::Anon }, ) } } @@ -470,7 +460,7 @@ impl<'tcx> Ty<'tcx> { { ty } else { - Ty::new(tcx, Placeholder(placeholder)) + tcx.interners.intern_placeholder(placeholder) } } @@ -480,12 +470,12 @@ impl<'tcx> Ty<'tcx> { is_rigid: ty::IsRigid, alias_ty: ty::AliasTy<'tcx>, ) -> Ty<'tcx> { - Ty::new(tcx, Alias(is_rigid, alias_ty)) + tcx.interners.intern_alias(is_rigid, alias_ty) } #[inline] pub fn new_pat(tcx: TyCtxt<'tcx>, base: Ty<'tcx>, pat: ty::Pattern<'tcx>) -> Ty<'tcx> { - Ty::new(tcx, Pat(base, pat)) + tcx.interners.intern_pat(base, pat) } #[inline] @@ -530,7 +520,7 @@ impl<'tcx> Ty<'tcx> { /// Constructs a `TyKind::Error` type with current `ErrorGuaranteed` pub fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Ty<'tcx> { - Ty::new(tcx, Error(guar)) + tcx.interners.intern_error(guar) } /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` to ensure it gets used. @@ -548,7 +538,7 @@ impl<'tcx> Ty<'tcx> { msg: impl Into>, ) -> Ty<'tcx> { let reported = tcx.dcx().span_delayed_bug(span, msg); - Ty::new(tcx, Error(reported)) + tcx.interners.intern_error(reported) } #[inline] @@ -595,7 +585,7 @@ impl<'tcx> Ty<'tcx> { ty: Ty<'tcx>, mutbl: ty::Mutability, ) -> Ty<'tcx> { - Ty::new(tcx, Ref(r, ty, mutbl)) + tcx.interners.intern_ref(r, ty, mutbl) } #[inline] @@ -620,7 +610,7 @@ impl<'tcx> Ty<'tcx> { #[inline] pub fn new_ptr(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, mutbl: ty::Mutability) -> Ty<'tcx> { - Ty::new(tcx, ty::RawPtr(ty, mutbl)) + tcx.interners.intern_raw_ptr(ty, mutbl) } #[inline] @@ -671,17 +661,17 @@ impl<'tcx> Ty<'tcx> { } } } - Ty::new(tcx, Adt(def, args)) + tcx.interners.intern_adt(def, args) } #[inline] pub fn new_foreign(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'tcx> { - Ty::new(tcx, Foreign(def_id)) + tcx.interners.intern_foreign(def_id) } #[inline] pub fn new_array(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> { - Ty::new(tcx, Array(ty, ty::Const::from_target_usize(tcx, n))) + tcx.interners.intern_array(ty, ty::Const::from_target_usize(tcx, n)) } #[inline] @@ -690,17 +680,21 @@ impl<'tcx> Ty<'tcx> { ty: Ty<'tcx>, ct: ty::Const<'tcx>, ) -> Ty<'tcx> { - Ty::new(tcx, Array(ty, ct)) + tcx.interners.intern_array(ty, ct) } #[inline] pub fn new_slice(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { - Ty::new(tcx, Slice(ty)) + tcx.interners.intern_slice(ty) } #[inline] pub fn new_tup(tcx: TyCtxt<'tcx>, ts: &[Ty<'tcx>]) -> Ty<'tcx> { - if ts.is_empty() { tcx.types.unit } else { Ty::new(tcx, Tuple(tcx.mk_type_list(ts))) } + if ts.is_empty() { + tcx.types.unit + } else { + tcx.interners.intern_tuple(tcx.mk_type_list(ts)) + } } pub fn new_tup_from_iter(tcx: TyCtxt<'tcx>, iter: I) -> T::Output @@ -723,18 +717,18 @@ impl<'tcx> Ty<'tcx> { DefKind::AssocFn | DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) ); let args = args.map_bound(|args| tcx.check_and_mk_args(def_id, args)); - Ty::new(tcx, FnDef(def_id, args)) + tcx.interners.intern_fn_def(def_id, args) } #[inline] pub fn new_fn_ptr(tcx: TyCtxt<'tcx>, fty: PolyFnSig<'tcx>) -> Ty<'tcx> { let (sig_tys, hdr) = fty.split(); - Ty::new(tcx, FnPtr(sig_tys, hdr)) + tcx.interners.intern_fn_ptr(sig_tys, hdr) } #[inline] pub fn new_unsafe_binder(tcx: TyCtxt<'tcx>, b: Binder<'tcx, Ty<'tcx>>) -> Ty<'tcx> { - Ty::new(tcx, UnsafeBinder(b.into())) + tcx.interners.intern_unsafe_binder(b.into()) } #[inline] @@ -770,7 +764,7 @@ impl<'tcx> Ty<'tcx> { but it has {projection_count}" ); } - Ty::new(tcx, Dynamic(obj, reg)) + tcx.interners.intern_dynamic(obj, reg) } #[inline] @@ -808,7 +802,7 @@ impl<'tcx> Ty<'tcx> { closure_args: GenericArgs<'tcx>, ) -> Ty<'tcx> { tcx.debug_assert_args_compatible(def_id, closure_args); - Ty::new(tcx, Closure(def_id, closure_args)) + tcx.interners.intern_closure(def_id, closure_args) } #[inline] @@ -818,7 +812,7 @@ impl<'tcx> Ty<'tcx> { closure_args: GenericArgs<'tcx>, ) -> Ty<'tcx> { tcx.debug_assert_args_compatible(def_id, closure_args); - Ty::new(tcx, CoroutineClosure(def_id, closure_args)) + tcx.interners.intern_coroutine_closure(def_id, closure_args) } #[inline] @@ -828,7 +822,7 @@ impl<'tcx> Ty<'tcx> { coroutine_args: GenericArgs<'tcx>, ) -> Ty<'tcx> { tcx.debug_assert_args_compatible(def_id, coroutine_args); - Ty::new(tcx, Coroutine(def_id, coroutine_args)) + tcx.interners.intern_coroutine(def_id, coroutine_args) } #[inline] @@ -840,7 +834,7 @@ impl<'tcx> Ty<'tcx> { if cfg!(debug_assertions) { tcx.debug_assert_args_compatible(tcx.typeck_root_def_id(def_id), args); } - Ty::new(tcx, CoroutineWitness(def_id, args)) + tcx.interners.intern_coroutine_witness(def_id, args) } pub fn new_coroutine_witness_for_coroutine( diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index 4af4f1479ec82..ce21bdb7732ed 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -182,9 +182,36 @@ impl FlagComputation { #[allow(rustc::usage_of_ty_tykind)] pub fn for_kind(kind: &ty::TyKind) -> FlagComputation { - let mut result = FlagComputation::new(); - result.add_kind(kind); - result + match *kind { + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Float(_) + | ty::Uint(_) + | ty::Never + | ty::Str + | ty::Foreign(..) => Self::new(), + ty::Error(_) => Self::for_flags(TypeFlags::HAS_NON_REGION_ERROR), + ty::Param(_) => Self::for_flags(TypeFlags::HAS_TY_PARAM), + ty::Placeholder(..) => Self::for_flags(TypeFlags::HAS_TY_PLACEHOLDER), + ty::Closure(_, args) + | ty::CoroutineClosure(_, args) + | ty::CoroutineWitness(_, args) + | ty::Adt(_, args) => Self::for_args(args), + ty::Coroutine(_, args) => Self::for_coroutine(args), + ty::Bound(index, _) => Self::for_bound(index), + ty::Infer(infer) => Self::for_infer(infer), + ty::Alias(is_rigid, alias) => Self::for_alias(is_rigid, alias), + ty::Dynamic(obj, region) => Self::for_dynamic(obj, region), + ty::Array(ty, len) => Self::for_array(ty, len), + ty::Pat(ty, pat) => Self::for_pat(ty, pat), + ty::Slice(ty) | ty::RawPtr(ty, _) => Self::for_ty(ty), + ty::Ref(region, ty, _) => Self::for_ref(region, ty), + ty::Tuple(types) => Self::for_tys(types), + ty::FnDef(_, args) => Self::for_fn_def(args), + ty::FnPtr(sig_tys, _) => Self::for_fn_ptr(sig_tys), + ty::UnsafeBinder(bound_ty) => Self::for_unsafe_binder(bound_ty), + } } pub fn for_predicate(binder: ty::Binder>) -> FlagComputation { @@ -250,129 +277,122 @@ impl FlagComputation { } // otherwise, this binder captures nothing } - #[allow(rustc::usage_of_ty_tykind)] - fn add_kind(&mut self, kind: &ty::TyKind) { - match *kind { - ty::Bool - | ty::Char - | ty::Int(_) - | ty::Float(_) - | ty::Uint(_) - | ty::Never - | ty::Str - | ty::Foreign(..) => {} - - ty::Error(_) => self.add_flags(TypeFlags::HAS_NON_REGION_ERROR), - - ty::Param(_) => { - self.add_flags(TypeFlags::HAS_TY_PARAM); - } - - ty::Closure(_, args) - | ty::CoroutineClosure(_, args) - | ty::CoroutineWitness(_, args) => { - self.add_args(args.as_slice()); - } - - ty::Coroutine(_, args) => { - self.add_flags(TypeFlags::HAS_TY_CORO); - self.add_args(args.as_slice()); - } - - ty::Bound(ty::BoundVarIndexKind::Canonical, _) => { - self.add_flags(TypeFlags::HAS_TY_BOUND); - self.add_flags(TypeFlags::HAS_CANONICAL_BOUND); - } + /// Flags for a type with no nested types, constants, regions, or binders. + pub fn for_flags(flags: TypeFlags) -> Self { + Self { flags, ..Self::new() } + } - ty::Bound(ty::BoundVarIndexKind::Bound(debruijn), _) => { - self.add_bound_var(debruijn); - self.add_flags(TypeFlags::HAS_TY_BOUND); - } + pub fn for_empty_flags() -> Self { + Self { flags: TypeFlags::empty(), ..Self::new() } + } - ty::Placeholder(..) => { - self.add_flags(TypeFlags::HAS_TY_PLACEHOLDER); - } + pub fn for_args(args: I::GenericArgs) -> Self { + let mut result = Self::new(); + result.add_args(args.as_slice()); + result + } - ty::Infer(infer) => match infer { - ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => { - self.add_flags(TypeFlags::HAS_TY_FRESH) - } + pub fn for_coroutine(args: I::GenericArgs) -> Self { + let mut result = Self::for_args(args); + result.add_flags(TypeFlags::HAS_TY_CORO); + result + } - ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => { - self.add_flags(TypeFlags::HAS_TY_INFER) - } - }, + pub fn for_bound(index: ty::BoundVarIndexKind) -> Self { + let mut result = Self::for_flags(TypeFlags::HAS_TY_BOUND); + match index { + ty::BoundVarIndexKind::Canonical => result.add_flags(TypeFlags::HAS_CANONICAL_BOUND), + ty::BoundVarIndexKind::Bound(debruijn) => result.add_bound_var(debruijn), + } + result + } - ty::Adt(_, args) => { - self.add_args(args.as_slice()); - } + pub fn for_infer(infer: ty::InferTy) -> Self { + Self::for_flags(match infer { + ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => TypeFlags::HAS_TY_FRESH, + ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => TypeFlags::HAS_TY_INFER, + }) + } - ty::Alias(is_rigid, alias) => { - self.add_is_rigid(is_rigid); - self.add_flags(match alias.kind { - ty::Projection { .. } => TypeFlags::HAS_TY_PROJECTION, - ty::Free { .. } => TypeFlags::HAS_TY_FREE_ALIAS, - ty::Opaque { .. } => TypeFlags::HAS_TY_OPAQUE, - ty::Inherent { .. } => TypeFlags::HAS_TY_INHERENT, - }); - self.add_alias_ty(alias); - } + pub fn for_alias(is_rigid: ty::IsRigid, alias: ty::AliasTy) -> Self { + let mut result = Self::new(); + result.add_is_rigid(is_rigid); + result.add_flags(match alias.kind { + ty::Projection { .. } => TypeFlags::HAS_TY_PROJECTION, + ty::Free { .. } => TypeFlags::HAS_TY_FREE_ALIAS, + ty::Opaque { .. } => TypeFlags::HAS_TY_OPAQUE, + ty::Inherent { .. } => TypeFlags::HAS_TY_INHERENT, + }); + result.add_alias_ty(alias); + result + } - ty::Dynamic(obj, r) => { - for predicate in obj.iter() { - self.bound_computation(predicate, |computation, predicate| match predicate { - ty::ExistentialPredicate::Trait(tr) => { - computation.add_args(tr.args.as_slice()) - } - ty::ExistentialPredicate::Projection(p) => { - computation.add_existential_projection(&p); - } - ty::ExistentialPredicate::AutoTrait(_) => {} - }); + pub fn for_dynamic(obj: I::BoundExistentialPredicates, region: Region) -> Self { + let mut result = Self::new(); + for predicate in obj.iter() { + result.bound_computation(predicate, |computation, predicate| match predicate { + ty::ExistentialPredicate::Trait(tr) => computation.add_args(tr.args.as_slice()), + ty::ExistentialPredicate::Projection(p) => { + computation.add_existential_projection(&p) } + ty::ExistentialPredicate::AutoTrait(_) => {} + }); + } + result.add_region(region); + result + } - self.add_region(r); - } - - ty::Array(tt, len) => { - self.add_ty(tt); - self.add_const(len); - } - - ty::Pat(ty, pat) => { - self.add_ty(ty); - self.add_ty_pat(pat); - } + pub fn for_array(ty: I::Ty, len: Const) -> Self { + let mut result = Self::for_ty(ty); + result.add_const(len); + result + } - ty::Slice(tt) => self.add_ty(tt), + pub fn for_pat(ty: I::Ty, pat: I::Pat) -> Self { + let mut result = Self::for_ty(ty); + result.add_ty_pat(pat); + result + } - ty::RawPtr(ty, _) => { - self.add_ty(ty); - } + pub fn for_ty(ty: I::Ty) -> Self { + let mut result = Self::new(); + result.add_ty(ty); + result + } - ty::Ref(r, ty, _) => { - self.add_region(r); - self.add_ty(ty); - } + pub fn for_ref(region: Region, ty: I::Ty) -> Self { + let mut result = Self::new(); + result.add_region(region); + result.add_ty(ty); + result + } - ty::Tuple(types) => { - self.add_tys(types); - } + pub fn for_tys(types: I::Tys) -> Self { + let mut result = Self::new(); + result.add_tys(types); + result + } - ty::FnDef(_, args) => { - self.add_binder_args(args); - } + pub fn for_fn_def(args: ty::Binder) -> Self { + let mut result = Self::new(); + result.add_binder_args(args); + result + } - ty::FnPtr(sig_tys, _) => self.bound_computation(sig_tys, |computation, sig_tys| { - computation.add_tys(sig_tys.inputs_and_output); - }), + pub fn for_fn_ptr(sig_tys: ty::Binder>) -> Self { + let mut result = Self::new(); + result.bound_computation(sig_tys, |computation, sig_tys| { + computation.add_tys(sig_tys.inputs_and_output); + }); + result + } - ty::UnsafeBinder(bound_ty) => { - self.bound_computation(bound_ty.into(), |computation, ty| { - computation.add_ty(ty); - }) - } - } + pub fn for_unsafe_binder(bound_ty: ty::UnsafeBinderInner) -> Self { + let mut result = Self::new(); + result.bound_computation(bound_ty.into(), |computation, ty| { + computation.add_ty(ty); + }); + result } fn add_ty_pat(&mut self, pat: ::Pat) {