Skip to content

Commit 6756294

Browse files
committed
Auto merge of #14184 - lowr:feat/trait-alias-def, r=Veykril
Handle trait alias definitions Part of #2773 This PR adds a bunch of structs and enum variants for trait aliases. Trait aliases should be handled as an independent item because they are semantically distinct from traits. I basically started by adding `TraitAlias{Id, Loc}` to `hir_def::item_tree` and iterated adding necessary stuffs until compiler stopped complaining what's missing. Let me know if there's still anything I need to add. I'm opening up this PR for early review and stuff. I'm planning to add tests for IDE functionalities in this PR, but not type-related support, for which I put FIXME notes.
2 parents a8d3c46 + f8eac19 commit 6756294

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+623
-206
lines changed

crates/hir-def/src/attr.rs

+12-36
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ impl AttrsWithOwner {
300300
AdtId::UnionId(it) => attrs_from_item_tree(it.lookup(db).id, db),
301301
},
302302
AttrDefId::TraitId(it) => attrs_from_item_tree(it.lookup(db).id, db),
303+
AttrDefId::TraitAliasId(it) => attrs_from_item_tree(it.lookup(db).id, db),
303304
AttrDefId::MacroId(it) => match it {
304305
MacroId::Macro2Id(it) => attrs_from_item_tree(it.lookup(db).id, db),
305306
MacroId::MacroRulesId(it) => attrs_from_item_tree(it.lookup(db).id, db),
@@ -315,26 +316,14 @@ impl AttrsWithOwner {
315316
let src = it.parent().child_source(db);
316317
RawAttrs::from_attrs_owner(
317318
db.upcast(),
318-
src.with_value(src.value[it.local_id()].as_ref().either(
319-
|it| match it {
320-
ast::TypeOrConstParam::Type(it) => it as _,
321-
ast::TypeOrConstParam::Const(it) => it as _,
322-
},
323-
|it| it as _,
324-
)),
319+
src.with_value(&src.value[it.local_id()]),
325320
)
326321
}
327322
GenericParamId::TypeParamId(it) => {
328323
let src = it.parent().child_source(db);
329324
RawAttrs::from_attrs_owner(
330325
db.upcast(),
331-
src.with_value(src.value[it.local_id()].as_ref().either(
332-
|it| match it {
333-
ast::TypeOrConstParam::Type(it) => it as _,
334-
ast::TypeOrConstParam::Const(it) => it as _,
335-
},
336-
|it| it as _,
337-
)),
326+
src.with_value(&src.value[it.local_id()]),
338327
)
339328
}
340329
GenericParamId::LifetimeParamId(it) => {
@@ -404,6 +393,7 @@ impl AttrsWithOwner {
404393
AttrDefId::StaticId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
405394
AttrDefId::ConstId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
406395
AttrDefId::TraitId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
396+
AttrDefId::TraitAliasId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
407397
AttrDefId::TypeAliasId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
408398
AttrDefId::MacroId(id) => match id {
409399
MacroId::Macro2Id(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
@@ -412,28 +402,14 @@ impl AttrsWithOwner {
412402
},
413403
AttrDefId::ImplId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
414404
AttrDefId::GenericParamId(id) => match id {
415-
GenericParamId::ConstParamId(id) => {
416-
id.parent().child_source(db).map(|source| match &source[id.local_id()] {
417-
Either::Left(ast::TypeOrConstParam::Type(id)) => {
418-
ast::AnyHasAttrs::new(id.clone())
419-
}
420-
Either::Left(ast::TypeOrConstParam::Const(id)) => {
421-
ast::AnyHasAttrs::new(id.clone())
422-
}
423-
Either::Right(id) => ast::AnyHasAttrs::new(id.clone()),
424-
})
425-
}
426-
GenericParamId::TypeParamId(id) => {
427-
id.parent().child_source(db).map(|source| match &source[id.local_id()] {
428-
Either::Left(ast::TypeOrConstParam::Type(id)) => {
429-
ast::AnyHasAttrs::new(id.clone())
430-
}
431-
Either::Left(ast::TypeOrConstParam::Const(id)) => {
432-
ast::AnyHasAttrs::new(id.clone())
433-
}
434-
Either::Right(id) => ast::AnyHasAttrs::new(id.clone()),
435-
})
436-
}
405+
GenericParamId::ConstParamId(id) => id
406+
.parent()
407+
.child_source(db)
408+
.map(|source| ast::AnyHasAttrs::new(source[id.local_id()].clone())),
409+
GenericParamId::TypeParamId(id) => id
410+
.parent()
411+
.child_source(db)
412+
.map(|source| ast::AnyHasAttrs::new(source[id.local_id()].clone())),
437413
GenericParamId::LifetimeParamId(id) => id
438414
.parent
439415
.child_source(db)

crates/hir-def/src/child_by_source.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! When *constructing* `hir`, we start at some parent syntax node and recursively
22
//! lower the children.
33
//!
4-
//! This modules allows one to go in the opposite direction: start with a syntax
4+
//! This module allows one to go in the opposite direction: start with a syntax
55
//! node for a *child*, and get its hir.
66
77
use either::Either;
@@ -145,6 +145,7 @@ impl ChildBySource for ItemScope {
145145
ModuleDefId::StaticId(id) => insert!(map[keys::STATIC].insert(id)),
146146
ModuleDefId::TypeAliasId(id) => insert!(map[keys::TYPE_ALIAS].insert(id)),
147147
ModuleDefId::TraitId(id) => insert!(map[keys::TRAIT].insert(id)),
148+
ModuleDefId::TraitAliasId(id) => insert!(map[keys::TRAIT_ALIAS].insert(id)),
148149
ModuleDefId::AdtId(adt) => match adt {
149150
AdtId::StructId(id) => insert!(map[keys::STRUCT].insert(id)),
150151
AdtId::UnionId(id) => insert!(map[keys::UNION].insert(id)),

crates/hir-def/src/data.rs

+23-14
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::{
2222
visibility::RawVisibility,
2323
AssocItemId, AstIdWithPath, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId,
2424
Intern, ItemContainerId, ItemLoc, Lookup, Macro2Id, MacroRulesId, ModuleId, ProcMacroId,
25-
StaticId, TraitId, TypeAliasId, TypeAliasLoc,
25+
StaticId, TraitAliasId, TraitId, TypeAliasId, TypeAliasLoc,
2626
};
2727

2828
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -245,19 +245,11 @@ impl TraitData {
245245
attrs.by_key("rustc_skip_array_during_method_dispatch").exists();
246246
let rustc_has_incoherent_inherent_impls =
247247
attrs.by_key("rustc_has_incoherent_inherent_impls").exists();
248-
let (items, attribute_calls, diagnostics) = match &tr_def.items {
249-
Some(items) => {
250-
let mut collector = AssocItemCollector::new(
251-
db,
252-
module_id,
253-
tree_id.file_id(),
254-
ItemContainerId::TraitId(tr),
255-
);
256-
collector.collect(&item_tree, tree_id.tree_id(), items);
257-
collector.finish()
258-
}
259-
None => Default::default(),
260-
};
248+
let mut collector =
249+
AssocItemCollector::new(db, module_id, tree_id.file_id(), ItemContainerId::TraitId(tr));
250+
collector.collect(&item_tree, tree_id.tree_id(), &tr_def.items);
251+
let (items, attribute_calls, diagnostics) = collector.finish();
252+
261253
(
262254
Arc::new(TraitData {
263255
name,
@@ -299,6 +291,23 @@ impl TraitData {
299291
}
300292
}
301293

294+
#[derive(Debug, Clone, PartialEq, Eq)]
295+
pub struct TraitAliasData {
296+
pub name: Name,
297+
pub visibility: RawVisibility,
298+
}
299+
300+
impl TraitAliasData {
301+
pub(crate) fn trait_alias_query(db: &dyn DefDatabase, id: TraitAliasId) -> Arc<TraitAliasData> {
302+
let loc = id.lookup(db);
303+
let item_tree = loc.id.item_tree(db);
304+
let alias = &item_tree[loc.id.value];
305+
let visibility = item_tree[alias.visibility].clone();
306+
307+
Arc::new(TraitAliasData { name: alias.name.clone(), visibility })
308+
}
309+
}
310+
302311
#[derive(Debug, Clone, PartialEq, Eq)]
303312
pub struct ImplData {
304313
pub target_trait: Option<Interned<TraitRef>>,

crates/hir-def/src/db.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414
body::{scope::ExprScopes, Body, BodySourceMap},
1515
data::{
1616
ConstData, FunctionData, ImplData, Macro2Data, MacroRulesData, ProcMacroData, StaticData,
17-
TraitData, TypeAliasData,
17+
TraitAliasData, TraitData, TypeAliasData,
1818
},
1919
generics::GenericParams,
2020
import_map::ImportMap,
@@ -25,8 +25,8 @@ use crate::{
2525
AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, ExternBlockId,
2626
ExternBlockLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalEnumVariantId,
2727
LocalFieldId, Macro2Id, Macro2Loc, MacroRulesId, MacroRulesLoc, ProcMacroId, ProcMacroLoc,
28-
StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc,
29-
UnionId, UnionLoc, VariantId,
28+
StaticId, StaticLoc, StructId, StructLoc, TraitAliasId, TraitAliasLoc, TraitId, TraitLoc,
29+
TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, VariantId,
3030
};
3131

3232
#[salsa::query_group(InternDatabaseStorage)]
@@ -46,6 +46,8 @@ pub trait InternDatabase: SourceDatabase {
4646
#[salsa::interned]
4747
fn intern_trait(&self, loc: TraitLoc) -> TraitId;
4848
#[salsa::interned]
49+
fn intern_trait_alias(&self, loc: TraitAliasLoc) -> TraitAliasId;
50+
#[salsa::interned]
4951
fn intern_type_alias(&self, loc: TypeAliasLoc) -> TypeAliasId;
5052
#[salsa::interned]
5153
fn intern_impl(&self, loc: ImplLoc) -> ImplId;
@@ -125,6 +127,9 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
125127
#[salsa::invoke(TraitData::trait_data_with_diagnostics_query)]
126128
fn trait_data_with_diagnostics(&self, tr: TraitId) -> (Arc<TraitData>, Arc<[DefDiagnostic]>);
127129

130+
#[salsa::invoke(TraitAliasData::trait_alias_query)]
131+
fn trait_alias_data(&self, e: TraitAliasId) -> Arc<TraitAliasData>;
132+
128133
#[salsa::invoke(TypeAliasData::type_alias_data_query)]
129134
fn type_alias_data(&self, e: TypeAliasId) -> Arc<TypeAliasData>;
130135

crates/hir-def/src/generics.rs

+32-12
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ impl GenericParams {
187187
GenericDefId::AdtId(AdtId::EnumId(id)) => id_to_generics!(id),
188188
GenericDefId::AdtId(AdtId::UnionId(id)) => id_to_generics!(id),
189189
GenericDefId::TraitId(id) => id_to_generics!(id),
190+
GenericDefId::TraitAliasId(id) => id_to_generics!(id),
190191
GenericDefId::TypeAliasId(id) => id_to_generics!(id),
191192
GenericDefId::ImplId(id) => id_to_generics!(id),
192193
GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {
@@ -207,12 +208,10 @@ impl GenericParams {
207208
pub(crate) fn fill_bounds(
208209
&mut self,
209210
lower_ctx: &LowerCtx<'_>,
210-
node: &dyn ast::HasTypeBounds,
211+
type_bounds: Option<ast::TypeBoundList>,
211212
target: Either<TypeRef, LifetimeRef>,
212213
) {
213-
for bound in
214-
node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds())
215-
{
214+
for bound in type_bounds.iter().flat_map(|type_bound_list| type_bound_list.bounds()) {
216215
self.add_where_predicate_from_bound(lower_ctx, bound, None, target.clone());
217216
}
218217
}
@@ -233,7 +232,11 @@ impl GenericParams {
233232
};
234233
self.type_or_consts.alloc(param.into());
235234
let type_ref = TypeRef::Path(name.into());
236-
self.fill_bounds(lower_ctx, &type_param, Either::Left(type_ref));
235+
self.fill_bounds(
236+
lower_ctx,
237+
type_param.type_bound_list(),
238+
Either::Left(type_ref),
239+
);
237240
}
238241
ast::TypeOrConstParam::Const(const_param) => {
239242
let name = const_param.name().map_or_else(Name::missing, |it| it.as_name());
@@ -255,7 +258,11 @@ impl GenericParams {
255258
let param = LifetimeParamData { name: name.clone() };
256259
self.lifetimes.alloc(param);
257260
let lifetime_ref = LifetimeRef::new_name(name);
258-
self.fill_bounds(lower_ctx, &lifetime_param, Either::Right(lifetime_ref));
261+
self.fill_bounds(
262+
lower_ctx,
263+
lifetime_param.type_bound_list(),
264+
Either::Right(lifetime_ref),
265+
);
259266
}
260267
}
261268

@@ -421,6 +428,10 @@ fn file_id_and_params_of(
421428
let src = it.lookup(db).source(db);
422429
(src.file_id, src.value.generic_param_list())
423430
}
431+
GenericDefId::TraitAliasId(it) => {
432+
let src = it.lookup(db).source(db);
433+
(src.file_id, src.value.generic_param_list())
434+
}
424435
GenericDefId::TypeAliasId(it) => {
425436
let src = it.lookup(db).source(db);
426437
(src.file_id, src.value.generic_param_list())
@@ -435,7 +446,7 @@ fn file_id_and_params_of(
435446
}
436447

437448
impl HasChildSource<LocalTypeOrConstParamId> for GenericDefId {
438-
type Value = Either<ast::TypeOrConstParam, ast::Trait>;
449+
type Value = Either<ast::TypeOrConstParam, ast::TraitOrAlias>;
439450
fn child_source(
440451
&self,
441452
db: &dyn DefDatabase,
@@ -447,11 +458,20 @@ impl HasChildSource<LocalTypeOrConstParamId> for GenericDefId {
447458

448459
let mut params = ArenaMap::default();
449460

450-
// For traits the first type index is `Self`, we need to add it before the other params.
451-
if let GenericDefId::TraitId(id) = *self {
452-
let trait_ref = id.lookup(db).source(db).value;
453-
let idx = idx_iter.next().unwrap();
454-
params.insert(idx, Either::Right(trait_ref));
461+
// For traits and trait aliases the first type index is `Self`, we need to add it before
462+
// the other params.
463+
match *self {
464+
GenericDefId::TraitId(id) => {
465+
let trait_ref = id.lookup(db).source(db).value;
466+
let idx = idx_iter.next().unwrap();
467+
params.insert(idx, Either::Right(ast::TraitOrAlias::Trait(trait_ref)));
468+
}
469+
GenericDefId::TraitAliasId(id) => {
470+
let alias = id.lookup(db).source(db).value;
471+
let idx = idx_iter.next().unwrap();
472+
params.insert(idx, Either::Right(ast::TraitOrAlias::TraitAlias(alias)));
473+
}
474+
_ => {}
455475
}
456476

457477
if let Some(generic_params_list) = generic_params_list {

crates/hir-def/src/import_map.rs

+2
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ pub enum ImportKind {
268268
Const,
269269
Static,
270270
Trait,
271+
TraitAlias,
271272
TypeAlias,
272273
BuiltinType,
273274
AssociatedItem,
@@ -463,6 +464,7 @@ fn item_import_kind(item: ItemInNs) -> Option<ImportKind> {
463464
ModuleDefId::ConstId(_) => ImportKind::Const,
464465
ModuleDefId::StaticId(_) => ImportKind::Static,
465466
ModuleDefId::TraitId(_) => ImportKind::Trait,
467+
ModuleDefId::TraitAliasId(_) => ImportKind::TraitAlias,
466468
ModuleDefId::TypeAliasId(_) => ImportKind::TypeAlias,
467469
ModuleDefId::BuiltinType(_) => ImportKind::BuiltinType,
468470
ModuleDefId::MacroId(_) => ImportKind::Macro,

crates/hir-def/src/item_scope.rs

+1
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ impl PerNs {
431431
ModuleDefId::EnumVariantId(_) => PerNs::both(def, def, v),
432432
ModuleDefId::ConstId(_) | ModuleDefId::StaticId(_) => PerNs::values(def, v),
433433
ModuleDefId::TraitId(_) => PerNs::types(def, v),
434+
ModuleDefId::TraitAliasId(_) => PerNs::types(def, v),
434435
ModuleDefId::TypeAliasId(_) => PerNs::types(def, v),
435436
ModuleDefId::BuiltinType(_) => PerNs::types(def, v),
436437
ModuleDefId::MacroId(mac) => PerNs::macros(mac, v),

crates/hir-def/src/item_tree.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ impl ItemTree {
204204
consts,
205205
statics,
206206
traits,
207+
trait_aliases,
207208
impls,
208209
type_aliases,
209210
mods,
@@ -226,6 +227,7 @@ impl ItemTree {
226227
consts.shrink_to_fit();
227228
statics.shrink_to_fit();
228229
traits.shrink_to_fit();
230+
trait_aliases.shrink_to_fit();
229231
impls.shrink_to_fit();
230232
type_aliases.shrink_to_fit();
231233
mods.shrink_to_fit();
@@ -276,6 +278,7 @@ struct ItemTreeData {
276278
consts: Arena<Const>,
277279
statics: Arena<Static>,
278280
traits: Arena<Trait>,
281+
trait_aliases: Arena<TraitAlias>,
279282
impls: Arena<Impl>,
280283
type_aliases: Arena<TypeAlias>,
281284
mods: Arena<Mod>,
@@ -496,6 +499,7 @@ mod_items! {
496499
Const in consts -> ast::Const,
497500
Static in statics -> ast::Static,
498501
Trait in traits -> ast::Trait,
502+
TraitAlias in trait_aliases -> ast::TraitAlias,
499503
Impl in impls -> ast::Impl,
500504
TypeAlias in type_aliases -> ast::TypeAlias,
501505
Mod in mods -> ast::Module,
@@ -672,11 +676,18 @@ pub struct Trait {
672676
pub generic_params: Interned<GenericParams>,
673677
pub is_auto: bool,
674678
pub is_unsafe: bool,
675-
/// This is [`None`] if this Trait is a trait alias.
676-
pub items: Option<Box<[AssocItem]>>,
679+
pub items: Box<[AssocItem]>,
677680
pub ast_id: FileAstId<ast::Trait>,
678681
}
679682

683+
#[derive(Debug, Clone, Eq, PartialEq)]
684+
pub struct TraitAlias {
685+
pub name: Name,
686+
pub visibility: RawVisibilityId,
687+
pub generic_params: Interned<GenericParams>,
688+
pub ast_id: FileAstId<ast::TraitAlias>,
689+
}
690+
680691
#[derive(Debug, Clone, Eq, PartialEq)]
681692
pub struct Impl {
682693
pub generic_params: Interned<GenericParams>,
@@ -872,6 +883,7 @@ impl ModItem {
872883
| ModItem::Enum(_)
873884
| ModItem::Static(_)
874885
| ModItem::Trait(_)
886+
| ModItem::TraitAlias(_)
875887
| ModItem::Impl(_)
876888
| ModItem::Mod(_)
877889
| ModItem::MacroRules(_)
@@ -899,6 +911,7 @@ impl ModItem {
899911
ModItem::Const(it) => tree[it.index].ast_id().upcast(),
900912
ModItem::Static(it) => tree[it.index].ast_id().upcast(),
901913
ModItem::Trait(it) => tree[it.index].ast_id().upcast(),
914+
ModItem::TraitAlias(it) => tree[it.index].ast_id().upcast(),
902915
ModItem::Impl(it) => tree[it.index].ast_id().upcast(),
903916
ModItem::TypeAlias(it) => tree[it.index].ast_id().upcast(),
904917
ModItem::Mod(it) => tree[it.index].ast_id().upcast(),

0 commit comments

Comments
 (0)