diff options
-rw-r--r-- | crates/ra_hir/src/path.rs | 44 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 16 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 6 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar.ron | 2 |
4 files changed, 55 insertions, 13 deletions
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs index 24316fc91..d6c78593b 100644 --- a/crates/ra_hir/src/path.rs +++ b/crates/ra_hir/src/path.rs | |||
@@ -1,11 +1,11 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | ast::{self, NameOwner}, | 4 | ast::{self, NameOwner, TypeAscriptionOwner}, |
5 | AstNode, | 5 | AstNode, |
6 | }; | 6 | }; |
7 | 7 | ||
8 | use crate::{type_ref::TypeRef, AsName, Name}; | 8 | use crate::{name, type_ref::TypeRef, AsName, Name}; |
9 | 9 | ||
10 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 10 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
11 | pub struct Path { | 11 | pub struct Path { |
@@ -76,8 +76,16 @@ impl Path { | |||
76 | 76 | ||
77 | match segment.kind()? { | 77 | match segment.kind()? { |
78 | ast::PathSegmentKind::Name(name) => { | 78 | ast::PathSegmentKind::Name(name) => { |
79 | let args = | 79 | let args = segment |
80 | segment.type_arg_list().and_then(GenericArgs::from_ast).map(Arc::new); | 80 | .type_arg_list() |
81 | .and_then(GenericArgs::from_ast) | ||
82 | .or_else(|| { | ||
83 | GenericArgs::from_fn_like_path_ast( | ||
84 | segment.param_list(), | ||
85 | segment.ret_type(), | ||
86 | ) | ||
87 | }) | ||
88 | .map(Arc::new); | ||
81 | let segment = PathSegment { name: name.as_name(), args_and_bindings: args }; | 89 | let segment = PathSegment { name: name.as_name(), args_and_bindings: args }; |
82 | segments.push(segment); | 90 | segments.push(segment); |
83 | } | 91 | } |
@@ -187,6 +195,34 @@ impl GenericArgs { | |||
187 | } | 195 | } |
188 | } | 196 | } |
189 | 197 | ||
198 | /// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y) | ||
199 | /// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`). | ||
200 | pub(crate) fn from_fn_like_path_ast( | ||
201 | params: Option<ast::ParamList>, | ||
202 | ret_type: Option<ast::RetType>, | ||
203 | ) -> Option<GenericArgs> { | ||
204 | let mut args = Vec::new(); | ||
205 | let mut bindings = Vec::new(); | ||
206 | if let Some(params) = params { | ||
207 | let mut param_types = Vec::new(); | ||
208 | for param in params.params() { | ||
209 | let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); | ||
210 | param_types.push(type_ref); | ||
211 | } | ||
212 | let arg = GenericArg::Type(TypeRef::Tuple(param_types)); | ||
213 | args.push(arg); | ||
214 | } | ||
215 | if let Some(ret_type) = ret_type { | ||
216 | let type_ref = TypeRef::from_ast_opt(ret_type.type_ref()); | ||
217 | bindings.push((name::OUTPUT, type_ref)) | ||
218 | } | ||
219 | if args.is_empty() && bindings.is_empty() { | ||
220 | None | ||
221 | } else { | ||
222 | Some(GenericArgs { args, has_self_type: false, bindings }) | ||
223 | } | ||
224 | } | ||
225 | |||
190 | pub(crate) fn empty() -> GenericArgs { | 226 | pub(crate) fn empty() -> GenericArgs { |
191 | GenericArgs { args: Vec::new(), has_self_type: false, bindings: Vec::new() } | 227 | GenericArgs { args: Vec::new(), has_self_type: false, bindings: Vec::new() } |
192 | } | 228 | } |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 17c4e3556..c414e6a95 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -3736,7 +3736,7 @@ fn fn_trait() { | |||
3736 | trait FnOnce<Args> { | 3736 | trait FnOnce<Args> { |
3737 | type Output; | 3737 | type Output; |
3738 | 3738 | ||
3739 | fn call_once(self, args: Args) -> Self::Output; | 3739 | fn call_once(self, args: Args) -> <Self as FnOnce<Args>>::Output; |
3740 | } | 3740 | } |
3741 | 3741 | ||
3742 | fn test<F: FnOnce(u32, u64) -> u128>(f: F) { | 3742 | fn test<F: FnOnce(u32, u64) -> u128>(f: F) { |
@@ -3746,13 +3746,13 @@ fn test<F: FnOnce(u32, u64) -> u128>(f: F) { | |||
3746 | @r###" | 3746 | @r###" |
3747 | [57; 61) 'self': Self | 3747 | [57; 61) 'self': Self |
3748 | [63; 67) 'args': Args | 3748 | [63; 67) 'args': Args |
3749 | [132; 133) 'f': F | 3749 | [150; 151) 'f': F |
3750 | [138; 166) '{ ...2)); }': () | 3750 | [156; 184) '{ ...2)); }': () |
3751 | [144; 145) 'f': F | 3751 | [162; 163) 'f': F |
3752 | [144; 163) 'f.call...1, 2))': {unknown} | 3752 | [162; 181) 'f.call...1, 2))': {unknown} |
3753 | [156; 162) '(1, 2)': (i32, i32) | 3753 | [174; 180) '(1, 2)': (u32, u64) |
3754 | [157; 158) '1': i32 | 3754 | [175; 176) '1': u32 |
3755 | [160; 161) '2': i32 | 3755 | [178; 179) '2': u64 |
3756 | "### | 3756 | "### |
3757 | ); | 3757 | ); |
3758 | } | 3758 | } |
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index bcf753f78..d274b6fbc 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -2312,6 +2312,12 @@ impl PathSegment { | |||
2312 | pub fn type_arg_list(&self) -> Option<TypeArgList> { | 2312 | pub fn type_arg_list(&self) -> Option<TypeArgList> { |
2313 | AstChildren::new(&self.syntax).next() | 2313 | AstChildren::new(&self.syntax).next() |
2314 | } | 2314 | } |
2315 | pub fn param_list(&self) -> Option<ParamList> { | ||
2316 | AstChildren::new(&self.syntax).next() | ||
2317 | } | ||
2318 | pub fn ret_type(&self) -> Option<RetType> { | ||
2319 | AstChildren::new(&self.syntax).next() | ||
2320 | } | ||
2315 | } | 2321 | } |
2316 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 2322 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
2317 | pub struct PathType { | 2323 | pub struct PathType { |
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 3e6c2d3f3..993e58e64 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -684,7 +684,7 @@ Grammar( | |||
684 | ] | 684 | ] |
685 | ), | 685 | ), |
686 | "PathSegment": ( | 686 | "PathSegment": ( |
687 | options: [ "NameRef", "TypeArgList" ] | 687 | options: [ "NameRef", "TypeArgList", "ParamList", "RetType" ] |
688 | ), | 688 | ), |
689 | "TypeArgList": (collections: [ | 689 | "TypeArgList": (collections: [ |
690 | ("type_args", "TypeArg"), | 690 | ("type_args", "TypeArg"), |