Skip to content

Commit 54f3f56

Browse files
committed
Save allocations for empty generic_defaults query results
1 parent 2893153 commit 54f3f56

File tree

3 files changed

+67
-60
lines changed

3 files changed

+67
-60
lines changed

src/tools/rust-analyzer/crates/hir-ty/src/db.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ use crate::{
2121
chalk_db,
2222
consteval::ConstEvalError,
2323
layout::{Layout, LayoutError},
24-
lower::GenericPredicates,
24+
lower::{GenericDefaults, GenericPredicates},
2525
method_resolution::{InherentImpls, TraitImpls, TyFingerprint},
2626
mir::{BorrowckResult, MirBody, MirLowerError},
27-
Binders, CallableDefId, ClosureId, Const, FnDefId, GenericArg, ImplTraitId, ImplTraits,
28-
InferenceResult, Interner, PolyFnSig, QuantifiedWhereClause, Substitution, TraitEnvironment,
29-
TraitRef, Ty, TyDefId, ValueTyDefId,
27+
Binders, CallableDefId, ClosureId, Const, FnDefId, ImplTraitId, ImplTraits, InferenceResult,
28+
Interner, PolyFnSig, QuantifiedWhereClause, Substitution, TraitEnvironment, TraitRef, Ty,
29+
TyDefId, ValueTyDefId,
3030
};
3131
use hir_expand::name::Name;
3232

@@ -159,7 +159,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
159159

160160
#[salsa::invoke(crate::lower::generic_defaults_query)]
161161
#[salsa::cycle(crate::lower::generic_defaults_recover)]
162-
fn generic_defaults(&self, def: GenericDefId) -> Arc<[Binders<GenericArg>]>;
162+
fn generic_defaults(&self, def: GenericDefId) -> GenericDefaults;
163163

164164
#[salsa::invoke(InherentImpls::inherent_impls_in_crate_query)]
165165
fn inherent_impls_in_crate(&self, krate: CrateId) -> Arc<InherentImpls>;

src/tools/rust-analyzer/crates/hir-ty/src/lib.rs

+2-13
Original file line numberDiff line numberDiff line change
@@ -330,18 +330,15 @@ pub(crate) fn make_single_type_binders<T: HasInterner<Interner = Interner>>(
330330
)
331331
}
332332

333-
pub(crate) fn make_binders_with_count<T: HasInterner<Interner = Interner>>(
333+
pub(crate) fn make_binders<T: HasInterner<Interner = Interner>>(
334334
db: &dyn HirDatabase,
335-
count: usize,
336335
generics: &Generics,
337336
value: T,
338337
) -> Binders<T> {
339-
let it = generics.iter_id().take(count);
340-
341338
Binders::new(
342339
VariableKinds::from_iter(
343340
Interner,
344-
it.map(|x| match x {
341+
generics.iter_id().map(|x| match x {
345342
hir_def::GenericParamId::ConstParamId(id) => {
346343
chalk_ir::VariableKind::Const(db.const_param_ty(id))
347344
}
@@ -355,14 +352,6 @@ pub(crate) fn make_binders_with_count<T: HasInterner<Interner = Interner>>(
355352
)
356353
}
357354

358-
pub(crate) fn make_binders<T: HasInterner<Interner = Interner>>(
359-
db: &dyn HirDatabase,
360-
generics: &Generics,
361-
value: T,
362-
) -> Binders<T> {
363-
make_binders_with_count(db, usize::MAX, generics, value)
364-
}
365-
366355
// FIXME: get rid of this, just replace it by FnPointer
367356
/// A function signature as seen by type inference: Several parameter types and
368357
/// one return type.

src/tools/rust-analyzer/crates/hir-ty/src/lower.rs

+60-42
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use std::{
99
cell::{Cell, RefCell, RefMut},
1010
iter,
11-
ops::Not as _,
11+
ops::{self, Not as _},
1212
};
1313

1414
use base_db::{
@@ -1693,9 +1693,11 @@ pub(crate) fn trait_environment_query(
16931693
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
16941694
pub struct GenericPredicates(Option<Arc<[Binders<QuantifiedWhereClause>]>>);
16951695

1696-
impl GenericPredicates {
1697-
pub fn iter(&self) -> impl Iterator<Item = &Binders<QuantifiedWhereClause>> + '_ + Clone {
1698-
self.0.as_ref().into_iter().flat_map(Arc::as_ref)
1696+
impl ops::Deref for GenericPredicates {
1697+
type Target = [Binders<crate::QuantifiedWhereClause>];
1698+
1699+
fn deref(&self) -> &Self::Target {
1700+
self.0.as_deref().unwrap_or(&[])
16991701
}
17001702
}
17011703

@@ -1767,68 +1769,84 @@ fn implicitly_sized_clauses<'a, 'subst: 'a>(
17671769
})
17681770
}
17691771

1772+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1773+
pub struct GenericDefaults(Option<Arc<[Binders<crate::GenericArg>]>>);
1774+
1775+
impl ops::Deref for GenericDefaults {
1776+
type Target = [Binders<crate::GenericArg>];
1777+
1778+
fn deref(&self) -> &Self::Target {
1779+
self.0.as_deref().unwrap_or(&[])
1780+
}
1781+
}
1782+
17701783
/// Resolve the default type params from generics
1771-
pub(crate) fn generic_defaults_query(
1772-
db: &dyn HirDatabase,
1773-
def: GenericDefId,
1774-
) -> Arc<[Binders<crate::GenericArg>]> {
1775-
let resolver = def.resolver(db.upcast());
1784+
pub(crate) fn generic_defaults_query(db: &dyn HirDatabase, def: GenericDefId) -> GenericDefaults {
17761785
let generic_params = generics(db.upcast(), def);
1786+
if generic_params.len() == 0 {
1787+
return GenericDefaults(None);
1788+
}
1789+
let resolver = def.resolver(db.upcast());
17771790
let parent_start_idx = generic_params.len_self();
17781791

17791792
let ctx = TyLoweringContext::new(db, &resolver, def.into())
17801793
.with_impl_trait_mode(ImplTraitLoweringMode::Disallowed)
17811794
.with_type_param_mode(ParamLoweringMode::Variable);
1782-
Arc::from_iter(generic_params.iter().enumerate().map(|(idx, (id, p))| {
1783-
match p {
1784-
GenericParamDataRef::TypeParamData(p) => {
1785-
let mut ty =
1786-
p.default.as_ref().map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t));
1787-
// Each default can only refer to previous parameters.
1788-
// Type variable default referring to parameter coming
1789-
// after it is forbidden (FIXME: report diagnostic)
1790-
ty = fallback_bound_vars(ty, idx, parent_start_idx);
1791-
crate::make_binders(db, &generic_params, ty.cast(Interner))
1792-
}
1793-
GenericParamDataRef::ConstParamData(p) => {
1794-
let GenericParamId::ConstParamId(id) = id else {
1795-
unreachable!("Unexpected lifetime or type argument")
1796-
};
1795+
GenericDefaults(Some(Arc::from_iter(generic_params.iter().enumerate().map(
1796+
|(idx, (id, p))| {
1797+
match p {
1798+
GenericParamDataRef::TypeParamData(p) => {
1799+
let ty = p.default.as_ref().map_or(TyKind::Error.intern(Interner), |ty| {
1800+
// Each default can only refer to previous parameters.
1801+
// Type variable default referring to parameter coming
1802+
// after it is forbidden (FIXME: report diagnostic)
1803+
fallback_bound_vars(ctx.lower_ty(ty), idx, parent_start_idx)
1804+
});
1805+
crate::make_binders(db, &generic_params, ty.cast(Interner))
1806+
}
1807+
GenericParamDataRef::ConstParamData(p) => {
1808+
let GenericParamId::ConstParamId(id) = id else {
1809+
unreachable!("Unexpected lifetime or type argument")
1810+
};
17971811

1798-
let mut val = p.default.as_ref().map_or_else(
1799-
|| unknown_const_as_generic(db.const_param_ty(id)),
1800-
|c| {
1801-
let c = ctx.lower_const(c, ctx.lower_ty(&p.ty));
1802-
c.cast(Interner)
1803-
},
1804-
);
1805-
// Each default can only refer to previous parameters, see above.
1806-
val = fallback_bound_vars(val, idx, parent_start_idx);
1807-
make_binders(db, &generic_params, val)
1808-
}
1809-
GenericParamDataRef::LifetimeParamData(_) => {
1810-
make_binders(db, &generic_params, error_lifetime().cast(Interner))
1812+
let mut val = p.default.as_ref().map_or_else(
1813+
|| unknown_const_as_generic(db.const_param_ty(id)),
1814+
|c| {
1815+
let c = ctx.lower_const(c, ctx.lower_ty(&p.ty));
1816+
c.cast(Interner)
1817+
},
1818+
);
1819+
// Each default can only refer to previous parameters, see above.
1820+
val = fallback_bound_vars(val, idx, parent_start_idx);
1821+
make_binders(db, &generic_params, val)
1822+
}
1823+
GenericParamDataRef::LifetimeParamData(_) => {
1824+
make_binders(db, &generic_params, error_lifetime().cast(Interner))
1825+
}
18111826
}
1812-
}
1813-
}))
1827+
},
1828+
))))
18141829
}
18151830

18161831
pub(crate) fn generic_defaults_recover(
18171832
db: &dyn HirDatabase,
18181833
_cycle: &Cycle,
18191834
def: &GenericDefId,
1820-
) -> Arc<[Binders<crate::GenericArg>]> {
1835+
) -> GenericDefaults {
18211836
let generic_params = generics(db.upcast(), *def);
1837+
if generic_params.len() == 0 {
1838+
return GenericDefaults(None);
1839+
}
18221840
// FIXME: this code is not covered in tests.
18231841
// we still need one default per parameter
1824-
Arc::from_iter(generic_params.iter_id().map(|id| {
1842+
GenericDefaults(Some(Arc::from_iter(generic_params.iter_id().map(|id| {
18251843
let val = match id {
18261844
GenericParamId::TypeParamId(_) => TyKind::Error.intern(Interner).cast(Interner),
18271845
GenericParamId::ConstParamId(id) => unknown_const_as_generic(db.const_param_ty(id)),
18281846
GenericParamId::LifetimeParamId(_) => error_lifetime().cast(Interner),
18291847
};
18301848
crate::make_binders(db, &generic_params, val)
1831-
}))
1849+
}))))
18321850
}
18331851

18341852
fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {

0 commit comments

Comments
 (0)