diff options
author | Igor Aleksanov <[email protected]> | 2020-10-17 09:17:58 +0100 |
---|---|---|
committer | Igor Aleksanov <[email protected]> | 2020-10-17 09:17:58 +0100 |
commit | 99c435939c941fe5216c39bc136769098abbbfea (patch) | |
tree | b4259ce1810c3cd6c2bea62bae499415b764728d | |
parent | 6f573bd84f4564f11b08db720401ae16a0f42f2f (diff) |
Scan all ancestors for the impl trait block check
-rw-r--r-- | crates/ide/src/completion/completion_context.rs | 12 | ||||
-rw-r--r-- | crates/ide/src/completion/patterns.rs | 19 |
2 files changed, 17 insertions, 14 deletions
diff --git a/crates/ide/src/completion/completion_context.rs b/crates/ide/src/completion/completion_context.rs index cff0afae9..d9f90477c 100644 --- a/crates/ide/src/completion/completion_context.rs +++ b/crates/ide/src/completion/completion_context.rs | |||
@@ -18,8 +18,8 @@ use crate::{ | |||
18 | patterns::{ | 18 | patterns::{ |
19 | fn_is_prev, for_is_prev2, has_bind_pat_parent, has_block_expr_parent, | 19 | fn_is_prev, for_is_prev2, has_bind_pat_parent, has_block_expr_parent, |
20 | has_field_list_parent, has_impl_as_prev_sibling, has_impl_parent, | 20 | has_field_list_parent, has_impl_as_prev_sibling, has_impl_parent, |
21 | has_impl_trait_parent, has_item_list_or_source_file_parent, has_ref_parent, | 21 | has_item_list_or_source_file_parent, has_ref_parent, has_trait_as_prev_sibling, |
22 | has_trait_as_prev_sibling, has_trait_parent, if_is_prev, is_in_loop_body, is_match_arm, | 22 | has_trait_parent, if_is_prev, inside_impl_trait_block, is_in_loop_body, is_match_arm, |
23 | unsafe_is_prev, | 23 | unsafe_is_prev, |
24 | }, | 24 | }, |
25 | CompletionConfig, | 25 | CompletionConfig, |
@@ -87,7 +87,7 @@ pub(crate) struct CompletionContext<'a> { | |||
87 | pub(super) in_loop_body: bool, | 87 | pub(super) in_loop_body: bool, |
88 | pub(super) has_trait_parent: bool, | 88 | pub(super) has_trait_parent: bool, |
89 | pub(super) has_impl_parent: bool, | 89 | pub(super) has_impl_parent: bool, |
90 | pub(super) has_impl_trait_parent: bool, | 90 | pub(super) inside_impl_trait_block: bool, |
91 | pub(super) has_field_list_parent: bool, | 91 | pub(super) has_field_list_parent: bool, |
92 | pub(super) trait_as_prev_sibling: bool, | 92 | pub(super) trait_as_prev_sibling: bool, |
93 | pub(super) impl_as_prev_sibling: bool, | 93 | pub(super) impl_as_prev_sibling: bool, |
@@ -172,7 +172,7 @@ impl<'a> CompletionContext<'a> { | |||
172 | block_expr_parent: false, | 172 | block_expr_parent: false, |
173 | has_trait_parent: false, | 173 | has_trait_parent: false, |
174 | has_impl_parent: false, | 174 | has_impl_parent: false, |
175 | has_impl_trait_parent: false, | 175 | inside_impl_trait_block: false, |
176 | has_field_list_parent: false, | 176 | has_field_list_parent: false, |
177 | trait_as_prev_sibling: false, | 177 | trait_as_prev_sibling: false, |
178 | impl_as_prev_sibling: false, | 178 | impl_as_prev_sibling: false, |
@@ -234,7 +234,7 @@ impl<'a> CompletionContext<'a> { | |||
234 | /// Exception for this case is `impl Trait for Foo`, where we would like to hint trait method names. | 234 | /// Exception for this case is `impl Trait for Foo`, where we would like to hint trait method names. |
235 | /// - `for _ i<|>` -- obviously, it'll be "in" keyword. | 235 | /// - `for _ i<|>` -- obviously, it'll be "in" keyword. |
236 | pub(crate) fn no_completion_required(&self) -> bool { | 236 | pub(crate) fn no_completion_required(&self) -> bool { |
237 | (self.fn_is_prev && !self.has_impl_trait_parent) || self.for_is_prev2 | 237 | (self.fn_is_prev && !self.inside_impl_trait_block) || self.for_is_prev2 |
238 | } | 238 | } |
239 | 239 | ||
240 | /// The range of the identifier that is being completed. | 240 | /// The range of the identifier that is being completed. |
@@ -260,7 +260,7 @@ impl<'a> CompletionContext<'a> { | |||
260 | self.in_loop_body = is_in_loop_body(syntax_element.clone()); | 260 | self.in_loop_body = is_in_loop_body(syntax_element.clone()); |
261 | self.has_trait_parent = has_trait_parent(syntax_element.clone()); | 261 | self.has_trait_parent = has_trait_parent(syntax_element.clone()); |
262 | self.has_impl_parent = has_impl_parent(syntax_element.clone()); | 262 | self.has_impl_parent = has_impl_parent(syntax_element.clone()); |
263 | self.has_impl_trait_parent = has_impl_trait_parent(syntax_element.clone()); | 263 | self.inside_impl_trait_block = inside_impl_trait_block(syntax_element.clone()); |
264 | self.has_field_list_parent = has_field_list_parent(syntax_element.clone()); | 264 | self.has_field_list_parent = has_field_list_parent(syntax_element.clone()); |
265 | self.impl_as_prev_sibling = has_impl_as_prev_sibling(syntax_element.clone()); | 265 | self.impl_as_prev_sibling = has_impl_as_prev_sibling(syntax_element.clone()); |
266 | self.trait_as_prev_sibling = has_trait_as_prev_sibling(syntax_element.clone()); | 266 | self.trait_as_prev_sibling = has_trait_as_prev_sibling(syntax_element.clone()); |
diff --git a/crates/ide/src/completion/patterns.rs b/crates/ide/src/completion/patterns.rs index bdce7a6e7..cf6d5947d 100644 --- a/crates/ide/src/completion/patterns.rs +++ b/crates/ide/src/completion/patterns.rs | |||
@@ -35,19 +35,22 @@ fn test_has_impl_parent() { | |||
35 | check_pattern_is_applicable(r"impl A { f<|> }", has_impl_parent); | 35 | check_pattern_is_applicable(r"impl A { f<|> }", has_impl_parent); |
36 | } | 36 | } |
37 | 37 | ||
38 | pub(crate) fn has_impl_trait_parent(element: SyntaxElement) -> bool { | 38 | pub(crate) fn inside_impl_trait_block(element: SyntaxElement) -> bool { |
39 | not_same_range_ancestor(element) | 39 | // Here we search `impl` keyword up through the all ancestors, unlike in `has_impl_parent`, |
40 | .filter(|it| it.kind() == ASSOC_ITEM_LIST) | 40 | // where we only check the first parent with different text range. |
41 | .and_then(|it| it.parent()) | 41 | element |
42 | .filter(|it| it.kind() == IMPL) | 42 | .ancestors() |
43 | .find(|it| it.kind() == IMPL) | ||
43 | .map(|it| ast::Impl::cast(it).unwrap()) | 44 | .map(|it| ast::Impl::cast(it).unwrap()) |
44 | .map(|it| it.trait_().is_some()) | 45 | .map(|it| it.trait_().is_some()) |
45 | .unwrap_or(false) | 46 | .unwrap_or(false) |
46 | } | 47 | } |
47 | #[test] | 48 | #[test] |
48 | fn test_has_impl_trait_parent() { | 49 | fn test_inside_impl_trait_block() { |
49 | check_pattern_is_applicable(r"impl Foo for Bar { f<|> }", has_impl_trait_parent); | 50 | check_pattern_is_applicable(r"impl Foo for Bar { f<|> }", inside_impl_trait_block); |
50 | check_pattern_is_not_applicable(r"impl A { f<|> }", has_impl_trait_parent); | 51 | check_pattern_is_applicable(r"impl Foo for Bar { fn f<|> }", inside_impl_trait_block); |
52 | check_pattern_is_not_applicable(r"impl A { f<|> }", inside_impl_trait_block); | ||
53 | check_pattern_is_not_applicable(r"impl A { fn f<|> }", inside_impl_trait_block); | ||
51 | } | 54 | } |
52 | 55 | ||
53 | pub(crate) fn has_field_list_parent(element: SyntaxElement) -> bool { | 56 | pub(crate) fn has_field_list_parent(element: SyntaxElement) -> bool { |