Skip to content

Commit e6f3399

Browse files
committed
Auto merge of #17151 - Veykril:fix-cfg-trait-params, r=Veykril
fix: Fix attributes on generic parameters colliding in item tree Fixes #16141
2 parents 4ff01a2 + bfe59bb commit e6f3399

File tree

11 files changed

+250
-212
lines changed

11 files changed

+250
-212
lines changed

crates/hir-def/src/data.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -698,24 +698,22 @@ impl<'a> AssocItemCollector<'a> {
698698
match item {
699699
AssocItem::Function(id) => {
700700
let item = &item_tree[id];
701-
702701
let def =
703702
FunctionLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db);
704703
self.items.push((item.name.clone(), def.into()));
705704
}
706-
AssocItem::Const(id) => {
707-
let item = &item_tree[id];
708-
let Some(name) = item.name.clone() else { return };
709-
let def = ConstLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db);
710-
self.items.push((name, def.into()));
711-
}
712705
AssocItem::TypeAlias(id) => {
713706
let item = &item_tree[id];
714-
715707
let def =
716708
TypeAliasLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db);
717709
self.items.push((item.name.clone(), def.into()));
718710
}
711+
AssocItem::Const(id) => {
712+
let item = &item_tree[id];
713+
let Some(name) = item.name.clone() else { return };
714+
let def = ConstLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db);
715+
self.items.push((name, def.into()));
716+
}
719717
AssocItem::MacroCall(call) => {
720718
let file_id = self.expander.current_file_id();
721719
let MacroCall { ast_id, expand_to, ctxt, ref path } = item_tree[call];

crates/hir-def/src/find_path.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,6 +1177,8 @@ pub mod fmt {
11771177
//- /main.rs crate:main deps:alloc,std
11781178
#![no_std]
11791179
1180+
extern crate alloc;
1181+
11801182
$0
11811183
11821184
//- /std.rs crate:std deps:alloc

crates/hir-def/src/generics.rs

Lines changed: 55 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use triomphe::Arc;
2020
use crate::{
2121
db::DefDatabase,
2222
expander::Expander,
23-
item_tree::{GenericsItemTreeNode, ItemTree},
23+
item_tree::{AttrOwner, FileItemTreeId, GenericModItem, GenericsItemTreeNode, ItemTree},
2424
lower::LowerCtx,
2525
nameres::{DefMap, MacroSubNs},
2626
type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRef},
@@ -456,56 +456,67 @@ impl GenericParams {
456456
let cfg_options = &cfg_options[krate].cfg_options;
457457

458458
// Returns the generic parameters that are enabled under the current `#[cfg]` options
459-
let enabled_params = |params: &Interned<GenericParams>, item_tree: &ItemTree| {
460-
let enabled = |param| item_tree.attrs(db, krate, param).is_cfg_enabled(cfg_options);
461-
462-
// In the common case, no parameters will by disabled by `#[cfg]` attributes.
463-
// Therefore, make a first pass to check if all parameters are enabled and, if so,
464-
// clone the `Interned<GenericParams>` instead of recreating an identical copy.
465-
let all_type_or_consts_enabled =
466-
params.type_or_consts.iter().all(|(idx, _)| enabled(idx.into()));
467-
let all_lifetimes_enabled = params.lifetimes.iter().all(|(idx, _)| enabled(idx.into()));
468-
469-
if all_type_or_consts_enabled && all_lifetimes_enabled {
470-
params.clone()
471-
} else {
472-
Interned::new(GenericParams {
473-
type_or_consts: all_type_or_consts_enabled
474-
.then(|| params.type_or_consts.clone())
475-
.unwrap_or_else(|| {
476-
params
477-
.type_or_consts
478-
.iter()
479-
.filter(|(idx, _)| enabled((*idx).into()))
480-
.map(|(_, param)| param.clone())
481-
.collect()
482-
}),
483-
lifetimes: all_lifetimes_enabled
484-
.then(|| params.lifetimes.clone())
485-
.unwrap_or_else(|| {
486-
params
487-
.lifetimes
488-
.iter()
489-
.filter(|(idx, _)| enabled((*idx).into()))
490-
.map(|(_, param)| param.clone())
491-
.collect()
492-
}),
493-
where_predicates: params.where_predicates.clone(),
494-
})
495-
}
496-
};
459+
let enabled_params =
460+
|params: &Interned<GenericParams>, item_tree: &ItemTree, parent: GenericModItem| {
461+
let enabled = |param| item_tree.attrs(db, krate, param).is_cfg_enabled(cfg_options);
462+
let attr_owner_ct = |param| AttrOwner::TypeOrConstParamData(parent, param);
463+
let attr_owner_lt = |param| AttrOwner::LifetimeParamData(parent, param);
464+
465+
// In the common case, no parameters will by disabled by `#[cfg]` attributes.
466+
// Therefore, make a first pass to check if all parameters are enabled and, if so,
467+
// clone the `Interned<GenericParams>` instead of recreating an identical copy.
468+
let all_type_or_consts_enabled =
469+
params.type_or_consts.iter().all(|(idx, _)| enabled(attr_owner_ct(idx)));
470+
let all_lifetimes_enabled =
471+
params.lifetimes.iter().all(|(idx, _)| enabled(attr_owner_lt(idx)));
472+
473+
if all_type_or_consts_enabled && all_lifetimes_enabled {
474+
params.clone()
475+
} else {
476+
Interned::new(GenericParams {
477+
type_or_consts: all_type_or_consts_enabled
478+
.then(|| params.type_or_consts.clone())
479+
.unwrap_or_else(|| {
480+
params
481+
.type_or_consts
482+
.iter()
483+
.filter(|&(idx, _)| enabled(attr_owner_ct(idx)))
484+
.map(|(_, param)| param.clone())
485+
.collect()
486+
}),
487+
lifetimes: all_lifetimes_enabled
488+
.then(|| params.lifetimes.clone())
489+
.unwrap_or_else(|| {
490+
params
491+
.lifetimes
492+
.iter()
493+
.filter(|&(idx, _)| enabled(attr_owner_lt(idx)))
494+
.map(|(_, param)| param.clone())
495+
.collect()
496+
}),
497+
where_predicates: params.where_predicates.clone(),
498+
})
499+
}
500+
};
497501
fn id_to_generics<Id: GenericsItemTreeNode>(
498502
db: &dyn DefDatabase,
499503
id: impl for<'db> Lookup<
500504
Database<'db> = dyn DefDatabase + 'db,
501505
Data = impl ItemTreeLoc<Id = Id>,
502506
>,
503-
enabled_params: impl Fn(&Interned<GenericParams>, &ItemTree) -> Interned<GenericParams>,
504-
) -> Interned<GenericParams> {
507+
enabled_params: impl Fn(
508+
&Interned<GenericParams>,
509+
&ItemTree,
510+
GenericModItem,
511+
) -> Interned<GenericParams>,
512+
) -> Interned<GenericParams>
513+
where
514+
FileItemTreeId<Id>: Into<GenericModItem>,
515+
{
505516
let id = id.lookup(db).item_tree_id();
506517
let tree = id.item_tree(db);
507518
let item = &tree[id.value];
508-
enabled_params(item.generic_params(), &tree)
519+
enabled_params(item.generic_params(), &tree, id.value.into())
509520
}
510521

511522
match def {
@@ -514,7 +525,8 @@ impl GenericParams {
514525
let tree = loc.id.item_tree(db);
515526
let item = &tree[loc.id.value];
516527

517-
let enabled_params = enabled_params(&item.explicit_generic_params, &tree);
528+
let enabled_params =
529+
enabled_params(&item.explicit_generic_params, &tree, loc.id.value.into());
518530

519531
let module = loc.container.module(db);
520532
let func_data = db.function_data(id);

crates/hir-def/src/item_tree.rs

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,11 @@ use triomphe::Arc;
5757
use crate::{
5858
attr::Attrs,
5959
db::DefDatabase,
60-
generics::{GenericParams, LifetimeParamData, TypeOrConstParamData},
60+
generics::GenericParams,
6161
path::{GenericArgs, ImportAlias, ModPath, Path, PathKind},
6262
type_ref::{Mutability, TraitRef, TypeBound, TypeRef},
6363
visibility::{RawVisibility, VisibilityExplicitness},
64-
BlockId, Lookup,
64+
BlockId, LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup,
6565
};
6666

6767
#[derive(Copy, Clone, Eq, PartialEq)]
@@ -293,8 +293,8 @@ pub enum AttrOwner {
293293
Variant(FileItemTreeId<Variant>),
294294
Field(Idx<Field>),
295295
Param(Idx<Param>),
296-
TypeOrConstParamData(Idx<TypeOrConstParamData>),
297-
LifetimeParamData(Idx<LifetimeParamData>),
296+
TypeOrConstParamData(GenericModItem, LocalTypeOrConstParamId),
297+
LifetimeParamData(GenericModItem, LocalLifetimeParamId),
298298
}
299299

300300
macro_rules! from_attrs {
@@ -314,8 +314,6 @@ from_attrs!(
314314
Variant(FileItemTreeId<Variant>),
315315
Field(Idx<Field>),
316316
Param(Idx<Param>),
317-
TypeOrConstParamData(Idx<TypeOrConstParamData>),
318-
LifetimeParamData(Idx<LifetimeParamData>),
319317
);
320318

321319
/// Trait implemented by all nodes in the item tree.
@@ -465,12 +463,49 @@ macro_rules! mod_items {
465463
)+
466464
}
467465

466+
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
467+
pub enum GenericModItem {
468+
$(
469+
$(
470+
#[cfg_attr(FALSE, $generic_params)]
471+
$typ(FileItemTreeId<$typ>),
472+
)?
473+
)+
474+
}
475+
476+
impl From<GenericModItem> for ModItem {
477+
fn from(id: GenericModItem) -> ModItem {
478+
match id {
479+
$(
480+
$(
481+
#[cfg_attr(FALSE, $generic_params)]
482+
GenericModItem::$typ(id) => ModItem::$typ(id),
483+
)?
484+
)+
485+
}
486+
}
487+
}
488+
489+
impl From<GenericModItem> for AttrOwner {
490+
fn from(t: GenericModItem) -> AttrOwner {
491+
AttrOwner::ModItem(t.into())
492+
}
493+
}
494+
468495
$(
469496
impl From<FileItemTreeId<$typ>> for ModItem {
470497
fn from(id: FileItemTreeId<$typ>) -> ModItem {
471498
ModItem::$typ(id)
472499
}
473500
}
501+
$(
502+
#[cfg_attr(FALSE, $generic_params)]
503+
impl From<FileItemTreeId<$typ>> for GenericModItem {
504+
fn from(id: FileItemTreeId<$typ>) -> GenericModItem {
505+
GenericModItem::$typ(id)
506+
}
507+
}
508+
)?
474509
)+
475510

476511
$(

0 commit comments

Comments
 (0)