Unnamed repository; edit this file 'description' to name the repository.
Reuse the `Generics` from `TyLoweringContext`
This is a micro-optimization and I'm not sure it's worth the code becoming a bit more ugly, but it's not *really* ugly.
| -rw-r--r-- | crates/hir-ty/src/generics.rs | 2 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer.rs | 14 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/closure.rs | 8 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/diagnostics.rs | 15 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/path.rs | 1 | ||||
| -rw-r--r-- | crates/hir-ty/src/lower.rs | 64 | ||||
| -rw-r--r-- | crates/hir/src/source_analyzer.rs | 11 |
7 files changed, 88 insertions, 27 deletions
diff --git a/crates/hir-ty/src/generics.rs b/crates/hir-ty/src/generics.rs index 25a31e2f58..c4321e8a61 100644 --- a/crates/hir-ty/src/generics.rs +++ b/crates/hir-ty/src/generics.rs @@ -39,7 +39,7 @@ pub(crate) fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics<'_> } #[derive(Debug)] -pub(crate) struct Generics<'db> { +pub struct Generics<'db> { chain: ArrayVec<SingleGenerics<'db>, 2>, } diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index b399a7e0ed..0b16da722e 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -61,7 +61,7 @@ use rustc_ast_ir::Mutability; use rustc_hash::{FxHashMap, FxHashSet}; use rustc_type_ir::{ AliasTyKind, TypeFoldable, TypeVisitableExt, - inherent::{IntoKind, Ty as _}, + inherent::{GenericArgs as _, IntoKind, Ty as _}, }; use smallvec::SmallVec; use span::Edition; @@ -1189,6 +1189,7 @@ pub(crate) struct InferenceContext<'body, 'db> { pub(crate) edition: Edition, allow_using_generic_params: bool, generics: OnceCell<Generics<'db>>, + identity_args: OnceCell<GenericArgs<'db>>, pub(crate) table: unify::InferenceTable<'db>, pub(crate) lang_items: &'db LangItems, pub(crate) features: &'db UnstableFeatures, @@ -1302,6 +1303,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { generic_def, allow_using_generic_params, generics: OnceCell::new(), + identity_args: OnceCell::new(), store, traits_in_scope: resolver.traits_in_scope(db), resolver, @@ -1840,6 +1842,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { types_source, store_owner, self.generic_def, + &self.generics, lifetime_elision, self.allow_using_generic_params, &self.defined_anon_consts, @@ -1905,8 +1908,12 @@ impl<'body, 'db> InferenceContext<'body, 'db> { } fn generics(&self) -> &Generics<'db> { - self.generics.get_or_init(|| { - crate::generics::generics(self.db, self.store_owner.generic_def(self.db)) + self.generics.get_or_init(|| crate::generics::generics(self.db, self.generic_def)) + } + + fn identity_args(&self) -> GenericArgs<'db> { + *self.identity_args.get_or_init(|| { + GenericArgs::identity_for_item(self.interner(), self.store_owner.into()) }) } @@ -2182,6 +2189,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { InferenceTyDiagnosticSource::Body, self.store_owner, self.generic_def, + &self.generics, LifetimeElisionKind::Infer, self.allow_using_generic_params, &self.defined_anon_consts, diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs index 90578e30c2..ab111736d5 100644 --- a/crates/hir-ty/src/infer/closure.rs +++ b/crates/hir-ty/src/infer/closure.rs @@ -23,9 +23,9 @@ use crate::{ db::{InternedClosure, InternedClosureId, InternedCoroutineClosureId, InternedCoroutineId}, infer::{BreakableKind, Diverges, coerce::CoerceMany, pat::PatOrigin}, next_solver::{ - AliasTy, Binder, ClauseKind, DbInterner, ErrorGuaranteed, FnSig, GenericArg, GenericArgs, - PolyFnSig, PolyProjectionPredicate, Predicate, PredicateKind, SolverDefId, TermId, Ty, - TyKind, Unnormalized, + AliasTy, Binder, ClauseKind, DbInterner, ErrorGuaranteed, FnSig, GenericArg, PolyFnSig, + PolyProjectionPredicate, Predicate, PredicateKind, SolverDefId, TermId, Ty, TyKind, + Unnormalized, abi::Safety, infer::{ BoundRegionConversionTime, InferOk, InferResult, @@ -99,7 +99,7 @@ impl<'db> InferenceContext<'_, 'db> { debug!(?bound_sig, ?liberated_sig); - let parent_args = GenericArgs::identity_for_item(interner, self.store_owner.into()); + let parent_args = self.identity_args(); let tupled_upvars_ty = self.table.next_ty_var(closure_expr.into()); diff --git a/crates/hir-ty/src/infer/diagnostics.rs b/crates/hir-ty/src/infer/diagnostics.rs index 71aa35e634..a08a8a023e 100644 --- a/crates/hir-ty/src/infer/diagnostics.rs +++ b/crates/hir-ty/src/infer/diagnostics.rs @@ -2,7 +2,7 @@ //! and a wrapper around [`TyLoweringContext`] ([`InferenceTyLoweringContext`]) that replaces //! it and takes care of diagnostics in inference. -use std::cell::RefCell; +use std::cell::{OnceCell, RefCell}; use std::ops::{Deref, DerefMut}; use either::Either; @@ -16,6 +16,7 @@ use thin_vec::ThinVec; use crate::{ InferenceDiagnostic, InferenceTyDiagnosticSource, TyLoweringDiagnostic, db::{AnonConstId, HirDatabase}, + generics::Generics, lower::{ ForbidParamsAfterReason, LifetimeElisionKind, TyLoweringContext, path::{PathDiagnosticCallback, PathLoweringContext}, @@ -71,12 +72,20 @@ impl<'db, 'a> InferenceTyLoweringContext<'db, 'a> { source: InferenceTyDiagnosticSource, def: ExpressionStoreOwnerId, generic_def: GenericDefId, + generics: &'a OnceCell<Generics<'db>>, lifetime_elision: LifetimeElisionKind<'db>, allow_using_generic_params: bool, defined_anon_consts: &'a RefCell<ThinVec<AnonConstId>>, ) -> Self { - let mut ctx = - TyLoweringContext::new(db, resolver, store, def, generic_def, lifetime_elision); + let mut ctx = TyLoweringContext::new( + db, + resolver, + store, + def, + generic_def, + generics, + lifetime_elision, + ); if !allow_using_generic_params { ctx.forbid_params_after(0, ForbidParamsAfterReason::AnonConst); } diff --git a/crates/hir-ty/src/infer/path.rs b/crates/hir-ty/src/infer/path.rs index a2bcf02589..bc4039ff2e 100644 --- a/crates/hir-ty/src/infer/path.rs +++ b/crates/hir-ty/src/infer/path.rs @@ -147,6 +147,7 @@ impl<'db> InferenceContext<'_, 'db> { InferenceTyDiagnosticSource::Body, self.store_owner, self.generic_def, + &self.generics, LifetimeElisionKind::Infer, self.allow_using_generic_params, &self.defined_anon_consts, diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index f79bcddef0..737cfb16f6 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -194,7 +194,7 @@ pub struct TyLoweringContext<'db, 'a> { store: &'a ExpressionStore, def: ExpressionStoreOwnerId, generic_def: GenericDefId, - generics: OnceCell<Generics<'db>>, + generics: &'a OnceCell<Generics<'db>>, in_binders: DebruijnIndex, impl_trait_mode: ImplTraitLoweringState, /// Tracks types with explicit `?Sized` bounds. @@ -213,6 +213,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { store: &'a ExpressionStore, def: ExpressionStoreOwnerId, generic_def: GenericDefId, + generics: &'a OnceCell<Generics<'db>>, lifetime_elision: LifetimeElisionKind<'db>, ) -> Self { let impl_trait_mode = ImplTraitLoweringState::new(ImplTraitLoweringMode::Disallowed); @@ -227,7 +228,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { resolver, def, generic_def, - generics: Default::default(), + generics, store, in_binders, impl_trait_mode, @@ -1126,12 +1127,14 @@ pub(crate) fn impl_trait_with_diagnostics( ) -> Option<TyLoweringResult<StoredEarlyBinder<StoredTraitRef>>> { let impl_data = ImplSignature::of(db, impl_id); let resolver = impl_id.resolver(db); + let generics = OnceCell::new(); let mut ctx = TyLoweringContext::new( db, &resolver, &impl_data.store, ExpressionStoreOwnerId::Signature(impl_id.into()), impl_id.into(), + &generics, LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true }, ); let self_ty = db.impl_self_ty(impl_id).skip_binder(); @@ -1208,12 +1211,14 @@ impl ImplTraits { // FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe let data = FunctionSignature::of(db, def); let resolver = def.resolver(db); + let generics = OnceCell::new(); let mut ctx_ret = TyLoweringContext::new( db, &resolver, &data.store, ExpressionStoreOwnerId::Signature(def.into()), def.into(), + &generics, LifetimeElisionKind::Infer, ) .with_impl_trait_mode(ImplTraitLoweringMode::Opaque); @@ -1237,12 +1242,14 @@ impl ImplTraits { ) -> Option<Box<StoredEarlyBinder<ImplTraits>>> { let data = TypeAliasSignature::of(db, def); let resolver = def.resolver(db); + let generics = OnceCell::new(); let mut ctx = TyLoweringContext::new( db, &resolver, &data.store, ExpressionStoreOwnerId::Signature(def.into()), def.into(), + &generics, LifetimeElisionKind::AnonymousReportError, ) .with_impl_trait_mode(ImplTraitLoweringMode::Opaque); @@ -1336,12 +1343,14 @@ pub(crate) fn type_for_const_with_diagnostics( let resolver = def.resolver(db); let data = ConstSignature::of(db, def); let parent = def.loc(db).container; + let generics = OnceCell::new(); let mut ctx = TyLoweringContext::new( db, &resolver, &data.store, ExpressionStoreOwnerId::Signature(def.into()), def.into(), + &generics, LifetimeElisionKind::AnonymousReportError, ); ctx.set_lifetime_elision(LifetimeElisionKind::for_const(ctx.interner, parent)); @@ -1364,12 +1373,14 @@ pub(crate) fn type_for_static_with_diagnostics( ) -> TyLoweringResult<StoredEarlyBinder<StoredTy>> { let resolver = def.resolver(db); let data = StaticSignature::of(db, def); + let generics = OnceCell::new(); let mut ctx = TyLoweringContext::new( db, &resolver, &data.store, ExpressionStoreOwnerId::Signature(def.into()), def.into(), + &generics, LifetimeElisionKind::AnonymousReportError, ); ctx.set_lifetime_elision(LifetimeElisionKind::Elided(Region::new_static(ctx.interner))); @@ -1437,19 +1448,21 @@ pub(crate) fn type_for_type_alias_with_diagnostics( t: TypeAliasId, ) -> TyLoweringResult<StoredEarlyBinder<StoredTy>> { let type_alias_data = TypeAliasSignature::of(db, t); - let resolver = t.resolver(db); let interner = DbInterner::new_no_crate(db); if type_alias_data.flags.contains(TypeAliasFlags::IS_EXTERN) { TyLoweringResult::empty(StoredEarlyBinder::bind( Ty::new_foreign(interner, t.into()).store(), )) } else { + let resolver = t.resolver(db); + let generics = OnceCell::new(); let mut ctx = TyLoweringContext::new( db, &resolver, &type_alias_data.store, ExpressionStoreOwnerId::Signature(t.into()), t.into(), + &generics, LifetimeElisionKind::AnonymousReportError, ) .with_impl_trait_mode(ImplTraitLoweringMode::Opaque); @@ -1487,7 +1500,7 @@ pub(crate) fn impl_self_ty_with_diagnostics( impl_id: ImplId, ) -> TyLoweringResult<StoredEarlyBinder<StoredTy>> { let resolver = impl_id.resolver(db); - + let generics = OnceCell::new(); let impl_data = ImplSignature::of(db, impl_id); let mut ctx = TyLoweringContext::new( db, @@ -1495,6 +1508,7 @@ pub(crate) fn impl_self_ty_with_diagnostics( &impl_data.store, ExpressionStoreOwnerId::Signature(impl_id.into()), impl_id.into(), + &generics, LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true }, ); let ty = ctx.lower_ty(impl_data.self_ty); @@ -1535,12 +1549,14 @@ pub(crate) fn const_param_types_with_diagnostics( let mut result = ArenaMap::new(); let (data, store) = GenericParams::with_store(db, def); let resolver = def.resolver(db); + let generics = OnceCell::new(); let mut ctx = TyLoweringContext::new( db, &resolver, store, ExpressionStoreOwnerId::Signature(def), def, + &generics, LifetimeElisionKind::AnonymousReportError, ); ctx.forbid_params_after(0, ForbidParamsAfterReason::ConstParamTy); @@ -1585,6 +1601,7 @@ pub(crate) fn field_types_with_diagnostics( VariantId::UnionId(it) => (it.resolver(db), it.into()), VariantId::EnumVariantId(it) => (it.resolver(db), it.lookup(db).parent.into()), }; + let generics = OnceCell::new(); let mut res = ArenaMap::default(); let mut ctx = TyLoweringContext::new( db, @@ -1592,6 +1609,7 @@ pub(crate) fn field_types_with_diagnostics( &var_data.store, ExpressionStoreOwnerId::VariantFields(variant_id), generic_def, + &generics, LifetimeElisionKind::AnonymousReportError, ); for (field_id, field_data) in var_data.fields().iter() { @@ -1714,16 +1732,20 @@ fn resolve_type_param_assoc_type_shorthand( assoc_name: Name, ) -> AssocTypeShorthandResolution { let generics = generics(db, def); + let store = generics.store(); + let generics = &OnceCell::from(generics); let resolver = def.resolver(db); let mut ctx = TyLoweringContext::new( db, &resolver, - generics.store(), + store, ExpressionStoreOwnerId::Signature(def), def, + generics, LifetimeElisionKind::AnonymousReportError, ); let interner = ctx.interner; + let generics = generics.get().unwrap(); let param_ty = Ty::new_param(interner, param, generics.type_or_const_param_idx(param.into())); let mut this_trait_resolution = None; @@ -1891,13 +1913,15 @@ pub(crate) fn type_alias_bounds_with_diagnostics( type_alias: TypeAliasId, ) -> TyLoweringResult<TypeAliasBounds<StoredEarlyBinder<StoredClauses>>> { let type_alias_data = TypeAliasSignature::of(db, type_alias); - let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db); + let resolver = type_alias.resolver(db); + let generics = OnceCell::new(); let mut ctx = TyLoweringContext::new( db, &resolver, &type_alias_data.store, ExpressionStoreOwnerId::Signature(type_alias.into()), type_alias.into(), + &generics, LifetimeElisionKind::AnonymousReportError, ); let interner = ctx.interner; @@ -2130,16 +2154,20 @@ fn generic_predicates( def: GenericDefId, ) -> TyLoweringResult<GenericPredicates> { let generics = generics(db, def); + let store = generics.store(); + let generics = &OnceCell::from(generics); let resolver = def.resolver(db); let interner = DbInterner::new_no_crate(db); let mut ctx = TyLoweringContext::new( db, &resolver, - generics.store(), + store, ExpressionStoreOwnerId::Signature(def), def, + generics, LifetimeElisionKind::AnonymousReportError, ); + let generics = generics.get().unwrap(); let sized_trait = ctx.lang_items.Sized; // We need to lower parents and self separately - see the comment below lowering of implicit @@ -2339,24 +2367,27 @@ pub(crate) fn generic_defaults_with_diagnostics( db: &dyn HirDatabase, def: GenericDefId, ) -> TyLoweringResult<GenericDefaults> { - let generic_params = generics(db, def); - if generic_params.has_no_params() { + let generics = generics(db, def); + if generics.has_no_params() { return TyLoweringResult::empty(GenericDefaults(ThinVec::new())); } let resolver = def.resolver(db); - let store_for_self = generic_params.store(); + let store_for_self = generics.store(); + let generics = &OnceCell::from(generics); let mut ctx = TyLoweringContext::new( db, &resolver, store_for_self, ExpressionStoreOwnerId::Signature(def), def, + generics, LifetimeElisionKind::AnonymousReportError, ) .with_impl_trait_mode(ImplTraitLoweringMode::Disallowed); + let generics = generics.get().unwrap(); let mut defaults = ThinVec::new(); - if let Some(parent) = generic_params.parent() { + if let Some(parent) = generics.parent() { ctx.store = parent.store(); defaults.extend( parent.iter_with_idx().map(|(idx, _id, p)| handle_generic_param(&mut ctx, idx, p)), @@ -2366,9 +2397,7 @@ pub(crate) fn generic_defaults_with_diagnostics( ctx.defined_anon_consts.clear(); ctx.store = store_for_self; defaults.extend( - generic_params - .iter_self_with_idx() - .map(|(idx, _id, p)| handle_generic_param(&mut ctx, idx, p)), + generics.iter_self_with_idx().map(|(idx, _id, p)| handle_generic_param(&mut ctx, idx, p)), ); defaults.shrink_to_fit(); return TyLoweringResult::from_ctx(GenericDefaults(defaults), ctx); @@ -2434,12 +2463,14 @@ fn fn_sig_for_fn( let data = FunctionSignature::of(db, def); let resolver = def.resolver(db); let interner = DbInterner::new_no_crate(db); + let generics = OnceCell::new(); let mut ctx_params = TyLoweringContext::new( db, &resolver, &data.store, ExpressionStoreOwnerId::Signature(def.into()), def.into(), + &generics, LifetimeElisionKind::for_fn_params(data), ); let params = data.params.iter().map(|&tr| ctx_params.lower_ty(tr)); @@ -2450,6 +2481,7 @@ fn fn_sig_for_fn( &data.store, ExpressionStoreOwnerId::Signature(def.into()), def.into(), + &generics, LifetimeElisionKind::for_fn_ret(interner), ) .with_impl_trait_mode(ImplTraitLoweringMode::Opaque); @@ -2521,14 +2553,16 @@ pub(crate) fn associated_ty_item_bounds<'db>( type_alias: TypeAliasId, ) -> EarlyBinder<'db, BoundExistentialPredicates<'db>> { let type_alias_data = TypeAliasSignature::of(db, type_alias); - let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db); + let resolver = type_alias.resolver(db); let interner = DbInterner::new_no_crate(db); + let generics = OnceCell::new(); let mut ctx = TyLoweringContext::new( db, &resolver, &type_alias_data.store, ExpressionStoreOwnerId::Signature(type_alias.into()), type_alias.into(), + &generics, LifetimeElisionKind::AnonymousReportError, ); // FIXME: we should never create non-existential predicates in the first place diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 4029b004a7..0fc439b3cc 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -5,7 +5,10 @@ //! //! So, this modules should not be used during hir construction, it exists //! purely for "IDE needs". -use std::iter::{self, once}; +use std::{ + cell::OnceCell, + iter::{self, once}, +}; use either::Either; use hir_def::{ @@ -374,12 +377,14 @@ impl<'db> SourceAnalyzer<'db> { let type_ref = self.type_id(ty)?; let generic_def = self.resolver.generic_def()?; + let generics = OnceCell::new(); let mut ty = TyLoweringContext::new( db, &self.resolver, self.store()?, generic_def.into(), generic_def, + &generics, // FIXME: Is this correct here? Anyway that should impact mostly diagnostics, which we don't emit here // (this can impact the lifetimes generated, e.g. in `const` they won't be `'static`, but this seems like a // small problem). @@ -1753,12 +1758,14 @@ fn resolve_hir_path_( let types = || { let (ty, unresolved) = match path.type_anchor() { Some(type_ref) => resolver.generic_def().and_then(|def| { + let generics = OnceCell::new(); let (_, res) = TyLoweringContext::new( db, resolver, store?, def.into(), def, + &generics, LifetimeElisionKind::Infer, ) .lower_ty_ext(type_ref); @@ -1909,12 +1916,14 @@ fn resolve_hir_path_qualifier( (|| { let (ty, unresolved) = match path.type_anchor() { Some(type_ref) => resolver.generic_def().and_then(|def| { + let generics = OnceCell::new(); let (_, res) = TyLoweringContext::new( db, resolver, store, def.into(), def, + &generics, LifetimeElisionKind::Infer, ) .lower_ty_ext(type_ref); |