Skip to content

Commit ae6e737

Browse files
committed
Auto merge of rust-lang#16329 - Veykril:perfperf, r=Veykril
internal: Some minor perf/memory improvements
2 parents 51ac6de + f8b130a commit ae6e737

File tree

16 files changed

+315
-267
lines changed

16 files changed

+315
-267
lines changed

crates/base-db/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ pub trait Upcast<T: ?Sized> {
4444
}
4545

4646
pub const DEFAULT_PARSE_LRU_CAP: usize = 128;
47+
pub const DEFAULT_BORROWCK_LRU_CAP: usize = 256;
4748

4849
pub trait FileLoader {
4950
/// Text of the file.

crates/hir-def/src/attr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ fn parse_comma_sep<S>(subtree: &tt::Subtree<S>) -> Vec<SmolStr> {
355355
}
356356

357357
impl AttrsWithOwner {
358-
pub(crate) fn attrs_with_owner(db: &dyn DefDatabase, owner: AttrDefId) -> Self {
358+
pub fn attrs_with_owner(db: &dyn DefDatabase, owner: AttrDefId) -> Self {
359359
Self { attrs: db.attrs(owner), owner }
360360
}
361361

crates/hir-def/src/db.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -210,13 +210,10 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast<dyn ExpandDataba
210210
#[salsa::invoke(AttrsWithOwner::attrs_query)]
211211
fn attrs(&self, def: AttrDefId) -> Attrs;
212212

213+
#[salsa::transparent]
213214
#[salsa::invoke(lang_item::lang_attr_query)]
214215
fn lang_attr(&self, def: AttrDefId) -> Option<LangItem>;
215216

216-
#[salsa::transparent]
217-
#[salsa::invoke(AttrsWithOwner::attrs_with_owner)]
218-
fn attrs_with_owner(&self, def: AttrDefId) -> AttrsWithOwner;
219-
220217
// endregion:attrs
221218

222219
#[salsa::invoke(LangItems::lang_item_query)]
@@ -240,7 +237,7 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast<dyn ExpandDataba
240237
// endregion:visibilities
241238

242239
#[salsa::invoke(LangItems::crate_lang_items_query)]
243-
fn crate_lang_items(&self, krate: CrateId) -> Arc<LangItems>;
240+
fn crate_lang_items(&self, krate: CrateId) -> Option<Arc<LangItems>>;
244241

245242
fn crate_supports_no_std(&self, crate_id: CrateId) -> bool;
246243
}

crates/hir-def/src/generics.rs

+133-108
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,11 @@ impl TypeOrConstParamData {
107107
impl_from!(TypeParamData, ConstParamData for TypeOrConstParamData);
108108

109109
/// Data about the generic parameters of a function, struct, impl, etc.
110-
#[derive(Clone, PartialEq, Eq, Debug, Default, Hash)]
110+
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
111111
pub struct GenericParams {
112112
pub type_or_consts: Arena<TypeOrConstParamData>,
113113
pub lifetimes: Arena<LifetimeParamData>,
114-
pub where_predicates: Vec<WherePredicate>,
114+
pub where_predicates: Box<[WherePredicate]>,
115115
}
116116

117117
/// A single predicate from a where clause, i.e. `where Type: Trait`. Combined
@@ -142,109 +142,14 @@ pub enum WherePredicateTypeTarget {
142142
TypeOrConstParam(LocalTypeOrConstParamId),
143143
}
144144

145-
impl GenericParams {
146-
/// Iterator of type_or_consts field
147-
pub fn iter(
148-
&self,
149-
) -> impl DoubleEndedIterator<Item = (Idx<TypeOrConstParamData>, &TypeOrConstParamData)> {
150-
self.type_or_consts.iter()
151-
}
152-
153-
pub(crate) fn generic_params_query(
154-
db: &dyn DefDatabase,
155-
def: GenericDefId,
156-
) -> Interned<GenericParams> {
157-
let _p = profile::span("generic_params_query");
158-
159-
let krate = def.module(db).krate;
160-
let cfg_options = db.crate_graph();
161-
let cfg_options = &cfg_options[krate].cfg_options;
162-
163-
// Returns the generic parameters that are enabled under the current `#[cfg]` options
164-
let enabled_params = |params: &Interned<GenericParams>, item_tree: &ItemTree| {
165-
let enabled = |param| item_tree.attrs(db, krate, param).is_cfg_enabled(cfg_options);
166-
167-
// In the common case, no parameters will by disabled by `#[cfg]` attributes.
168-
// Therefore, make a first pass to check if all parameters are enabled and, if so,
169-
// clone the `Interned<GenericParams>` instead of recreating an identical copy.
170-
let all_type_or_consts_enabled =
171-
params.type_or_consts.iter().all(|(idx, _)| enabled(idx.into()));
172-
let all_lifetimes_enabled = params.lifetimes.iter().all(|(idx, _)| enabled(idx.into()));
173-
174-
if all_type_or_consts_enabled && all_lifetimes_enabled {
175-
params.clone()
176-
} else {
177-
Interned::new(GenericParams {
178-
type_or_consts: all_type_or_consts_enabled
179-
.then(|| params.type_or_consts.clone())
180-
.unwrap_or_else(|| {
181-
params
182-
.type_or_consts
183-
.iter()
184-
.filter_map(|(idx, param)| {
185-
enabled(idx.into()).then(|| param.clone())
186-
})
187-
.collect()
188-
}),
189-
lifetimes: all_lifetimes_enabled
190-
.then(|| params.lifetimes.clone())
191-
.unwrap_or_else(|| {
192-
params
193-
.lifetimes
194-
.iter()
195-
.filter_map(|(idx, param)| {
196-
enabled(idx.into()).then(|| param.clone())
197-
})
198-
.collect()
199-
}),
200-
where_predicates: params.where_predicates.clone(),
201-
})
202-
}
203-
};
204-
macro_rules! id_to_generics {
205-
($id:ident) => {{
206-
let id = $id.lookup(db).id;
207-
let tree = id.item_tree(db);
208-
let item = &tree[id.value];
209-
enabled_params(&item.generic_params, &tree)
210-
}};
211-
}
212-
213-
match def {
214-
GenericDefId::FunctionId(id) => {
215-
let loc = id.lookup(db);
216-
let tree = loc.id.item_tree(db);
217-
let item = &tree[loc.id.value];
218-
219-
let enabled_params = enabled_params(&item.explicit_generic_params, &tree);
220-
let mut generic_params = GenericParams::clone(&enabled_params);
221-
222-
let module = loc.container.module(db);
223-
let func_data = db.function_data(id);
224-
225-
// Don't create an `Expander` if not needed since this
226-
// could cause a reparse after the `ItemTree` has been created due to the spanmap.
227-
let mut expander =
228-
Lazy::new(|| (module.def_map(db), Expander::new(db, loc.id.file_id(), module)));
229-
for param in func_data.params.iter() {
230-
generic_params.fill_implicit_impl_trait_args(db, &mut expander, param);
231-
}
232-
233-
Interned::new(generic_params)
234-
}
235-
GenericDefId::AdtId(AdtId::StructId(id)) => id_to_generics!(id),
236-
GenericDefId::AdtId(AdtId::EnumId(id)) => id_to_generics!(id),
237-
GenericDefId::AdtId(AdtId::UnionId(id)) => id_to_generics!(id),
238-
GenericDefId::TraitId(id) => id_to_generics!(id),
239-
GenericDefId::TraitAliasId(id) => id_to_generics!(id),
240-
GenericDefId::TypeAliasId(id) => id_to_generics!(id),
241-
GenericDefId::ImplId(id) => id_to_generics!(id),
242-
GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {
243-
Interned::new(GenericParams::default())
244-
}
245-
}
246-
}
145+
#[derive(Clone, Default)]
146+
pub(crate) struct GenericParamsCollector {
147+
pub(crate) type_or_consts: Arena<TypeOrConstParamData>,
148+
lifetimes: Arena<LifetimeParamData>,
149+
where_predicates: Vec<WherePredicate>,
150+
}
247151

152+
impl GenericParamsCollector {
248153
pub(crate) fn fill(
249154
&mut self,
250155
lower_ctx: &LowerCtx<'_>,
@@ -444,11 +349,131 @@ impl GenericParams {
444349
});
445350
}
446351

447-
pub(crate) fn shrink_to_fit(&mut self) {
448-
let Self { lifetimes, type_or_consts: types, where_predicates } = self;
352+
pub(crate) fn finish(self) -> GenericParams {
353+
let Self { mut lifetimes, mut type_or_consts, where_predicates } = self;
449354
lifetimes.shrink_to_fit();
450-
types.shrink_to_fit();
451-
where_predicates.shrink_to_fit();
355+
type_or_consts.shrink_to_fit();
356+
GenericParams {
357+
type_or_consts,
358+
lifetimes,
359+
where_predicates: where_predicates.into_boxed_slice(),
360+
}
361+
}
362+
}
363+
364+
impl GenericParams {
365+
/// Iterator of type_or_consts field
366+
pub fn iter(
367+
&self,
368+
) -> impl DoubleEndedIterator<Item = (Idx<TypeOrConstParamData>, &TypeOrConstParamData)> {
369+
self.type_or_consts.iter()
370+
}
371+
372+
pub(crate) fn generic_params_query(
373+
db: &dyn DefDatabase,
374+
def: GenericDefId,
375+
) -> Interned<GenericParams> {
376+
let _p = profile::span("generic_params_query");
377+
378+
let krate = def.module(db).krate;
379+
let cfg_options = db.crate_graph();
380+
let cfg_options = &cfg_options[krate].cfg_options;
381+
382+
// Returns the generic parameters that are enabled under the current `#[cfg]` options
383+
let enabled_params = |params: &Interned<GenericParams>, item_tree: &ItemTree| {
384+
let enabled = |param| item_tree.attrs(db, krate, param).is_cfg_enabled(cfg_options);
385+
386+
// In the common case, no parameters will by disabled by `#[cfg]` attributes.
387+
// Therefore, make a first pass to check if all parameters are enabled and, if so,
388+
// clone the `Interned<GenericParams>` instead of recreating an identical copy.
389+
let all_type_or_consts_enabled =
390+
params.type_or_consts.iter().all(|(idx, _)| enabled(idx.into()));
391+
let all_lifetimes_enabled = params.lifetimes.iter().all(|(idx, _)| enabled(idx.into()));
392+
393+
if all_type_or_consts_enabled && all_lifetimes_enabled {
394+
params.clone()
395+
} else {
396+
Interned::new(GenericParams {
397+
type_or_consts: all_type_or_consts_enabled
398+
.then(|| params.type_or_consts.clone())
399+
.unwrap_or_else(|| {
400+
params
401+
.type_or_consts
402+
.iter()
403+
.filter_map(|(idx, param)| {
404+
enabled(idx.into()).then(|| param.clone())
405+
})
406+
.collect()
407+
}),
408+
lifetimes: all_lifetimes_enabled
409+
.then(|| params.lifetimes.clone())
410+
.unwrap_or_else(|| {
411+
params
412+
.lifetimes
413+
.iter()
414+
.filter_map(|(idx, param)| {
415+
enabled(idx.into()).then(|| param.clone())
416+
})
417+
.collect()
418+
}),
419+
where_predicates: params.where_predicates.clone(),
420+
})
421+
}
422+
};
423+
macro_rules! id_to_generics {
424+
($id:ident) => {{
425+
let id = $id.lookup(db).id;
426+
let tree = id.item_tree(db);
427+
let item = &tree[id.value];
428+
enabled_params(&item.generic_params, &tree)
429+
}};
430+
}
431+
432+
match def {
433+
GenericDefId::FunctionId(id) => {
434+
let loc = id.lookup(db);
435+
let tree = loc.id.item_tree(db);
436+
let item = &tree[loc.id.value];
437+
438+
let enabled_params = enabled_params(&item.explicit_generic_params, &tree);
439+
440+
let module = loc.container.module(db);
441+
let func_data = db.function_data(id);
442+
if func_data.params.is_empty() {
443+
enabled_params
444+
} else {
445+
let mut generic_params = GenericParamsCollector {
446+
type_or_consts: enabled_params.type_or_consts.clone(),
447+
lifetimes: enabled_params.lifetimes.clone(),
448+
where_predicates: enabled_params.where_predicates.clone().into(),
449+
};
450+
451+
// Don't create an `Expander` if not needed since this
452+
// could cause a reparse after the `ItemTree` has been created due to the spanmap.
453+
let mut expander = Lazy::new(|| {
454+
(module.def_map(db), Expander::new(db, loc.id.file_id(), module))
455+
});
456+
for param in func_data.params.iter() {
457+
generic_params.fill_implicit_impl_trait_args(db, &mut expander, param);
458+
}
459+
Interned::new(generic_params.finish())
460+
}
461+
}
462+
GenericDefId::AdtId(AdtId::StructId(id)) => id_to_generics!(id),
463+
GenericDefId::AdtId(AdtId::EnumId(id)) => id_to_generics!(id),
464+
GenericDefId::AdtId(AdtId::UnionId(id)) => id_to_generics!(id),
465+
GenericDefId::TraitId(id) => id_to_generics!(id),
466+
GenericDefId::TraitAliasId(id) => id_to_generics!(id),
467+
GenericDefId::TypeAliasId(id) => id_to_generics!(id),
468+
GenericDefId::ImplId(id) => id_to_generics!(id),
469+
GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {
470+
Interned::new(GenericParams {
471+
type_or_consts: Default::default(),
472+
lifetimes: Default::default(),
473+
where_predicates: Default::default(),
474+
})
475+
}
476+
}
452477
}
453478

454479
pub fn find_type_by_name(&self, name: &Name, parent: GenericDefId) -> Option<TypeParamId> {

crates/hir-def/src/hir/type_ref.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,7 @@ pub enum TypeRef {
116116
Path(Path),
117117
RawPtr(Box<TypeRef>, Mutability),
118118
Reference(Box<TypeRef>, Option<LifetimeRef>, Mutability),
119-
// FIXME: for full const generics, the latter element (length) here is going to have to be an
120-
// expression that is further lowered later in hir_ty.
119+
// FIXME: This should be Array(Box<TypeRef>, Ast<ConstArg>),
121120
Array(Box<TypeRef>, ConstRef),
122121
Slice(Box<TypeRef>),
123122
/// A fn pointer. Last element of the vector is the return type.

crates/hir-def/src/item_tree/lower.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use hir_expand::{ast_id_map::AstIdMap, span_map::SpanMapRef, HirFileId};
66
use syntax::ast::{self, HasModuleItem, HasTypeBounds};
77

88
use crate::{
9-
generics::{GenericParams, TypeParamData, TypeParamProvenance},
9+
generics::{GenericParams, GenericParamsCollector, TypeParamData, TypeParamProvenance},
1010
type_ref::{LifetimeRef, TraitBoundModifier, TraitRef},
1111
LocalLifetimeParamId, LocalTypeOrConstParamId,
1212
};
@@ -386,17 +386,16 @@ impl<'a> Ctx<'a> {
386386
flags |= FnFlags::HAS_UNSAFE_KW;
387387
}
388388

389-
let mut res = Function {
389+
let res = Function {
390390
name,
391391
visibility,
392-
explicit_generic_params: Interned::new(GenericParams::default()),
392+
explicit_generic_params: self.lower_generic_params(HasImplicitSelf::No, func),
393393
abi,
394394
params,
395395
ret_type: Interned::new(ret_type),
396396
ast_id,
397397
flags,
398398
};
399-
res.explicit_generic_params = self.lower_generic_params(HasImplicitSelf::No, func);
400399

401400
Some(id(self.data().functions.alloc(res)))
402401
}
@@ -604,7 +603,7 @@ impl<'a> Ctx<'a> {
604603
has_implicit_self: HasImplicitSelf,
605604
node: &dyn ast::HasGenericParams,
606605
) -> Interned<GenericParams> {
607-
let mut generics = GenericParams::default();
606+
let mut generics = GenericParamsCollector::default();
608607

609608
if let HasImplicitSelf::Yes(bounds) = has_implicit_self {
610609
// Traits and trait aliases get the Self type as an implicit first type parameter.
@@ -642,8 +641,7 @@ impl<'a> Ctx<'a> {
642641
};
643642
generics.fill(&self.body_ctx, node, add_param_attrs);
644643

645-
generics.shrink_to_fit();
646-
Interned::new(generics)
644+
Interned::new(generics.finish())
647645
}
648646

649647
fn lower_type_bounds(&mut self, node: &dyn ast::HasTypeBounds) -> Box<[Interned<TypeBound>]> {

0 commit comments

Comments
 (0)