diff options
-rw-r--r-- | crates/ra_assists/src/ast_transform.rs | 16 | ||||
-rw-r--r-- | crates/ra_hir_def/src/path/lower.rs | 42 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated/nodes.rs | 85 | ||||
-rw-r--r-- | xtask/src/codegen/rust.ungram | 14 |
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 { | |||
46 | impl GenericArgList { | 46 | impl 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)] |
89 | pub struct LifetimeArg { | ||
90 | pub(crate) syntax: SyntaxNode, | ||
91 | } | ||
92 | impl 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)] | ||
98 | pub struct AssocTypeArg { | 86 | pub 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)] |
96 | pub struct LifetimeArg { | ||
97 | pub(crate) syntax: SyntaxNode, | ||
98 | } | ||
99 | impl 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)] | ||
108 | pub struct ConstArg { | 105 | pub 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)] |
1272 | pub enum GenericArg { | ||
1273 | TypeArg(TypeArg), | ||
1274 | AssocTypeArg(AssocTypeArg), | ||
1275 | LifetimeArg(LifetimeArg), | ||
1276 | ConstArg(ConstArg), | ||
1277 | } | ||
1278 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
1275 | pub enum Type { | 1279 | pub 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 | } |
1492 | impl AstNode for LifetimeArg { | 1496 | impl 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 | } |
1503 | impl AstNode for AssocTypeArg { | 1507 | impl 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 | } |
2772 | impl From<TypeArg> for GenericArg { | ||
2773 | fn from(node: TypeArg) -> GenericArg { GenericArg::TypeArg(node) } | ||
2774 | } | ||
2775 | impl From<AssocTypeArg> for GenericArg { | ||
2776 | fn from(node: AssocTypeArg) -> GenericArg { GenericArg::AssocTypeArg(node) } | ||
2777 | } | ||
2778 | impl From<LifetimeArg> for GenericArg { | ||
2779 | fn from(node: LifetimeArg) -> GenericArg { GenericArg::LifetimeArg(node) } | ||
2780 | } | ||
2781 | impl From<ConstArg> for GenericArg { | ||
2782 | fn from(node: ConstArg) -> GenericArg { GenericArg::ConstArg(node) } | ||
2783 | } | ||
2784 | impl 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 | } | ||
2768 | impl From<ArrayType> for Type { | 2810 | impl 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 { | |||
3380 | impl From<LetStmt> for Stmt { | 3422 | impl From<LetStmt> for Stmt { |
3381 | fn from(node: LetStmt) -> Stmt { Stmt::LetStmt(node) } | 3423 | fn from(node: LetStmt) -> Stmt { Stmt::LetStmt(node) } |
3382 | } | 3424 | } |
3425 | impl 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 | } | ||
3383 | impl std::fmt::Display for Type { | 3430 | impl 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 | } |
3473 | impl std::fmt::Display for LifetimeArg { | 3520 | impl 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 | } |
3478 | impl std::fmt::Display for AssocTypeArg { | 3525 | impl 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 | ||
10 | GenericArgList = | 10 | GenericArgList = |
11 | '::'? '<' | 11 | '::'? '<' (GenericArg (',' GenericArg)* ','?)? '>' |
12 | TypeArg* | 12 | |
13 | LifetimeArg* | 13 | GenericArg = |
14 | AssocTypeArg* | 14 | TypeArg |
15 | ConstArg* | 15 | | AssocTypeArg |
16 | '>' | 16 | | LifetimeArg |
17 | | ConstArg | ||
17 | 18 | ||
18 | TypeArg = | 19 | TypeArg = |
19 | Type | 20 | Type |
@@ -27,7 +28,6 @@ LifetimeArg = | |||
27 | ConstArg = | 28 | ConstArg = |
28 | Literal | BlockExpr BlockExpr | 29 | Literal | BlockExpr BlockExpr |
29 | 30 | ||
30 | |||
31 | SourceFile = | 31 | SourceFile = |
32 | 'shebang'? | 32 | 'shebang'? |
33 | Attr* | 33 | Attr* |