Unnamed repository; edit this file 'description' to name the repository.
Save allocations for empty generic_defaults query results
Lukas Wirth 2024-06-22
parent 2761b1e · commit 34ba8db
-rw-r--r--crates/hir-ty/src/db.rs10
-rw-r--r--crates/hir-ty/src/lib.rs15
-rw-r--r--crates/hir-ty/src/lower.rs102
3 files changed, 67 insertions, 60 deletions
diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs
index 515fc4c668..e951048021 100644
--- a/crates/hir-ty/src/db.rs
+++ b/crates/hir-ty/src/db.rs
@@ -21,12 +21,12 @@ use crate::{
chalk_db,
consteval::ConstEvalError,
layout::{Layout, LayoutError},
- lower::GenericPredicates,
+ lower::{GenericDefaults, GenericPredicates},
method_resolution::{InherentImpls, TraitImpls, TyFingerprint},
mir::{BorrowckResult, MirBody, MirLowerError},
- Binders, CallableDefId, ClosureId, Const, FnDefId, GenericArg, ImplTraitId, ImplTraits,
- InferenceResult, Interner, PolyFnSig, QuantifiedWhereClause, Substitution, TraitEnvironment,
- TraitRef, Ty, TyDefId, ValueTyDefId,
+ Binders, CallableDefId, ClosureId, Const, FnDefId, ImplTraitId, ImplTraits, InferenceResult,
+ Interner, PolyFnSig, QuantifiedWhereClause, Substitution, TraitEnvironment, TraitRef, Ty,
+ TyDefId, ValueTyDefId,
};
use hir_expand::name::Name;
@@ -159,7 +159,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
#[salsa::invoke(crate::lower::generic_defaults_query)]
#[salsa::cycle(crate::lower::generic_defaults_recover)]
- fn generic_defaults(&self, def: GenericDefId) -> Arc<[Binders<GenericArg>]>;
+ fn generic_defaults(&self, def: GenericDefId) -> GenericDefaults;
#[salsa::invoke(InherentImpls::inherent_impls_in_crate_query)]
fn inherent_impls_in_crate(&self, krate: CrateId) -> Arc<InherentImpls>;
diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs
index 685aceb233..257d6c71fd 100644
--- a/crates/hir-ty/src/lib.rs
+++ b/crates/hir-ty/src/lib.rs
@@ -330,18 +330,15 @@ pub(crate) fn make_single_type_binders<T: HasInterner<Interner = Interner>>(
)
}
-pub(crate) fn make_binders_with_count<T: HasInterner<Interner = Interner>>(
+pub(crate) fn make_binders<T: HasInterner<Interner = Interner>>(
db: &dyn HirDatabase,
- count: usize,
generics: &Generics,
value: T,
) -> Binders<T> {
- let it = generics.iter_id().take(count);
-
Binders::new(
VariableKinds::from_iter(
Interner,
- it.map(|x| match x {
+ generics.iter_id().map(|x| match x {
hir_def::GenericParamId::ConstParamId(id) => {
chalk_ir::VariableKind::Const(db.const_param_ty(id))
}
@@ -355,14 +352,6 @@ pub(crate) fn make_binders_with_count<T: HasInterner<Interner = Interner>>(
)
}
-pub(crate) fn make_binders<T: HasInterner<Interner = Interner>>(
- db: &dyn HirDatabase,
- generics: &Generics,
- value: T,
-) -> Binders<T> {
- make_binders_with_count(db, usize::MAX, generics, value)
-}
-
// FIXME: get rid of this, just replace it by FnPointer
/// A function signature as seen by type inference: Several parameter types and
/// one return type.
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index 4942244396..ac2eae03e6 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -8,7 +8,7 @@
use std::{
cell::{Cell, RefCell, RefMut},
iter,
- ops::Not as _,
+ ops::{self, Not as _},
};
use base_db::{
@@ -1693,9 +1693,11 @@ pub(crate) fn trait_environment_query(
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct GenericPredicates(Option<Arc<[Binders<QuantifiedWhereClause>]>>);
-impl GenericPredicates {
- pub fn iter(&self) -> impl Iterator<Item = &Binders<QuantifiedWhereClause>> + '_ + Clone {
- self.0.as_ref().into_iter().flat_map(Arc::as_ref)
+impl ops::Deref for GenericPredicates {
+ type Target = [Binders<crate::QuantifiedWhereClause>];
+
+ fn deref(&self) -> &Self::Target {
+ self.0.as_deref().unwrap_or(&[])
}
}
@@ -1767,68 +1769,84 @@ fn implicitly_sized_clauses<'a, 'subst: 'a>(
})
}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct GenericDefaults(Option<Arc<[Binders<crate::GenericArg>]>>);
+
+impl ops::Deref for GenericDefaults {
+ type Target = [Binders<crate::GenericArg>];
+
+ fn deref(&self) -> &Self::Target {
+ self.0.as_deref().unwrap_or(&[])
+ }
+}
+
/// Resolve the default type params from generics
-pub(crate) fn generic_defaults_query(
- db: &dyn HirDatabase,
- def: GenericDefId,
-) -> Arc<[Binders<crate::GenericArg>]> {
- let resolver = def.resolver(db.upcast());
+pub(crate) fn generic_defaults_query(db: &dyn HirDatabase, def: GenericDefId) -> GenericDefaults {
let generic_params = generics(db.upcast(), def);
+ if generic_params.len() == 0 {
+ return GenericDefaults(None);
+ }
+ let resolver = def.resolver(db.upcast());
let parent_start_idx = generic_params.len_self();
let ctx = TyLoweringContext::new(db, &resolver, def.into())
.with_impl_trait_mode(ImplTraitLoweringMode::Disallowed)
.with_type_param_mode(ParamLoweringMode::Variable);
- Arc::from_iter(generic_params.iter().enumerate().map(|(idx, (id, p))| {
- match p {
- GenericParamDataRef::TypeParamData(p) => {
- let mut ty =
- p.default.as_ref().map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t));
- // Each default can only refer to previous parameters.
- // Type variable default referring to parameter coming
- // after it is forbidden (FIXME: report diagnostic)
- ty = fallback_bound_vars(ty, idx, parent_start_idx);
- crate::make_binders(db, &generic_params, ty.cast(Interner))
- }
- GenericParamDataRef::ConstParamData(p) => {
- let GenericParamId::ConstParamId(id) = id else {
- unreachable!("Unexpected lifetime or type argument")
- };
+ GenericDefaults(Some(Arc::from_iter(generic_params.iter().enumerate().map(
+ |(idx, (id, p))| {
+ match p {
+ GenericParamDataRef::TypeParamData(p) => {
+ let ty = p.default.as_ref().map_or(TyKind::Error.intern(Interner), |ty| {
+ // Each default can only refer to previous parameters.
+ // Type variable default referring to parameter coming
+ // after it is forbidden (FIXME: report diagnostic)
+ fallback_bound_vars(ctx.lower_ty(ty), idx, parent_start_idx)
+ });
+ crate::make_binders(db, &generic_params, ty.cast(Interner))
+ }
+ GenericParamDataRef::ConstParamData(p) => {
+ let GenericParamId::ConstParamId(id) = id else {
+ unreachable!("Unexpected lifetime or type argument")
+ };
- let mut val = p.default.as_ref().map_or_else(
- || unknown_const_as_generic(db.const_param_ty(id)),
- |c| {
- let c = ctx.lower_const(c, ctx.lower_ty(&p.ty));
- c.cast(Interner)
- },
- );
- // Each default can only refer to previous parameters, see above.
- val = fallback_bound_vars(val, idx, parent_start_idx);
- make_binders(db, &generic_params, val)
- }
- GenericParamDataRef::LifetimeParamData(_) => {
- make_binders(db, &generic_params, error_lifetime().cast(Interner))
+ let mut val = p.default.as_ref().map_or_else(
+ || unknown_const_as_generic(db.const_param_ty(id)),
+ |c| {
+ let c = ctx.lower_const(c, ctx.lower_ty(&p.ty));
+ c.cast(Interner)
+ },
+ );
+ // Each default can only refer to previous parameters, see above.
+ val = fallback_bound_vars(val, idx, parent_start_idx);
+ make_binders(db, &generic_params, val)
+ }
+ GenericParamDataRef::LifetimeParamData(_) => {
+ make_binders(db, &generic_params, error_lifetime().cast(Interner))
+ }
}
- }
- }))
+ },
+ ))))
}
pub(crate) fn generic_defaults_recover(
db: &dyn HirDatabase,
_cycle: &Cycle,
def: &GenericDefId,
-) -> Arc<[Binders<crate::GenericArg>]> {
+) -> GenericDefaults {
let generic_params = generics(db.upcast(), *def);
+ if generic_params.len() == 0 {
+ return GenericDefaults(None);
+ }
// FIXME: this code is not covered in tests.
// we still need one default per parameter
- Arc::from_iter(generic_params.iter_id().map(|id| {
+ GenericDefaults(Some(Arc::from_iter(generic_params.iter_id().map(|id| {
let val = match id {
GenericParamId::TypeParamId(_) => TyKind::Error.intern(Interner).cast(Interner),
GenericParamId::ConstParamId(id) => unknown_const_as_generic(db.const_param_ty(id)),
GenericParamId::LifetimeParamId(_) => error_lifetime().cast(Interner),
};
crate::make_binders(db, &generic_params, val)
- }))
+ }))))
}
fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {