Skip to content

Commit

Permalink
optimization and #[cfg] filtering for function generic params
Browse files Browse the repository at this point in the history
  • Loading branch information
max-heller committed Aug 5, 2023
1 parent 3205ed7 commit 50db877
Showing 1 changed file with 42 additions and 11 deletions.
53 changes: 42 additions & 11 deletions crates/hir-def/src/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,17 +159,47 @@ impl GenericParams {
let krate = def.module(db).krate;
let cfg_options = db.crate_graph();
let cfg_options = &cfg_options[krate].cfg_options;
let enabled_params = |params: &GenericParams, item_tree: &ItemTree| {

// Returns the generic parameters that are enabled under the current `#[cfg]` options
let enabled_params = |params: &Interned<GenericParams>, item_tree: &ItemTree| {
let enabled = |param| item_tree.attrs(db, krate, param).is_cfg_enabled(cfg_options);
Interned::new(GenericParams {
type_or_consts: (params.type_or_consts.iter())
.filter_map(|(idx, param)| enabled(idx.into()).then(|| param.clone()))
.collect(),
lifetimes: (params.lifetimes.iter())
.filter_map(|(idx, param)| enabled(idx.into()).then(|| param.clone()))
.collect(),
where_predicates: params.where_predicates.clone(),
})

// In the common case, no parameters will by disabled by `#[cfg]` attributes.
// Therefore, make a first pass to check if all parameters are enabled and, if so,
// clone the `Interned<GenericParams>` instead of recreating an identical copy.
let all_type_or_consts_enabled =
params.type_or_consts.iter().all(|(idx, _)| enabled(idx.into()));
let all_lifetimes_enabled = params.lifetimes.iter().all(|(idx, _)| enabled(idx.into()));

if all_type_or_consts_enabled && all_lifetimes_enabled {
params.clone()
} else {
Interned::new(GenericParams {
type_or_consts: all_type_or_consts_enabled
.then(|| params.type_or_consts.clone())
.unwrap_or_else(|| {
params
.type_or_consts
.iter()
.filter_map(|(idx, param)| {
enabled(idx.into()).then(|| param.clone())
})
.collect()
}),
lifetimes: all_lifetimes_enabled
.then(|| params.lifetimes.clone())
.unwrap_or_else(|| {
params
.lifetimes
.iter()
.filter_map(|(idx, param)| {
enabled(idx.into()).then(|| param.clone())
})
.collect()
}),
where_predicates: params.where_predicates.clone(),
})
}
};
macro_rules! id_to_generics {
($id:ident) => {{
Expand All @@ -186,7 +216,8 @@ impl GenericParams {
let tree = loc.id.item_tree(db);
let item = &tree[loc.id.value];

let mut generic_params = GenericParams::clone(&item.explicit_generic_params);
let enabled_params = enabled_params(&item.explicit_generic_params, &tree);
let mut generic_params = GenericParams::clone(&enabled_params);

let module = loc.container.module(db);
let func_data = db.function_data(id);
Expand Down

0 comments on commit 50db877

Please sign in to comment.