aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-07-31 17:41:37 +0100
committerAleksey Kladov <[email protected]>2020-07-31 17:41:37 +0100
commit040b4c800d5279e77a6825fc90cb2921d26c7f95 (patch)
tree17de1c83aa3d392902777c9eebbbb17f14b05e12
parentd21b5db891d605c7c10118daca1f06c09c14b07e (diff)
Fix GenericArgs grammar
-rw-r--r--crates/ra_assists/src/ast_transform.rs16
-rw-r--r--crates/ra_hir_def/src/path/lower.rs42
-rw-r--r--crates/ra_syntax/src/ast/generated/nodes.rs85
-rw-r--r--xtask/src/codegen/rust.ungram14
4 files changed, 107 insertions, 50 deletions
diff --git a/crates/ra_assists/src/ast_transform.rs b/crates/ra_assists/src/ast_transform.rs
index e23331773..0a7be87a0 100644
--- a/crates/ra_assists/src/ast_transform.rs
+++ b/crates/ra_assists/src/ast_transform.rs
@@ -79,19 +79,25 @@ impl<'a> SubstituteTypeParams<'a> {
79 }; 79 };
80 80
81 // FIXME: It would probably be nicer if we could get this via HIR (i.e. get the 81 // FIXME: It would probably be nicer if we could get this via HIR (i.e. get the
82 // trait ref, and then go from the types in the substs back to the syntax) 82 // trait ref, and then go from the types in the substs back to the syntax).
83 fn get_syntactic_substs(impl_def: ast::Impl) -> Option<Vec<ast::Type>> { 83 fn get_syntactic_substs(impl_def: ast::Impl) -> Option<Vec<ast::Type>> {
84 let target_trait = impl_def.target_trait()?; 84 let target_trait = impl_def.target_trait()?;
85 let path_type = match target_trait { 85 let path_type = match target_trait {
86 ast::Type::PathType(path) => path, 86 ast::Type::PathType(path) => path,
87 _ => return None, 87 _ => return None,
88 }; 88 };
89 let type_arg_list = path_type.path()?.segment()?.generic_arg_list()?; 89 let generic_arg_list = path_type.path()?.segment()?.generic_arg_list()?;
90
90 let mut result = Vec::new(); 91 let mut result = Vec::new();
91 for type_arg in type_arg_list.type_args() { 92 for generic_arg in generic_arg_list.generic_args() {
92 let type_arg: ast::TypeArg = type_arg; 93 match generic_arg {
93 result.push(type_arg.ty()?); 94 ast::GenericArg::TypeArg(type_arg) => result.push(type_arg.ty()?),
95 ast::GenericArg::AssocTypeArg(_)
96 | ast::GenericArg::LifetimeArg(_)
97 | ast::GenericArg::ConstArg(_) => (),
98 }
94 } 99 }
100
95 Some(result) 101 Some(result)
96 } 102 }
97 } 103 }
diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs
index aefeca400..d09fc66e4 100644
--- a/crates/ra_hir_def/src/path/lower.rs
+++ b/crates/ra_hir_def/src/path/lower.rs
@@ -151,30 +151,34 @@ pub(super) fn lower_generic_args(
151 node: ast::GenericArgList, 151 node: ast::GenericArgList,
152) -> Option<GenericArgs> { 152) -> Option<GenericArgs> {
153 let mut args = Vec::new(); 153 let mut args = Vec::new();
154 for type_arg in node.type_args() {
155 let type_ref = TypeRef::from_ast_opt(lower_ctx, type_arg.ty());
156 args.push(GenericArg::Type(type_ref));
157 }
158 // lifetimes ignored for now
159 let mut bindings = Vec::new(); 154 let mut bindings = Vec::new();
160 for assoc_type_arg in node.assoc_type_args() { 155 for generic_arg in node.generic_args() {
161 let assoc_type_arg: ast::AssocTypeArg = assoc_type_arg; 156 match generic_arg {
162 if let Some(name_ref) = assoc_type_arg.name_ref() { 157 ast::GenericArg::TypeArg(type_arg) => {
163 let name = name_ref.as_name(); 158 let type_ref = TypeRef::from_ast_opt(lower_ctx, type_arg.ty());
164 let type_ref = assoc_type_arg.ty().map(|it| TypeRef::from_ast(lower_ctx, it)); 159 args.push(GenericArg::Type(type_ref));
165 let bounds = if let Some(l) = assoc_type_arg.type_bound_list() { 160 }
166 l.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect() 161 ast::GenericArg::AssocTypeArg(assoc_type_arg) => {
167 } else { 162 if let Some(name_ref) = assoc_type_arg.name_ref() {
168 Vec::new() 163 let name = name_ref.as_name();
169 }; 164 let type_ref = assoc_type_arg.ty().map(|it| TypeRef::from_ast(lower_ctx, it));
170 bindings.push(AssociatedTypeBinding { name, type_ref, bounds }); 165 let bounds = if let Some(l) = assoc_type_arg.type_bound_list() {
166 l.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect()
167 } else {
168 Vec::new()
169 };
170 bindings.push(AssociatedTypeBinding { name, type_ref, bounds });
171 }
172 }
173 // Lifetimes and constants are ignored for now.
174 ast::GenericArg::LifetimeArg(_) | ast::GenericArg::ConstArg(_) => (),
171 } 175 }
172 } 176 }
177
173 if args.is_empty() && bindings.is_empty() { 178 if args.is_empty() && bindings.is_empty() {
174 None 179 return None;
175 } else {
176 Some(GenericArgs { args, has_self_type: false, bindings })
177 } 180 }
181 Some(GenericArgs { args, has_self_type: false, bindings })
178} 182}
179 183
180/// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y) 184/// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y)
diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs
index 903646149..132c2ae8c 100644
--- a/crates/ra_syntax/src/ast/generated/nodes.rs
+++ b/crates/ra_syntax/src/ast/generated/nodes.rs
@@ -46,10 +46,7 @@ pub struct GenericArgList {
46impl GenericArgList { 46impl GenericArgList {
47 pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) } 47 pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
48 pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) } 48 pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
49 pub fn type_args(&self) -> AstChildren<TypeArg> { support::children(&self.syntax) } 49 pub fn generic_args(&self) -> AstChildren<GenericArg> { support::children(&self.syntax) }
50 pub fn lifetime_args(&self) -> AstChildren<LifetimeArg> { support::children(&self.syntax) }
51 pub fn assoc_type_args(&self) -> AstChildren<AssocTypeArg> { support::children(&self.syntax) }
52 pub fn const_args(&self) -> AstChildren<ConstArg> { support::children(&self.syntax) }
53 pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) } 50 pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
54} 51}
55#[derive(Debug, Clone, PartialEq, Eq, Hash)] 52#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -86,15 +83,6 @@ impl TypeArg {
86 pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) } 83 pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
87} 84}
88#[derive(Debug, Clone, PartialEq, Eq, Hash)] 85#[derive(Debug, Clone, PartialEq, Eq, Hash)]
89pub struct LifetimeArg {
90 pub(crate) syntax: SyntaxNode,
91}
92impl LifetimeArg {
93 pub fn lifetime_token(&self) -> Option<SyntaxToken> {
94 support::token(&self.syntax, T![lifetime])
95 }
96}
97#[derive(Debug, Clone, PartialEq, Eq, Hash)]
98pub struct AssocTypeArg { 86pub struct AssocTypeArg {
99 pub(crate) syntax: SyntaxNode, 87 pub(crate) syntax: SyntaxNode,
100} 88}
@@ -105,6 +93,15 @@ impl AssocTypeArg {
105 pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) } 93 pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
106} 94}
107#[derive(Debug, Clone, PartialEq, Eq, Hash)] 95#[derive(Debug, Clone, PartialEq, Eq, Hash)]
96pub struct LifetimeArg {
97 pub(crate) syntax: SyntaxNode,
98}
99impl LifetimeArg {
100 pub fn lifetime_token(&self) -> Option<SyntaxToken> {
101 support::token(&self.syntax, T![lifetime])
102 }
103}
104#[derive(Debug, Clone, PartialEq, Eq, Hash)]
108pub struct ConstArg { 105pub struct ConstArg {
109 pub(crate) syntax: SyntaxNode, 106 pub(crate) syntax: SyntaxNode,
110} 107}
@@ -1272,6 +1269,13 @@ impl MacroStmts {
1272 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) } 1269 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
1273} 1270}
1274#[derive(Debug, Clone, PartialEq, Eq, Hash)] 1271#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1272pub enum GenericArg {
1273 TypeArg(TypeArg),
1274 AssocTypeArg(AssocTypeArg),
1275 LifetimeArg(LifetimeArg),
1276 ConstArg(ConstArg),
1277}
1278#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1275pub enum Type { 1279pub enum Type {
1276 ArrayType(ArrayType), 1280 ArrayType(ArrayType),
1277 DynTraitType(DynTraitType), 1281 DynTraitType(DynTraitType),
@@ -1489,8 +1493,8 @@ impl AstNode for TypeArg {
1489 } 1493 }
1490 fn syntax(&self) -> &SyntaxNode { &self.syntax } 1494 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1491} 1495}
1492impl AstNode for LifetimeArg { 1496impl AstNode for AssocTypeArg {
1493 fn can_cast(kind: SyntaxKind) -> bool { kind == LIFETIME_ARG } 1497 fn can_cast(kind: SyntaxKind) -> bool { kind == ASSOC_TYPE_ARG }
1494 fn cast(syntax: SyntaxNode) -> Option<Self> { 1498 fn cast(syntax: SyntaxNode) -> Option<Self> {
1495 if Self::can_cast(syntax.kind()) { 1499 if Self::can_cast(syntax.kind()) {
1496 Some(Self { syntax }) 1500 Some(Self { syntax })
@@ -1500,8 +1504,8 @@ impl AstNode for LifetimeArg {
1500 } 1504 }
1501 fn syntax(&self) -> &SyntaxNode { &self.syntax } 1505 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1502} 1506}
1503impl AstNode for AssocTypeArg { 1507impl AstNode for LifetimeArg {
1504 fn can_cast(kind: SyntaxKind) -> bool { kind == ASSOC_TYPE_ARG } 1508 fn can_cast(kind: SyntaxKind) -> bool { kind == LIFETIME_ARG }
1505 fn cast(syntax: SyntaxNode) -> Option<Self> { 1509 fn cast(syntax: SyntaxNode) -> Option<Self> {
1506 if Self::can_cast(syntax.kind()) { 1510 if Self::can_cast(syntax.kind()) {
1507 Some(Self { syntax }) 1511 Some(Self { syntax })
@@ -2765,6 +2769,44 @@ impl AstNode for MacroStmts {
2765 } 2769 }
2766 fn syntax(&self) -> &SyntaxNode { &self.syntax } 2770 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2767} 2771}
2772impl From<TypeArg> for GenericArg {
2773 fn from(node: TypeArg) -> GenericArg { GenericArg::TypeArg(node) }
2774}
2775impl From<AssocTypeArg> for GenericArg {
2776 fn from(node: AssocTypeArg) -> GenericArg { GenericArg::AssocTypeArg(node) }
2777}
2778impl From<LifetimeArg> for GenericArg {
2779 fn from(node: LifetimeArg) -> GenericArg { GenericArg::LifetimeArg(node) }
2780}
2781impl From<ConstArg> for GenericArg {
2782 fn from(node: ConstArg) -> GenericArg { GenericArg::ConstArg(node) }
2783}
2784impl AstNode for GenericArg {
2785 fn can_cast(kind: SyntaxKind) -> bool {
2786 match kind {
2787 TYPE_ARG | ASSOC_TYPE_ARG | LIFETIME_ARG | CONST_ARG => true,
2788 _ => false,
2789 }
2790 }
2791 fn cast(syntax: SyntaxNode) -> Option<Self> {
2792 let res = match syntax.kind() {
2793 TYPE_ARG => GenericArg::TypeArg(TypeArg { syntax }),
2794 ASSOC_TYPE_ARG => GenericArg::AssocTypeArg(AssocTypeArg { syntax }),
2795 LIFETIME_ARG => GenericArg::LifetimeArg(LifetimeArg { syntax }),
2796 CONST_ARG => GenericArg::ConstArg(ConstArg { syntax }),
2797 _ => return None,
2798 };
2799 Some(res)
2800 }
2801 fn syntax(&self) -> &SyntaxNode {
2802 match self {
2803 GenericArg::TypeArg(it) => &it.syntax,
2804 GenericArg::AssocTypeArg(it) => &it.syntax,
2805 GenericArg::LifetimeArg(it) => &it.syntax,
2806 GenericArg::ConstArg(it) => &it.syntax,
2807 }
2808 }
2809}
2768impl From<ArrayType> for Type { 2810impl From<ArrayType> for Type {
2769 fn from(node: ArrayType) -> Type { Type::ArrayType(node) } 2811 fn from(node: ArrayType) -> Type { Type::ArrayType(node) }
2770} 2812}
@@ -3380,6 +3422,11 @@ impl From<Item> for Stmt {
3380impl From<LetStmt> for Stmt { 3422impl From<LetStmt> for Stmt {
3381 fn from(node: LetStmt) -> Stmt { Stmt::LetStmt(node) } 3423 fn from(node: LetStmt) -> Stmt { Stmt::LetStmt(node) }
3382} 3424}
3425impl std::fmt::Display for GenericArg {
3426 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3427 std::fmt::Display::fmt(self.syntax(), f)
3428 }
3429}
3383impl std::fmt::Display for Type { 3430impl std::fmt::Display for Type {
3384 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3431 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3385 std::fmt::Display::fmt(self.syntax(), f) 3432 std::fmt::Display::fmt(self.syntax(), f)
@@ -3470,12 +3517,12 @@ impl std::fmt::Display for TypeArg {
3470 std::fmt::Display::fmt(self.syntax(), f) 3517 std::fmt::Display::fmt(self.syntax(), f)
3471 } 3518 }
3472} 3519}
3473impl std::fmt::Display for LifetimeArg { 3520impl std::fmt::Display for AssocTypeArg {
3474 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3521 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3475 std::fmt::Display::fmt(self.syntax(), f) 3522 std::fmt::Display::fmt(self.syntax(), f)
3476 } 3523 }
3477} 3524}
3478impl std::fmt::Display for AssocTypeArg { 3525impl std::fmt::Display for LifetimeArg {
3479 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3526 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3480 std::fmt::Display::fmt(self.syntax(), f) 3527 std::fmt::Display::fmt(self.syntax(), f)
3481 } 3528 }
diff --git a/xtask/src/codegen/rust.ungram b/xtask/src/codegen/rust.ungram
index cb4cd49fe..fa18acbb3 100644
--- a/xtask/src/codegen/rust.ungram
+++ b/xtask/src/codegen/rust.ungram
@@ -8,12 +8,13 @@ PathSegment =
8| '<' PathType ('as' PathType)? '>' 8| '<' PathType ('as' PathType)? '>'
9 9
10GenericArgList = 10GenericArgList =
11 '::'? '<' 11 '::'? '<' (GenericArg (',' GenericArg)* ','?)? '>'
12 TypeArg* 12
13 LifetimeArg* 13GenericArg =
14 AssocTypeArg* 14 TypeArg
15 ConstArg* 15| AssocTypeArg
16 '>' 16| LifetimeArg
17| ConstArg
17 18
18TypeArg = 19TypeArg =
19 Type 20 Type
@@ -27,7 +28,6 @@ LifetimeArg =
27ConstArg = 28ConstArg =
28 Literal | BlockExpr BlockExpr 29 Literal | BlockExpr BlockExpr
29 30
30
31SourceFile = 31SourceFile =
32 'shebang'? 32 'shebang'?
33 Attr* 33 Attr*