Skip to content

Commit 7fcfd3a

Browse files
committed
Make trait aliases source for type parameter
Just like traits, trait aliases have implicit type parameter `Self`.
1 parent 03e1cde commit 7fcfd3a

File tree

9 files changed

+120
-46
lines changed

9 files changed

+120
-46
lines changed

crates/hir-def/src/attr.rs

+10-36
Original file line numberDiff line numberDiff line change
@@ -316,26 +316,14 @@ impl AttrsWithOwner {
316316
let src = it.parent().child_source(db);
317317
RawAttrs::from_attrs_owner(
318318
db.upcast(),
319-
src.with_value(src.value[it.local_id()].as_ref().either(
320-
|it| match it {
321-
ast::TypeOrConstParam::Type(it) => it as _,
322-
ast::TypeOrConstParam::Const(it) => it as _,
323-
},
324-
|it| it as _,
325-
)),
319+
src.with_value(&src.value[it.local_id()]),
326320
)
327321
}
328322
GenericParamId::TypeParamId(it) => {
329323
let src = it.parent().child_source(db);
330324
RawAttrs::from_attrs_owner(
331325
db.upcast(),
332-
src.with_value(src.value[it.local_id()].as_ref().either(
333-
|it| match it {
334-
ast::TypeOrConstParam::Type(it) => it as _,
335-
ast::TypeOrConstParam::Const(it) => it as _,
336-
},
337-
|it| it as _,
338-
)),
326+
src.with_value(&src.value[it.local_id()]),
339327
)
340328
}
341329
GenericParamId::LifetimeParamId(it) => {
@@ -414,28 +402,14 @@ impl AttrsWithOwner {
414402
},
415403
AttrDefId::ImplId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
416404
AttrDefId::GenericParamId(id) => match id {
417-
GenericParamId::ConstParamId(id) => {
418-
id.parent().child_source(db).map(|source| match &source[id.local_id()] {
419-
Either::Left(ast::TypeOrConstParam::Type(id)) => {
420-
ast::AnyHasAttrs::new(id.clone())
421-
}
422-
Either::Left(ast::TypeOrConstParam::Const(id)) => {
423-
ast::AnyHasAttrs::new(id.clone())
424-
}
425-
Either::Right(id) => ast::AnyHasAttrs::new(id.clone()),
426-
})
427-
}
428-
GenericParamId::TypeParamId(id) => {
429-
id.parent().child_source(db).map(|source| match &source[id.local_id()] {
430-
Either::Left(ast::TypeOrConstParam::Type(id)) => {
431-
ast::AnyHasAttrs::new(id.clone())
432-
}
433-
Either::Left(ast::TypeOrConstParam::Const(id)) => {
434-
ast::AnyHasAttrs::new(id.clone())
435-
}
436-
Either::Right(id) => ast::AnyHasAttrs::new(id.clone()),
437-
})
438-
}
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())),
439413
GenericParamId::LifetimeParamId(id) => id
440414
.parent
441415
.child_source(db)

crates/hir-def/src/child_by_source.rs

+1-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;

crates/hir-def/src/generics.rs

+15-6
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ fn file_id_and_params_of(
446446
}
447447

448448
impl HasChildSource<LocalTypeOrConstParamId> for GenericDefId {
449-
type Value = Either<ast::TypeOrConstParam, ast::Trait>;
449+
type Value = Either<ast::TypeOrConstParam, ast::TraitOrAlias>;
450450
fn child_source(
451451
&self,
452452
db: &dyn DefDatabase,
@@ -458,11 +458,20 @@ impl HasChildSource<LocalTypeOrConstParamId> for GenericDefId {
458458

459459
let mut params = ArenaMap::default();
460460

461-
// For traits the first type index is `Self`, we need to add it before the other params.
462-
if let GenericDefId::TraitId(id) = *self {
463-
let trait_ref = id.lookup(db).source(db).value;
464-
let idx = idx_iter.next().unwrap();
465-
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+
_ => {}
466475
}
467476

468477
if let Some(generic_params_list) = generic_params_list {

crates/hir/src/has_source.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ impl HasSource for Impl {
164164
}
165165

166166
impl HasSource for TypeOrConstParam {
167-
type Ast = Either<ast::TypeOrConstParam, ast::Trait>;
167+
type Ast = Either<ast::TypeOrConstParam, ast::TraitOrAlias>;
168168
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
169169
let child_source = self.id.parent.child_source(db.upcast());
170170
Some(child_source.map(|it| it[self.id.local_id].clone()))

crates/hir/src/semantics.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,7 @@ impl<'db> SemanticsImpl<'db> {
13311331
})
13321332
}
13331333
ChildContainer::TraitId(it) => it.resolver(self.db.upcast()),
1334+
ChildContainer::TraitAliasId(it) => it.resolver(self.db.upcast()),
13341335
ChildContainer::ImplId(it) => it.resolver(self.db.upcast()),
13351336
ChildContainer::ModuleId(it) => it.resolver(self.db.upcast()),
13361337
ChildContainer::EnumId(it) => it.resolver(self.db.upcast()),

crates/hir/src/semantics/source_to_def.rs

+6
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,9 @@ impl SourceToDefCtx<'_, '_> {
359359
match item {
360360
ast::Item::Module(it) => self.module_to_def(container.with_value(it))?.into(),
361361
ast::Item::Trait(it) => self.trait_to_def(container.with_value(it))?.into(),
362+
ast::Item::TraitAlias(it) => {
363+
self.trait_alias_to_def(container.with_value(it))?.into()
364+
}
362365
ast::Item::Impl(it) => self.impl_to_def(container.with_value(it))?.into(),
363366
ast::Item::Enum(it) => self.enum_to_def(container.with_value(it))?.into(),
364367
ast::Item::TypeAlias(it) => {
@@ -444,6 +447,7 @@ pub(crate) enum ChildContainer {
444447
DefWithBodyId(DefWithBodyId),
445448
ModuleId(ModuleId),
446449
TraitId(TraitId),
450+
TraitAliasId(TraitAliasId),
447451
ImplId(ImplId),
448452
EnumId(EnumId),
449453
VariantId(VariantId),
@@ -456,6 +460,7 @@ impl_from! {
456460
DefWithBodyId,
457461
ModuleId,
458462
TraitId,
463+
TraitAliasId,
459464
ImplId,
460465
EnumId,
461466
VariantId,
@@ -471,6 +476,7 @@ impl ChildContainer {
471476
ChildContainer::DefWithBodyId(it) => it.child_by_source(db, file_id),
472477
ChildContainer::ModuleId(it) => it.child_by_source(db, file_id),
473478
ChildContainer::TraitId(it) => it.child_by_source(db, file_id),
479+
ChildContainer::TraitAliasId(_) => DynMap::default(),
474480
ChildContainer::ImplId(it) => it.child_by_source(db, file_id),
475481
ChildContainer::EnumId(it) => it.child_by_source(db, file_id),
476482
ChildContainer::VariantId(it) => it.child_by_source(db, file_id),

crates/ide-db/src/defs.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ impl NameRefClass {
548548
}
549549

550550
impl_from!(
551-
Field, Module, Function, Adt, Variant, Const, Static, Trait, TypeAlias, BuiltinType, Local,
551+
Field, Module, Function, Adt, Variant, Const, Static, Trait, TraitAlias, TypeAlias, BuiltinType, Local,
552552
GenericParam, Label, Macro
553553
for Definition
554554
);
@@ -623,6 +623,7 @@ impl From<Definition> for Option<ItemInNs> {
623623
Definition::Const(it) => ModuleDef::Const(it),
624624
Definition::Static(it) => ModuleDef::Static(it),
625625
Definition::Trait(it) => ModuleDef::Trait(it),
626+
Definition::TraitAlias(it) => ModuleDef::TraitAlias(it),
626627
Definition::TypeAlias(it) => ModuleDef::TypeAlias(it),
627628
Definition::BuiltinType(it) => ModuleDef::BuiltinType(it),
628629
_ => return None,

crates/syntax/src/ast.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ pub use self::{
2525
generated::{nodes::*, tokens::*},
2626
node_ext::{
2727
AttrKind, FieldKind, Macro, NameLike, NameOrNameRef, PathSegmentKind, SelfParamKind,
28-
SlicePatComponents, StructKind, TypeBoundKind, TypeOrConstParam, VisibilityKind,
28+
SlicePatComponents, StructKind, TraitOrAlias, TypeBoundKind, TypeOrConstParam,
29+
VisibilityKind,
2930
},
3031
operators::{ArithOp, BinaryOp, CmpOp, LogicOp, Ordering, RangeOp, UnaryOp},
3132
token_ext::{CommentKind, CommentPlacement, CommentShape, IsString, QuoteOffsets, Radix},
@@ -128,6 +129,13 @@ where
128129
}
129130
}
130131

132+
impl<L, R> HasAttrs for Either<L, R>
133+
where
134+
L: HasAttrs,
135+
R: HasAttrs,
136+
{
137+
}
138+
131139
mod support {
132140
use super::{AstChildren, AstNode, SyntaxKind, SyntaxNode, SyntaxToken};
133141

crates/syntax/src/ast/node_ext.rs

+75
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,81 @@ impl TypeOrConstParam {
680680
}
681681
}
682682

683+
impl AstNode for TypeOrConstParam {
684+
fn can_cast(kind: SyntaxKind) -> bool
685+
where
686+
Self: Sized,
687+
{
688+
matches!(kind, SyntaxKind::TYPE_PARAM | SyntaxKind::CONST_PARAM)
689+
}
690+
691+
fn cast(syntax: SyntaxNode) -> Option<Self>
692+
where
693+
Self: Sized,
694+
{
695+
let res = match syntax.kind() {
696+
SyntaxKind::TYPE_PARAM => TypeOrConstParam::Type(ast::TypeParam { syntax }),
697+
SyntaxKind::CONST_PARAM => TypeOrConstParam::Const(ast::ConstParam { syntax }),
698+
_ => return None,
699+
};
700+
Some(res)
701+
}
702+
703+
fn syntax(&self) -> &SyntaxNode {
704+
match self {
705+
TypeOrConstParam::Type(it) => it.syntax(),
706+
TypeOrConstParam::Const(it) => it.syntax(),
707+
}
708+
}
709+
}
710+
711+
impl HasAttrs for TypeOrConstParam {}
712+
713+
#[derive(Debug, Clone)]
714+
pub enum TraitOrAlias {
715+
Trait(ast::Trait),
716+
TraitAlias(ast::TraitAlias),
717+
}
718+
719+
impl TraitOrAlias {
720+
pub fn name(&self) -> Option<ast::Name> {
721+
match self {
722+
TraitOrAlias::Trait(x) => x.name(),
723+
TraitOrAlias::TraitAlias(x) => x.name(),
724+
}
725+
}
726+
}
727+
728+
impl AstNode for TraitOrAlias {
729+
fn can_cast(kind: SyntaxKind) -> bool
730+
where
731+
Self: Sized,
732+
{
733+
matches!(kind, SyntaxKind::TRAIT | SyntaxKind::TRAIT_ALIAS)
734+
}
735+
736+
fn cast(syntax: SyntaxNode) -> Option<Self>
737+
where
738+
Self: Sized,
739+
{
740+
let res = match syntax.kind() {
741+
SyntaxKind::TRAIT => TraitOrAlias::Trait(ast::Trait { syntax }),
742+
SyntaxKind::TRAIT_ALIAS => TraitOrAlias::TraitAlias(ast::TraitAlias { syntax }),
743+
_ => return None,
744+
};
745+
Some(res)
746+
}
747+
748+
fn syntax(&self) -> &SyntaxNode {
749+
match self {
750+
TraitOrAlias::Trait(it) => it.syntax(),
751+
TraitOrAlias::TraitAlias(it) => it.syntax(),
752+
}
753+
}
754+
}
755+
756+
impl HasAttrs for TraitOrAlias {}
757+
683758
pub enum VisibilityKind {
684759
In(ast::Path),
685760
PubCrate,

0 commit comments

Comments
 (0)