From 6248bbbf268c327d70967bc7dcab909f912b9bf8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 8 Feb 2023 11:52:19 +1100 Subject: [PATCH 1/3] Pre-intern some commonly used type variables. This requires some rearrangement of plumbing, such as adding `mk_fresh_{,int_,float_}ty` and removing `mk_ty_infer`. --- compiler/rustc_hir_typeck/src/demand.rs | 8 +- compiler/rustc_infer/src/infer/freshen.rs | 17 ++-- compiler/rustc_middle/src/ty/context.rs | 78 ++++++++++++++++--- compiler/rustc_middle/src/ty/print/pretty.rs | 4 +- compiler/rustc_symbol_mangling/src/v0.rs | 2 +- .../rustc_trait_selection/src/traits/wf.rs | 2 +- 6 files changed, 80 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index c4905a934cb..ae00042eae7 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -273,12 +273,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ct_op: |c| c, ty_op: |t| match *t.kind() { ty::Infer(ty::TyVar(_)) => self.tcx.mk_ty_var(ty::TyVid::from_u32(0)), - ty::Infer(ty::IntVar(_)) => { - self.tcx.mk_ty_infer(ty::IntVar(ty::IntVid { index: 0 })) - } - ty::Infer(ty::FloatVar(_)) => { - self.tcx.mk_ty_infer(ty::FloatVar(ty::FloatVid { index: 0 })) - } + ty::Infer(ty::IntVar(_)) => self.tcx.mk_int_var(ty::IntVid { index: 0 }), + ty::Infer(ty::FloatVar(_)) => self.tcx.mk_float_var(ty::FloatVid { index: 0 }), _ => t, }, }; diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index 1c76950cc6c..073a2b0753d 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -58,14 +58,9 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { } } - fn freshen_ty( - &mut self, - opt_ty: Option>, - key: ty::InferTy, - freshener: F, - ) -> Ty<'tcx> + fn freshen_ty(&mut self, opt_ty: Option>, key: ty::InferTy, mk_fresh: F) -> Ty<'tcx> where - F: FnOnce(u32) -> ty::InferTy, + F: FnOnce(u32) -> Ty<'tcx>, { if let Some(ty) = opt_ty { return ty.fold_with(self); @@ -76,7 +71,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { Entry::Vacant(entry) => { let index = self.ty_freshen_count; self.ty_freshen_count += 1; - let t = self.infcx.tcx.mk_ty_infer(freshener(index)); + let t = mk_fresh(index); entry.insert(t); t } @@ -204,7 +199,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { match v { ty::TyVar(v) => { let opt_ty = self.infcx.inner.borrow_mut().type_variables().probe(v).known(); - Some(self.freshen_ty(opt_ty, ty::TyVar(v), ty::FreshTy)) + Some(self.freshen_ty(opt_ty, ty::TyVar(v), |n| self.infcx.tcx.mk_fresh_ty(n))) } ty::IntVar(v) => Some( @@ -216,7 +211,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { .probe_value(v) .map(|v| v.to_type(self.infcx.tcx)), ty::IntVar(v), - ty::FreshIntTy, + |n| self.infcx.tcx.mk_fresh_int_ty(n), ), ), @@ -229,7 +224,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { .probe_value(v) .map(|v| v.to_type(self.infcx.tcx)), ty::FloatVar(v), - ty::FreshFloatTy, + |n| self.infcx.tcx.mk_fresh_float_ty(n), ), ), diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 04537ad635a..5fe8a4521ca 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -241,6 +241,11 @@ impl<'tcx> CtxtInterners<'tcx> { } } +const NUM_PREINTERNED_TY_VARS: u32 = 100; +const NUM_PREINTERNED_FRESH_TYS: u32 = 20; +const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3; +const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3; + pub struct CommonTypes<'tcx> { pub unit: Ty<'tcx>, pub bool: Ty<'tcx>, @@ -266,7 +271,20 @@ pub struct CommonTypes<'tcx> { /// Dummy type used for the `Self` of a `TraitRef` created for converting /// a trait object, and which gets removed in `ExistentialTraitRef`. /// This type must not appear anywhere in other converted types. + /// `Infer(ty::FreshTy(0))` does the job. pub trait_object_dummy_self: Ty<'tcx>, + + /// Pre-interned `Infer(ty::TyVar(n))` for small values of `n`. + pub ty_vars: Vec>, + + /// Pre-interned `Infer(ty::FreshTy(n))` for small values of `n`. + pub fresh_tys: Vec>, + + /// Pre-interned `Infer(ty::FreshIntTy(n))` for small values of `n`. + pub fresh_int_tys: Vec>, + + /// Pre-interned `Infer(ty::FreshFloatTy(n))` for small values of `n`. + pub fresh_float_tys: Vec>, } pub struct CommonLifetimes<'tcx> { @@ -289,6 +307,15 @@ impl<'tcx> CommonTypes<'tcx> { ) -> CommonTypes<'tcx> { let mk = |ty| interners.intern_ty(ty, sess, untracked); + let ty_vars = + (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect(); + let fresh_tys: Vec<_> = + (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect(); + let fresh_int_tys: Vec<_> = + (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect(); + let fresh_float_tys: Vec<_> = + (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect(); + CommonTypes { unit: mk(Tuple(List::empty())), bool: mk(Bool), @@ -311,7 +338,12 @@ impl<'tcx> CommonTypes<'tcx> { str_: mk(Str), self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })), - trait_object_dummy_self: mk(Infer(ty::FreshTy(0))), + trait_object_dummy_self: fresh_tys[0], + + ty_vars, + fresh_tys, + fresh_int_tys, + fresh_float_tys, } } } @@ -1867,29 +1899,55 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_ty(GeneratorWitnessMIR(id, substs)) } - #[inline] - pub fn mk_ty_var(self, v: TyVid) -> Ty<'tcx> { - self.mk_ty_infer(TyVar(v)) - } - #[inline] pub fn mk_const(self, kind: impl Into>, ty: Ty<'tcx>) -> Const<'tcx> { self.mk_const_internal(ty::ConstData { kind: kind.into(), ty }) } + #[inline] + pub fn mk_ty_var(self, v: TyVid) -> Ty<'tcx> { + // Use a pre-interned one when possible. + self.types.ty_vars.get(v.as_usize()).copied().unwrap_or_else(|| self.mk_ty(Infer(TyVar(v)))) + } + #[inline] pub fn mk_int_var(self, v: IntVid) -> Ty<'tcx> { - self.mk_ty_infer(IntVar(v)) + self.mk_ty(Infer(IntVar(v))) } #[inline] pub fn mk_float_var(self, v: FloatVid) -> Ty<'tcx> { - self.mk_ty_infer(FloatVar(v)) + self.mk_ty(Infer(FloatVar(v))) } #[inline] - pub fn mk_ty_infer(self, it: InferTy) -> Ty<'tcx> { - self.mk_ty(Infer(it)) + pub fn mk_fresh_ty(self, n: u32) -> Ty<'tcx> { + // Use a pre-interned one when possible. + self.types + .fresh_tys + .get(n as usize) + .copied() + .unwrap_or_else(|| self.mk_ty(Infer(ty::FreshTy(n)))) + } + + #[inline] + pub fn mk_fresh_int_ty(self, n: u32) -> Ty<'tcx> { + // Use a pre-interned one when possible. + self.types + .fresh_int_tys + .get(n as usize) + .copied() + .unwrap_or_else(|| self.mk_ty(Infer(ty::FreshIntTy(n)))) + } + + #[inline] + pub fn mk_fresh_float_ty(self, n: u32) -> Ty<'tcx> { + // Use a pre-interned one when possible. + self.types + .fresh_float_tys + .get(n as usize) + .copied() + .unwrap_or_else(|| self.mk_ty(Infer(ty::FreshFloatTy(n)))) } #[inline] diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index e9a10f483e5..c4a95ddacbf 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1209,7 +1209,7 @@ pub trait PrettyPrinter<'tcx>: // in order to place the projections inside the `<...>`. if !resugared { // Use a type that can't appear in defaults of type parameters. - let dummy_cx = cx.tcx().mk_ty_infer(ty::FreshTy(0)); + let dummy_cx = cx.tcx().mk_fresh_ty(0); let principal = principal.with_self_ty(cx.tcx(), dummy_cx); let args = cx @@ -2696,7 +2696,7 @@ define_print_and_forward_display! { ty::ExistentialTraitRef<'tcx> { // Use a type that can't appear in defaults of type parameters. - let dummy_self = cx.tcx().mk_ty_infer(ty::FreshTy(0)); + let dummy_self = cx.tcx().mk_fresh_ty(0); let trait_ref = self.with_self_ty(cx.tcx(), dummy_self); p!(print(trait_ref.print_only_trait_path())) } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 00d1ff5ceed..c58b6a24ab5 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -540,7 +540,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { match predicate.as_ref().skip_binder() { ty::ExistentialPredicate::Trait(trait_ref) => { // Use a type that can't appear in defaults of type parameters. - let dummy_self = cx.tcx.mk_ty_infer(ty::FreshTy(0)); + let dummy_self = cx.tcx.mk_fresh_ty(0); let trait_ref = trait_ref.with_self_ty(cx.tcx, dummy_self); cx = cx.print_def_path(trait_ref.def_id, trait_ref.substs)?; } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 1136b70a0b9..5cfb6cf332e 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -879,7 +879,7 @@ pub fn object_region_bounds<'tcx>( // Since we don't actually *know* the self type for an object, // this "open(err)" serves as a kind of dummy standin -- basically // a placeholder type. - let open_ty = tcx.mk_ty_infer(ty::FreshTy(0)); + let open_ty = tcx.mk_fresh_ty(0); let predicates = existential_predicates.iter().filter_map(|predicate| { if let ty::ExistentialPredicate::Projection(_) = predicate.skip_binder() { From 7a7256015411f3178df466438006fe45530f4109 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 8 Feb 2023 12:28:03 +1100 Subject: [PATCH 2/3] Reduce direct `mk_ty` usage. We use more specific `mk_*` functions in most places, might as well use them as much as possible. --- .../rustc_codegen_ssa/src/mir/debuginfo.rs | 7 ++-- .../src/const_eval/valtrees.rs | 4 +- .../src/transform/check_consts/qualifs.rs | 4 +- .../rustc_hir_analysis/src/astconv/mod.rs | 4 +- .../src/check/compare_impl_item.rs | 4 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 3 +- compiler/rustc_hir_typeck/src/check.rs | 4 +- compiler/rustc_hir_typeck/src/expr.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 2 +- .../src/infer/canonical/canonicalizer.rs | 2 +- .../rustc_infer/src/infer/canonical/mod.rs | 2 +- .../src/infer/higher_ranked/mod.rs | 4 +- compiler/rustc_infer/src/infer/mod.rs | 4 +- compiler/rustc_middle/src/infer/canonical.rs | 6 +-- compiler/rustc_middle/src/mir/tcx.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 25 +++++++++++- compiler/rustc_middle/src/ty/fold.rs | 9 ++--- compiler/rustc_middle/src/ty/relate.rs | 2 +- compiler/rustc_middle/src/ty/sty.rs | 4 +- .../src/traits/error_reporting/suggestions.rs | 2 +- .../src/traits/project.rs | 4 +- .../src/traits/select/confirmation.rs | 4 +- compiler/rustc_traits/src/chalk/db.rs | 16 +++----- compiler/rustc_traits/src/chalk/lowering.rs | 14 +++---- .../passes/collect_intra_doc_links.rs | 40 +++++++++---------- 25 files changed, 92 insertions(+), 82 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index e9bc40c3310..708f3bc0c78 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -385,10 +385,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { calculate_debuginfo_offset(bx, local, &var, base); // Create a variable which will be a pointer to the actual value - let ptr_ty = bx.tcx().mk_ty(ty::RawPtr(ty::TypeAndMut { - mutbl: mir::Mutability::Mut, - ty: place.layout.ty, - })); + let ptr_ty = bx + .tcx() + .mk_ptr(ty::TypeAndMut { mutbl: mir::Mutability::Mut, ty: place.layout.ty }); let ptr_layout = bx.layout_of(ptr_ty); let alloca = PlaceRef::alloca(bx, ptr_layout); bx.set_var_name(alloca.llval, &(var.name.to_string() + ".dbg.spill")); diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index c52886b77e6..fc546e4de0e 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -193,7 +193,7 @@ fn get_info_on_unsized_field<'tcx>( // Have to adjust type for ty::Str let unsized_inner_ty = match unsized_inner_ty.kind() { - ty::Str => tcx.mk_ty(ty::Uint(ty::UintTy::U8)), + ty::Str => tcx.types.u8, _ => unsized_inner_ty, }; @@ -216,7 +216,7 @@ fn create_pointee_place<'tcx>( let (unsized_inner_ty, num_elems) = get_info_on_unsized_field(ty, valtree, tcx); let unsized_inner_ty = match unsized_inner_ty.kind() { - ty::Str => tcx.mk_ty(ty::Uint(ty::UintTy::U8)), + ty::Str => tcx.types.u8, _ => unsized_inner_ty, }; let unsized_inner_ty_size = diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 8ca3fdf400e..bb4b7ad50b8 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -217,10 +217,10 @@ impl Qualif for CustomEq { fn in_adt_inherently<'tcx>( cx: &ConstCx<'_, 'tcx>, - adt: AdtDef<'tcx>, + def: AdtDef<'tcx>, substs: SubstsRef<'tcx>, ) -> bool { - let ty = cx.tcx.mk_ty(ty::Adt(adt, substs)); + let ty = cx.tcx.mk_adt(def, substs); !ty.is_structural_eq_shallow(cx.tcx) } } diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 75cc7cbaa60..8c753a99a09 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1250,7 +1250,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // // Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty` // parameter to have a skipped binder. - let param_ty = tcx.mk_ty(ty::Alias(ty::Projection, projection_ty.skip_binder())); + let param_ty = tcx.mk_alias(ty::Projection, projection_ty.skip_binder()); self.add_bounds(param_ty, ast_bounds.iter(), bounds, candidate.bound_vars()); } } @@ -2930,7 +2930,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } }; - tcx.mk_ty(ty::Array(self.ast_ty_to_ty(ty), length)) + tcx.mk_array_with_const_len(self.ast_ty_to_ty(ty), length) } hir::TyKind::Typeof(e) => { let ty_erased = tcx.type_of(e.def_id); diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 640920638a7..c86af6a379b 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1927,10 +1927,10 @@ pub(super) fn check_type_bounds<'tcx>( let kind = ty::BoundTyKind::Param(param.def_id, param.name); let bound_var = ty::BoundVariableKind::Ty(kind); bound_vars.push(bound_var); - tcx.mk_ty(ty::Bound( + tcx.mk_bound( ty::INNERMOST, ty::BoundTy { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind }, - )) + ) .into() } GenericParamDefKind::Lifetime => { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 5b9b57da382..5f95622883b 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -603,8 +603,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<'tcx>>( // our example, the type was `Self`, which will also be // `Self` in the GAT. let ty_param = gat_generics.param_at(*ty_idx, tcx); - let ty_param = tcx - .mk_ty(ty::Param(ty::ParamTy { index: ty_param.index, name: ty_param.name })); + let ty_param = tcx.mk_ty_param(ty_param.index, ty_param.name); // Same for the region. In our example, 'a corresponds // to the 'me parameter. let region_param = gat_generics.param_at(*region_a_idx, tcx); diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index cc515e6c853..05f6d8e6072 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -264,9 +264,7 @@ fn check_lang_start_fn<'tcx>( // for example `start`'s generic should be a type parameter let generics = tcx.generics_of(def_id); let fn_generic = generics.param_at(0, tcx); - let generic_tykind = - ty::Param(ty::ParamTy { index: fn_generic.index, name: fn_generic.name }); - let generic_ty = tcx.mk_ty(generic_tykind); + let generic_ty = tcx.mk_ty_param(fn_generic.index, fn_generic.name); let expected_fn_sig = tcx.mk_fn_sig([].iter(), &generic_ty, false, hir::Unsafety::Normal, Abi::Rust); let expected_ty = tcx.mk_fn_ptr(Binder::dummy(expected_fn_sig)); diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index bb235a48361..12850c733e8 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1429,7 +1429,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.check_repeat_element_needs_copy_bound(element, count, element_ty); - tcx.mk_ty(ty::Array(t, count)) + tcx.mk_array_with_const_len(t, count) } fn check_repeat_element_needs_copy_bound( diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 52236ae56ee..3201035bdd8 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1296,7 +1296,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) }); let element_tys = tcx.mk_type_list(element_tys_iter); - let pat_ty = tcx.mk_ty(ty::Tuple(element_tys)); + let pat_ty = tcx.intern_tup(element_tys); if let Some(mut err) = self.demand_eqtype_pat_diag(span, expected, pat_ty, ti) { let reported = err.emit(); // Walk subpatterns with an expected type of `err` in this case to silence diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index f1b32cd941e..c11dcc8587b 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -752,7 +752,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { self.fold_ty(bound_to) } else { let var = self.canonical_var(info, ty_var.into()); - self.tcx().mk_ty(ty::Bound(self.binder_index, var.into())) + self.tcx().mk_bound(self.binder_index, var.into()) } } diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index f7e3e4a1cc0..d5cb3fb2498 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -124,7 +124,7 @@ impl<'tcx> InferCtxt<'tcx> { CanonicalVarKind::PlaceholderTy(ty::PlaceholderType { universe, name }) => { let universe_mapped = universe_map(universe); let placeholder_mapped = ty::PlaceholderType { universe: universe_mapped, name }; - self.tcx.mk_ty(ty::Placeholder(placeholder_mapped)).into() + self.tcx.mk_placeholder(placeholder_mapped).into() } CanonicalVarKind::Region(ui) => self diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs index 412e52d8fd7..39940f4592d 100644 --- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs +++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs @@ -88,10 +88,10 @@ impl<'tcx> InferCtxt<'tcx> { })) }, types: &mut |bound_ty: ty::BoundTy| { - self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { + self.tcx.mk_placeholder(ty::PlaceholderType { universe: next_universe, name: bound_ty.kind, - })) + }) }, consts: &mut |bound_var: ty::BoundVar, ty| { self.tcx diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index e77924900a0..ae196a7133c 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -2071,14 +2071,14 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>( fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { if let ty::Infer(_) = t.kind() { - self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { + self.tcx.mk_placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::ROOT, name: ty::BoundTyKind::Anon({ let idx = self.idx; self.idx += 1; idx }), - })) + }) } else { t.super_fold_with(self) } diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index d6f20a8fc06..e6e4545d9c3 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -345,9 +345,9 @@ impl<'tcx> CanonicalVarValues<'tcx> { var_values: tcx.mk_substs(infos.iter().enumerate().map( |(i, info)| -> ty::GenericArg<'tcx> { match info.kind { - CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) => tcx - .mk_ty(ty::Bound(ty::INNERMOST, ty::BoundVar::from_usize(i).into())) - .into(), + CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) => { + tcx.mk_bound(ty::INNERMOST, ty::BoundVar::from_usize(i).into()).into() + } CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => { let br = ty::BoundRegion { var: ty::BoundVar::from_usize(i), diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index b5e0b88bbe5..9f544de9f87 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -162,7 +162,7 @@ impl<'tcx> Rvalue<'tcx> { match *self { Rvalue::Use(ref operand) => operand.ty(local_decls, tcx), Rvalue::Repeat(ref operand, count) => { - tcx.mk_ty(ty::Array(operand.ty(local_decls, tcx), count)) + tcx.mk_array_with_const_len(operand.ty(local_decls, tcx), count) } Rvalue::ThreadLocalRef(did) => { let static_ty = tcx.type_of(did); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 5fe8a4521ca..802a1a5435a 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1636,6 +1636,7 @@ impl<'tcx> TyCtxt<'tcx> { if *r == kind { r } else { self.mk_region(kind) } } + // Avoid this in favour of more specific `mk_*` methods, where possible. #[allow(rustc::usage_of_ty_tykind)] #[inline] pub fn mk_ty(self, st: TyKind<'tcx>) -> Ty<'tcx> { @@ -1787,6 +1788,11 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_ty(Array(ty, ty::Const::from_usize(self, n))) } + #[inline] + pub fn mk_array_with_const_len(self, ty: Ty<'tcx>, ct: Const<'tcx>) -> Ty<'tcx> { + self.mk_ty(Array(ty, ct)) + } + #[inline] pub fn mk_slice(self, ty: Ty<'tcx>) -> Ty<'tcx> { self.mk_ty(Slice(ty)) @@ -1862,7 +1868,7 @@ impl<'tcx> TyCtxt<'tcx> { item_def_id: DefId, substs: impl IntoIterator>>, ) -> Ty<'tcx> { - self.mk_ty(Alias(ty::Projection, self.mk_alias_ty(item_def_id, substs))) + self.mk_alias(ty::Projection, self.mk_alias_ty(item_def_id, substs)) } #[inline] @@ -1970,9 +1976,24 @@ impl<'tcx> TyCtxt<'tcx> { } } + #[inline] + pub fn mk_bound(self, index: ty::DebruijnIndex, bound_ty: ty::BoundTy) -> Ty<'tcx> { + self.mk_ty(Bound(index, bound_ty)) + } + + #[inline] + pub fn mk_placeholder(self, placeholder: ty::PlaceholderType) -> Ty<'tcx> { + self.mk_ty(Placeholder(placeholder)) + } + + #[inline] + pub fn mk_alias(self, kind: ty::AliasKind, alias_ty: ty::AliasTy<'tcx>) -> Ty<'tcx> { + self.mk_ty(Alias(kind, alias_ty)) + } + #[inline] pub fn mk_opaque(self, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> { - self.mk_ty(Alias(ty::Opaque, self.mk_alias_ty(def_id, substs))) + self.mk_alias(ty::Opaque, self.mk_alias_ty(def_id, substs)) } pub fn mk_place_field(self, place: Place<'tcx>, f: Field, ty: Ty<'tcx>) -> Place<'tcx> { diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 8a0019bc012..c0d319edf76 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -562,10 +562,7 @@ impl<'tcx> TyCtxt<'tcx> { )) }, types: &mut |t: ty::BoundTy| { - self.mk_ty(ty::Bound( - ty::INNERMOST, - ty::BoundTy { var: shift_bv(t.var), kind: t.kind }, - )) + self.mk_bound(ty::INNERMOST, ty::BoundTy { var: shift_bv(t.var), kind: t.kind }) }, consts: &mut |c, ty: Ty<'tcx>| { self.mk_const(ty::ConstKind::Bound(ty::INNERMOST, shift_bv(c)), ty) @@ -614,7 +611,7 @@ impl<'tcx> TyCtxt<'tcx> { ty::BoundVariableKind::Ty(ty::BoundTyKind::Anon(index as u32)) }) .expect_ty(); - self.tcx.mk_ty(ty::Bound(ty::INNERMOST, BoundTy { var, kind })) + self.tcx.mk_bound(ty::INNERMOST, BoundTy { var, kind }) } fn replace_const(&mut self, bv: ty::BoundVar, ty: Ty<'tcx>) -> ty::Const<'tcx> { let entry = self.map.entry(bv); @@ -684,7 +681,7 @@ impl<'tcx> TypeFolder<'tcx> for Shifter<'tcx> { match *ty.kind() { ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => { let debruijn = debruijn.shifted_in(self.amount); - self.tcx.mk_ty(ty::Bound(debruijn, bound_ty)) + self.tcx.mk_bound(debruijn, bound_ty) } _ if ty.has_vars_bound_at_or_above(self.current_index) => ty.super_fold_with(self), diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 890dabde1f7..3b22da41a57 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -502,7 +502,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( (&ty::Array(a_t, sz_a), &ty::Array(b_t, sz_b)) => { let t = relation.relate(a_t, b_t)?; match relation.relate(sz_a, sz_b) { - Ok(sz) => Ok(tcx.mk_ty(ty::Array(t, sz))), + Ok(sz) => Ok(tcx.mk_array_with_const_len(t, sz)), Err(err) => { // Check whether the lengths are both concrete/known values, // but are unequal, for better diagnostics. diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index b3b2a4fd0e5..89cde91e755 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1171,7 +1171,7 @@ impl<'tcx> FallibleTypeFolder<'tcx> for SkipBindersAt<'tcx> { if index == self.index { Err(()) } else { - Ok(self.tcx().mk_ty(ty::Bound(index.shifted_out(1), bv))) + Ok(self.tcx().mk_bound(index.shifted_out(1), bv)) } } else { ty.try_super_fold_with(self) @@ -1260,7 +1260,7 @@ impl<'tcx> AliasTy<'tcx> { } pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { - tcx.mk_ty(ty::Alias(self.kind(tcx), self)) + tcx.mk_alias(self.kind(tcx), self) } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 048a5471994..cca178299df 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -3572,7 +3572,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { { type_diffs = vec![ Sorts(ty::error::ExpectedFound { - expected: self.tcx.mk_ty(ty::Alias(ty::Projection, where_pred.skip_binder().projection_ty)), + expected: self.tcx.mk_alias(ty::Projection, where_pred.skip_binder().projection_ty), found, }), ]; diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index aa81bc640aa..c2bce774bb5 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -785,7 +785,7 @@ impl<'tcx> TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> { let universe = self.universe_for(debruijn); let p = ty::PlaceholderType { universe, name: bound_ty.kind }; self.mapped_types.insert(p, bound_ty); - self.infcx.tcx.mk_ty(ty::Placeholder(p)) + self.infcx.tcx.mk_placeholder(p) } _ if t.has_vars_bound_at_or_above(self.current_index) => t.super_fold_with(self), _ => t, @@ -915,7 +915,7 @@ impl<'tcx> TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> { let db = ty::DebruijnIndex::from_usize( self.universe_indices.len() - index + self.current_index.as_usize() - 1, ); - self.tcx().mk_ty(ty::Bound(db, *replace_var)) + self.tcx().mk_bound(db, *replace_var) } None => ty, } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index fcc4820c2a6..dc5bcb48cad 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -527,13 +527,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let kind = ty::BoundTyKind::Param(param.def_id, param.name); let bound_var = ty::BoundVariableKind::Ty(kind); bound_vars.push(bound_var); - tcx.mk_ty(ty::Bound( + tcx.mk_bound( ty::INNERMOST, ty::BoundTy { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind, }, - )) + ) .into() } GenericParamDefKind::Lifetime => { diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index dbd5f13fe4e..7101f404269 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -588,10 +588,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t _id: chalk_ir::OpaqueTyId>, ) -> chalk_ir::Ty> { // FIXME(chalk): actually get hidden ty - self.interner - .tcx - .mk_ty(ty::Tuple(self.interner.tcx.intern_type_list(&[]))) - .lower_into(self.interner) + self.interner.tcx.types.unit.lower_into(self.interner) } fn closure_kind( @@ -721,13 +718,13 @@ impl<'tcx> chalk_ir::UnificationDatabase> for RustIrDatabase< fn bound_vars_for_item(tcx: TyCtxt<'_>, def_id: DefId) -> SubstsRef<'_> { InternalSubsts::for_item(tcx, def_id, |param, substs| match param.kind { ty::GenericParamDefKind::Type { .. } => tcx - .mk_ty(ty::Bound( + .mk_bound( ty::INNERMOST, ty::BoundTy { var: ty::BoundVar::from(param.index), kind: ty::BoundTyKind::Param(param.def_id, param.name), }, - )) + ) .into(), ty::GenericParamDefKind::Lifetime => { @@ -790,10 +787,9 @@ impl<'tcx> ty::TypeFolder<'tcx> for ReplaceOpaqueTyFolder<'tcx> { fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) = *ty.kind() { if def_id == self.opaque_ty_id.0 && substs == self.identity_substs { - return self.tcx.mk_ty(ty::Bound( - self.binder_index, - ty::BoundTy::from(ty::BoundVar::from_u32(0)), - )); + return self + .tcx + .mk_bound(self.binder_index, ty::BoundTy::from(ty::BoundVar::from_u32(0))); } } ty diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 7c9a014e2ab..4f71dcde818 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -677,11 +677,11 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { match *t.kind() { ty::Param(param) => match self.list.iter().position(|r| r == ¶m) { - Some(idx) => self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { + Some(idx) => self.tcx.mk_placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::from_usize(0), name: ty::BoundTyKind::Anon(idx as u32), - })), + }), None => { self.list.push(param); let idx = self.list.len() - 1 + self.next_ty_placeholder; self.params.insert(idx as u32, param); - self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { + self.tcx.mk_placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::from_usize(0), name: ty::BoundTyKind::Anon(idx as u32), - })) + }) } }, _ => t.super_fold_with(self), @@ -1147,7 +1147,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseParamsSubstitutor<'tcx> { match *t.kind() { ty::Placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::ROOT, name }) => { match self.params.get(&name.expect_anon()) { - Some(param) => self.tcx.mk_ty(ty::Param(*param)), + Some(&ty::ParamTy { index, name }) => self.tcx.mk_ty_param(index, name), None => t, } } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 779cbaa6802..0e2191185eb 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -516,27 +516,27 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // FIXME: Only simple types are supported here, see if we can support // other types such as Tuple, Array, Slice, etc. // See https://github.com/rust-lang/rust/issues/90703#issuecomment-1004263455 - Some(tcx.mk_ty(match prim { - Bool => ty::Bool, - Str => ty::Str, - Char => ty::Char, - Never => ty::Never, - I8 => ty::Int(ty::IntTy::I8), - I16 => ty::Int(ty::IntTy::I16), - I32 => ty::Int(ty::IntTy::I32), - I64 => ty::Int(ty::IntTy::I64), - I128 => ty::Int(ty::IntTy::I128), - Isize => ty::Int(ty::IntTy::Isize), - F32 => ty::Float(ty::FloatTy::F32), - F64 => ty::Float(ty::FloatTy::F64), - U8 => ty::Uint(ty::UintTy::U8), - U16 => ty::Uint(ty::UintTy::U16), - U32 => ty::Uint(ty::UintTy::U32), - U64 => ty::Uint(ty::UintTy::U64), - U128 => ty::Uint(ty::UintTy::U128), - Usize => ty::Uint(ty::UintTy::Usize), + Some(match prim { + Bool => tcx.types.bool, + Str => tcx.types.str_, + Char => tcx.types.char, + Never => tcx.types.never, + I8 => tcx.types.i8, + I16 => tcx.types.i16, + I32 => tcx.types.i32, + I64 => tcx.types.i64, + I128 => tcx.types.i128, + Isize => tcx.types.isize, + F32 => tcx.types.f32, + F64 => tcx.types.f64, + U8 => tcx.types.u8, + U16 => tcx.types.u16, + U32 => tcx.types.u32, + U64 => tcx.types.u64, + U128 => tcx.types.u128, + Usize => tcx.types.usize, _ => return None, - })) + }) } /// Resolve an associated item, returning its containing page's `Res` From e261665b2c6d6dd636ba369a086bd1bef598c026 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 10 Feb 2023 14:41:47 +1100 Subject: [PATCH 3/3] Avoid interning empty tuples. --- compiler/rustc_middle/src/ty/context.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 802a1a5435a..5962384241e 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1800,11 +1800,11 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> { - self.mk_ty(Tuple(self.intern_type_list(&ts))) + if ts.is_empty() { self.types.unit } else { self.mk_ty(Tuple(self.intern_type_list(&ts))) } } pub fn mk_tup, Ty<'tcx>>>(self, iter: I) -> I::Output { - iter.intern_with(|ts| self.mk_ty(Tuple(self.intern_type_list(&ts)))) + iter.intern_with(|ts| self.intern_tup(ts)) } #[inline]