Unnamed repository; edit this file 'description' to name the repository.
Parse trait alias as a distinct AST type
Ryo Yoshida 2023-03-03
parent 9b441b9 · commit 2e7d2c2
-rw-r--r--crates/hir-def/src/item_tree/lower.rs1
-rw-r--r--crates/parser/src/grammar/items/traits.rs2
-rw-r--r--crates/parser/src/syntax_kind/generated.rs1
-rw-r--r--crates/parser/test_data/parser/inline/ok/0151_trait_alias.rast2
-rw-r--r--crates/parser/test_data/parser/inline/ok/0177_trait_alias_where_clause.rast4
-rw-r--r--crates/syntax/rust.ungram10
-rw-r--r--crates/syntax/src/ast.rs3
-rw-r--r--crates/syntax/src/ast/generated/nodes.rs43
-rw-r--r--crates/syntax/src/ast/node_ext.rs45
-rw-r--r--crates/syntax/src/tests/ast_src.rs1
-rw-r--r--crates/syntax/src/tests/sourcegen_ast.rs1
11 files changed, 103 insertions, 10 deletions
diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs
index d4d3c5ef19..bd7c556ae6 100644
--- a/crates/hir-def/src/item_tree/lower.rs
+++ b/crates/hir-def/src/item_tree/lower.rs
@@ -110,6 +110,7 @@ impl<'a> Ctx<'a> {
ast::Item::Const(ast) => self.lower_const(ast).into(),
ast::Item::Module(ast) => self.lower_module(ast)?.into(),
ast::Item::Trait(ast) => self.lower_trait(ast)?.into(),
+ ast::Item::TraitAlias(_) => return None,
ast::Item::Impl(ast) => self.lower_impl(ast)?.into(),
ast::Item::Use(ast) => self.lower_use(ast)?.into(),
ast::Item::ExternCrate(ast) => self.lower_extern_crate(ast)?.into(),
diff --git a/crates/parser/src/grammar/items/traits.rs b/crates/parser/src/grammar/items/traits.rs
index c982e2d564..a8a1ccb15e 100644
--- a/crates/parser/src/grammar/items/traits.rs
+++ b/crates/parser/src/grammar/items/traits.rs
@@ -20,7 +20,7 @@ pub(super) fn trait_(p: &mut Parser<'_>, m: Marker) {
// trait Z<U> = where Self: T<U>;
generic_params::opt_where_clause(p);
p.expect(T![;]);
- m.complete(p, TRAIT);
+ m.complete(p, TRAIT_ALIAS);
return;
}
diff --git a/crates/parser/src/syntax_kind/generated.rs b/crates/parser/src/syntax_kind/generated.rs
index 52b3fc23d5..cd87b304a2 100644
--- a/crates/parser/src/syntax_kind/generated.rs
+++ b/crates/parser/src/syntax_kind/generated.rs
@@ -135,6 +135,7 @@ pub enum SyntaxKind {
STATIC,
CONST,
TRAIT,
+ TRAIT_ALIAS,
IMPL,
TYPE_ALIAS,
MACRO_CALL,
diff --git a/crates/parser/test_data/parser/inline/ok/0151_trait_alias.rast b/crates/parser/test_data/parser/inline/ok/0151_trait_alias.rast
index 2ef66484ae..c45f870898 100644
--- a/crates/parser/test_data/parser/inline/ok/0151_trait_alias.rast
+++ b/crates/parser/test_data/parser/inline/ok/0151_trait_alias.rast
@@ -1,5 +1,5 @@
SOURCE_FILE
- TRAIT
+ TRAIT_ALIAS
TRAIT_KW "trait"
WHITESPACE " "
NAME
diff --git a/crates/parser/test_data/parser/inline/ok/0177_trait_alias_where_clause.rast b/crates/parser/test_data/parser/inline/ok/0177_trait_alias_where_clause.rast
index 4443d9d142..8f67824773 100644
--- a/crates/parser/test_data/parser/inline/ok/0177_trait_alias_where_clause.rast
+++ b/crates/parser/test_data/parser/inline/ok/0177_trait_alias_where_clause.rast
@@ -1,5 +1,5 @@
SOURCE_FILE
- TRAIT
+ TRAIT_ALIAS
TRAIT_KW "trait"
WHITESPACE " "
NAME
@@ -50,7 +50,7 @@ SOURCE_FILE
IDENT "Copy"
SEMICOLON ";"
WHITESPACE "\n"
- TRAIT
+ TRAIT_ALIAS
TRAIT_KW "trait"
WHITESPACE " "
NAME
diff --git a/crates/syntax/rust.ungram b/crates/syntax/rust.ungram
index 36ad5fddfd..548b5ba8b8 100644
--- a/crates/syntax/rust.ungram
+++ b/crates/syntax/rust.ungram
@@ -97,6 +97,7 @@ Item =
| Static
| Struct
| Trait
+| TraitAlias
| TypeAlias
| Union
| Use
@@ -240,10 +241,11 @@ Trait =
Attr* Visibility?
'unsafe'? 'auto'?
'trait' Name GenericParamList?
- (
- (':' TypeBoundList?)? WhereClause? AssocItemList
- | '=' TypeBoundList? WhereClause? ';'
- )
+ (':' TypeBoundList?)? WhereClause? AssocItemList
+
+TraitAlias =
+ Attr* Visibility?
+ 'trait' Name GenericParamList? '=' TypeBoundList? WhereClause? ';'
AssocItemList =
'{' Attr* AssocItem* '}'
diff --git a/crates/syntax/src/ast.rs b/crates/syntax/src/ast.rs
index 679536fe27..745f2e14e9 100644
--- a/crates/syntax/src/ast.rs
+++ b/crates/syntax/src/ast.rs
@@ -25,7 +25,8 @@ pub use self::{
generated::{nodes::*, tokens::*},
node_ext::{
AttrKind, FieldKind, Macro, NameLike, NameOrNameRef, PathSegmentKind, SelfParamKind,
- SlicePatComponents, StructKind, TypeBoundKind, TypeOrConstParam, VisibilityKind,
+ SlicePatComponents, StructKind, TraitOrAlias, TypeBoundKind, TypeOrConstParam,
+ VisibilityKind,
},
operators::{ArithOp, BinaryOp, CmpOp, LogicOp, Ordering, RangeOp, UnaryOp},
token_ext::{CommentKind, CommentPlacement, CommentShape, IsString, QuoteOffsets, Radix},
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs
index 642a3bfc35..fe32484536 100644
--- a/crates/syntax/src/ast/generated/nodes.rs
+++ b/crates/syntax/src/ast/generated/nodes.rs
@@ -407,7 +407,21 @@ impl Trait {
pub fn auto_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![auto]) }
pub fn trait_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![trait]) }
pub fn assoc_item_list(&self) -> Option<AssocItemList> { support::child(&self.syntax) }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct TraitAlias {
+ pub(crate) syntax: SyntaxNode,
+}
+impl ast::HasAttrs for TraitAlias {}
+impl ast::HasName for TraitAlias {}
+impl ast::HasVisibility for TraitAlias {}
+impl ast::HasGenericParams for TraitAlias {}
+impl ast::HasDocComments for TraitAlias {}
+impl TraitAlias {
+ pub fn trait_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![trait]) }
pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
+ pub fn type_bound_list(&self) -> Option<TypeBoundList> { support::child(&self.syntax) }
pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
}
@@ -1573,6 +1587,7 @@ pub enum Item {
Static(Static),
Struct(Struct),
Trait(Trait),
+ TraitAlias(TraitAlias),
TypeAlias(TypeAlias),
Union(Union),
Use(Use),
@@ -2058,6 +2073,17 @@ impl AstNode for Trait {
}
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
+impl AstNode for TraitAlias {
+ fn can_cast(kind: SyntaxKind) -> bool { kind == TRAIT_ALIAS }
+ fn cast(syntax: SyntaxNode) -> Option<Self> {
+ if Self::can_cast(syntax.kind()) {
+ Some(Self { syntax })
+ } else {
+ None
+ }
+ }
+ fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
impl AstNode for TypeAlias {
fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_ALIAS }
fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3570,6 +3596,9 @@ impl From<Struct> for Item {
impl From<Trait> for Item {
fn from(node: Trait) -> Item { Item::Trait(node) }
}
+impl From<TraitAlias> for Item {
+ fn from(node: TraitAlias) -> Item { Item::TraitAlias(node) }
+}
impl From<TypeAlias> for Item {
fn from(node: TypeAlias) -> Item { Item::TypeAlias(node) }
}
@@ -3596,6 +3625,7 @@ impl AstNode for Item {
| STATIC
| STRUCT
| TRAIT
+ | TRAIT_ALIAS
| TYPE_ALIAS
| UNION
| USE
@@ -3616,6 +3646,7 @@ impl AstNode for Item {
STATIC => Item::Static(Static { syntax }),
STRUCT => Item::Struct(Struct { syntax }),
TRAIT => Item::Trait(Trait { syntax }),
+ TRAIT_ALIAS => Item::TraitAlias(TraitAlias { syntax }),
TYPE_ALIAS => Item::TypeAlias(TypeAlias { syntax }),
UNION => Item::Union(Union { syntax }),
USE => Item::Use(Use { syntax }),
@@ -3638,6 +3669,7 @@ impl AstNode for Item {
Item::Static(it) => &it.syntax,
Item::Struct(it) => &it.syntax,
Item::Trait(it) => &it.syntax,
+ Item::TraitAlias(it) => &it.syntax,
Item::TypeAlias(it) => &it.syntax,
Item::Union(it) => &it.syntax,
Item::Use(it) => &it.syntax,
@@ -3950,6 +3982,7 @@ impl AstNode for AnyHasAttrs {
| STATIC
| STRUCT
| TRAIT
+ | TRAIT_ALIAS
| TYPE_ALIAS
| UNION
| USE
@@ -4035,6 +4068,7 @@ impl AstNode for AnyHasDocComments {
| STATIC
| STRUCT
| TRAIT
+ | TRAIT_ALIAS
| TYPE_ALIAS
| UNION
| USE
@@ -4056,7 +4090,7 @@ impl AnyHasGenericParams {
}
impl AstNode for AnyHasGenericParams {
fn can_cast(kind: SyntaxKind) -> bool {
- matches!(kind, ENUM | FN | IMPL | STRUCT | TRAIT | TYPE_ALIAS | UNION)
+ matches!(kind, ENUM | FN | IMPL | STRUCT | TRAIT | TRAIT_ALIAS | TYPE_ALIAS | UNION)
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
Self::can_cast(syntax.kind()).then_some(AnyHasGenericParams { syntax })
@@ -4108,6 +4142,7 @@ impl AstNode for AnyHasName {
| STATIC
| STRUCT
| TRAIT
+ | TRAIT_ALIAS
| TYPE_ALIAS
| UNION
| RENAME
@@ -4163,6 +4198,7 @@ impl AstNode for AnyHasVisibility {
| STATIC
| STRUCT
| TRAIT
+ | TRAIT_ALIAS
| TYPE_ALIAS
| UNION
| USE
@@ -4391,6 +4427,11 @@ impl std::fmt::Display for Trait {
std::fmt::Display::fmt(self.syntax(), f)
}
}
+impl std::fmt::Display for TraitAlias {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::fmt::Display::fmt(self.syntax(), f)
+ }
+}
impl std::fmt::Display for TypeAlias {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index fe82aa9072..301fbcebf1 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -680,6 +680,51 @@ impl TypeOrConstParam {
}
}
+#[derive(Debug, Clone)]
+pub enum TraitOrAlias {
+ Trait(ast::Trait),
+ TraitAlias(ast::TraitAlias),
+}
+
+impl TraitOrAlias {
+ pub fn name(&self) -> Option<ast::Name> {
+ match self {
+ TraitOrAlias::Trait(x) => x.name(),
+ TraitOrAlias::TraitAlias(x) => x.name(),
+ }
+ }
+}
+
+impl AstNode for TraitOrAlias {
+ fn can_cast(kind: SyntaxKind) -> bool
+ where
+ Self: Sized,
+ {
+ matches!(kind, SyntaxKind::TRAIT | SyntaxKind::TRAIT_ALIAS)
+ }
+
+ fn cast(syntax: SyntaxNode) -> Option<Self>
+ where
+ Self: Sized,
+ {
+ let res = match syntax.kind() {
+ SyntaxKind::TRAIT => TraitOrAlias::Trait(ast::Trait { syntax }),
+ SyntaxKind::TRAIT_ALIAS => TraitOrAlias::TraitAlias(ast::TraitAlias { syntax }),
+ _ => return None,
+ };
+ Some(res)
+ }
+
+ fn syntax(&self) -> &SyntaxNode {
+ match self {
+ TraitOrAlias::Trait(it) => it.syntax(),
+ TraitOrAlias::TraitAlias(it) => it.syntax(),
+ }
+ }
+}
+
+impl HasAttrs for TraitOrAlias {}
+
pub enum VisibilityKind {
In(ast::Path),
PubCrate,
diff --git a/crates/syntax/src/tests/ast_src.rs b/crates/syntax/src/tests/ast_src.rs
index 3ff6e03006..ccce71966f 100644
--- a/crates/syntax/src/tests/ast_src.rs
+++ b/crates/syntax/src/tests/ast_src.rs
@@ -86,6 +86,7 @@ pub(crate) const KINDS_SRC: KindsSrc<'_> = KindsSrc {
"STATIC",
"CONST",
"TRAIT",
+ "TRAIT_ALIAS",
"IMPL",
"TYPE_ALIAS",
"MACRO_CALL",
diff --git a/crates/syntax/src/tests/sourcegen_ast.rs b/crates/syntax/src/tests/sourcegen_ast.rs
index 03aa2c451e..e954b58251 100644
--- a/crates/syntax/src/tests/sourcegen_ast.rs
+++ b/crates/syntax/src/tests/sourcegen_ast.rs
@@ -783,6 +783,7 @@ fn extract_struct_traits(ast: &mut AstSrc) {
"Enum",
"Variant",
"Trait",
+ "TraitAlias",
"Module",
"Static",
"Const",