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.
Chayim Refael Friedman 7 days ago
parent 0ea4f0f · commit d712cb7
-rw-r--r--crates/hir-ty/src/generics.rs2
-rw-r--r--crates/hir-ty/src/infer.rs14
-rw-r--r--crates/hir-ty/src/infer/closure.rs8
-rw-r--r--crates/hir-ty/src/infer/diagnostics.rs15
-rw-r--r--crates/hir-ty/src/infer/path.rs1
-rw-r--r--crates/hir-ty/src/lower.rs64
-rw-r--r--crates/hir/src/source_analyzer.rs11
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);