Skip to content

Commit ebe39e0

Browse files
committed
Lower and handle trait aliases in HIR
1 parent 96c2514 commit ebe39e0

Some content is hidden

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

47 files changed

+334
-75
lines changed

crates/hir-def/src/attr.rs

+2
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),
@@ -392,6 +393,7 @@ impl AttrsWithOwner {
392393
AttrDefId::StaticId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
393394
AttrDefId::ConstId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
394395
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),
395397
AttrDefId::TypeAliasId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
396398
AttrDefId::MacroId(id) => match id {
397399
MacroId::Macro2Id(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),

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

+20-6
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(_) => {
@@ -427,6 +428,10 @@ fn file_id_and_params_of(
427428
let src = it.lookup(db).source(db);
428429
(src.file_id, src.value.generic_param_list())
429430
}
431+
GenericDefId::TraitAliasId(it) => {
432+
let src = it.lookup(db).source(db);
433+
(src.file_id, src.value.generic_param_list())
434+
}
430435
GenericDefId::TypeAliasId(it) => {
431436
let src = it.lookup(db).source(db);
432437
(src.file_id, src.value.generic_param_list())
@@ -441,7 +446,7 @@ fn file_id_and_params_of(
441446
}
442447

443448
impl HasChildSource<LocalTypeOrConstParamId> for GenericDefId {
444-
type Value = Either<ast::TypeOrConstParam, ast::Trait>;
449+
type Value = Either<ast::TypeOrConstParam, ast::TraitOrAlias>;
445450
fn child_source(
446451
&self,
447452
db: &dyn DefDatabase,
@@ -453,11 +458,20 @@ impl HasChildSource<LocalTypeOrConstParamId> for GenericDefId {
453458

454459
let mut params = ArenaMap::default();
455460

456-
// For traits the first type index is `Self`, we need to add it before the other params.
457-
if let GenericDefId::TraitId(id) = *self {
458-
let trait_ref = id.lookup(db).source(db).value;
459-
let idx = idx_iter.next().unwrap();
460-
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+
_ => {}
461475
}
462476

463477
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(),

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

+33-14
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ impl<'a> Ctx<'a> {
110110
ast::Item::Const(ast) => self.lower_const(ast).into(),
111111
ast::Item::Module(ast) => self.lower_module(ast)?.into(),
112112
ast::Item::Trait(ast) => self.lower_trait(ast)?.into(),
113-
ast::Item::TraitAlias(_) => return None,
113+
ast::Item::TraitAlias(ast) => self.lower_trait_alias(ast)?.into(),
114114
ast::Item::Impl(ast) => self.lower_impl(ast)?.into(),
115115
ast::Item::Use(ast) => self.lower_use(ast)?.into(),
116116
ast::Item::ExternCrate(ast) => self.lower_extern_crate(ast)?.into(),
@@ -446,20 +446,39 @@ impl<'a> Ctx<'a> {
446446
self.lower_generic_params(HasImplicitSelf::Yes(trait_def.type_bound_list()), trait_def);
447447
let is_auto = trait_def.auto_token().is_some();
448448
let is_unsafe = trait_def.unsafe_token().is_some();
449-
let items = trait_def.assoc_item_list().map(|list| {
450-
list.assoc_items()
451-
.filter_map(|item| {
452-
let attrs = RawAttrs::new(self.db.upcast(), &item, self.hygiene());
453-
self.lower_assoc_item(&item).map(|item| {
454-
self.add_attrs(ModItem::from(item).into(), attrs);
455-
item
456-
})
457-
})
458-
.collect()
459-
});
460449
let ast_id = self.source_ast_id_map.ast_id(trait_def);
461-
let res = Trait { name, visibility, generic_params, is_auto, is_unsafe, items, ast_id };
462-
Some(id(self.data().traits.alloc(res)))
450+
451+
let items = trait_def
452+
.assoc_item_list()
453+
.into_iter()
454+
.flat_map(|list| list.assoc_items())
455+
.filter_map(|item| {
456+
let attrs = RawAttrs::new(self.db.upcast(), &item, self.hygiene());
457+
self.lower_assoc_item(&item).map(|item| {
458+
self.add_attrs(ModItem::from(item).into(), attrs);
459+
item
460+
})
461+
})
462+
.collect();
463+
464+
let def = Trait { name, visibility, generic_params, is_auto, is_unsafe, items, ast_id };
465+
Some(id(self.data().traits.alloc(def)))
466+
}
467+
468+
fn lower_trait_alias(
469+
&mut self,
470+
trait_alias_def: &ast::TraitAlias,
471+
) -> Option<FileItemTreeId<TraitAlias>> {
472+
let name = trait_alias_def.name()?.as_name();
473+
let visibility = self.lower_visibility(trait_alias_def);
474+
let generic_params = self.lower_generic_params(
475+
HasImplicitSelf::Yes(trait_alias_def.type_bound_list()),
476+
trait_alias_def,
477+
);
478+
let ast_id = self.source_ast_id_map.ast_id(trait_alias_def);
479+
480+
let alias = TraitAlias { name, visibility, generic_params, ast_id };
481+
Some(id(self.data().trait_aliases.alloc(alias)))
463482
}
464483

465484
fn lower_impl(&mut self, impl_def: &ast::Impl) -> Option<FileItemTreeId<Impl>> {

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

+15-14
Original file line numberDiff line numberDiff line change
@@ -374,23 +374,24 @@ impl<'a> Printer<'a> {
374374
}
375375
w!(self, "trait {}", name);
376376
self.print_generic_params(generic_params);
377-
match items {
378-
Some(items) => {
379-
self.print_where_clause_and_opening_brace(generic_params);
380-
self.indented(|this| {
381-
for item in &**items {
382-
this.print_mod_item((*item).into());
383-
}
384-
});
385-
}
386-
None => {
387-
w!(self, " = ");
388-
// FIXME: Print the aliased traits
389-
self.print_where_clause_and_opening_brace(generic_params);
377+
self.print_where_clause_and_opening_brace(generic_params);
378+
self.indented(|this| {
379+
for item in &**items {
380+
this.print_mod_item((*item).into());
390381
}
391-
}
382+
});
392383
wln!(self, "}}");
393384
}
385+
ModItem::TraitAlias(it) => {
386+
let TraitAlias { name, visibility, generic_params, ast_id: _ } = &self.tree[it];
387+
self.print_visibility(*visibility);
388+
w!(self, "trait {}", name);
389+
self.print_generic_params(generic_params);
390+
w!(self, " = ");
391+
self.print_where_clause(generic_params);
392+
w!(self, ";");
393+
wln!(self);
394+
}
394395
ModItem::Impl(it) => {
395396
let Impl { target_trait, self_ty, is_negative, items, generic_params, ast_id: _ } =
396397
&self.tree[it];

crates/hir-def/src/keys.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use syntax::{ast, AstNode, AstPtr};
99
use crate::{
1010
dyn_map::{DynMap, Policy},
1111
ConstId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, LifetimeParamId, Macro2Id,
12-
MacroRulesId, ProcMacroId, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId,
13-
UnionId,
12+
MacroRulesId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId,
13+
TypeOrConstParamId, UnionId,
1414
};
1515

1616
pub type Key<K, V> = crate::dyn_map::Key<K, V, AstPtrPolicy<K, V>>;
@@ -21,6 +21,7 @@ pub const STATIC: Key<ast::Static, StaticId> = Key::new();
2121
pub const TYPE_ALIAS: Key<ast::TypeAlias, TypeAliasId> = Key::new();
2222
pub const IMPL: Key<ast::Impl, ImplId> = Key::new();
2323
pub const TRAIT: Key<ast::Trait, TraitId> = Key::new();
24+
pub const TRAIT_ALIAS: Key<ast::TraitAlias, TraitAliasId> = Key::new();
2425
pub const STRUCT: Key<ast::Struct, StructId> = Key::new();
2526
pub const UNION: Key<ast::Union, UnionId> = Key::new();
2627
pub const ENUM: Key<ast::Enum, EnumId> = Key::new();

0 commit comments

Comments
 (0)