Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #14123 - dqkqd:discard-postfix-completion-for-indivisble-expr, r=Veykril
fix: Don't trigger postfix completion in `if` block which has an `else` block Fix #14096
bors 2023-02-14
parent a33e9d9 · parent 0285acc · commit 3812951
-rw-r--r--crates/ide-completion/src/completions/postfix.rs12
-rw-r--r--crates/ide-completion/src/context/analysis.rs28
2 files changed, 40 insertions, 0 deletions
diff --git a/crates/ide-completion/src/completions/postfix.rs b/crates/ide-completion/src/completions/postfix.rs
index 90c523735d..c55bd9aaae 100644
--- a/crates/ide-completion/src/completions/postfix.rs
+++ b/crates/ide-completion/src/completions/postfix.rs
@@ -747,4 +747,16 @@ fn main() {
"#,
);
}
+
+ #[test]
+ fn no_postfix_completions_in_if_block_that_has_an_else() {
+ check(
+ r#"
+fn test() {
+ if true {}.$0 else {}
+}
+"#,
+ expect![[r#""#]],
+ );
+ }
}
diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs
index 4bff665ab1..4c66f95903 100644
--- a/crates/ide-completion/src/context/analysis.rs
+++ b/crates/ide-completion/src/context/analysis.rs
@@ -605,6 +605,18 @@ fn classify_name_ref(
},
_ => false,
};
+
+ let reciever_is_part_of_indivisible_expression = match &receiver {
+ Some(ast::Expr::IfExpr(_)) => {
+ let next_token_kind = next_non_trivia_token(name_ref.syntax().clone()).map(|t| t.kind());
+ next_token_kind == Some(SyntaxKind::ELSE_KW)
+ },
+ _ => false
+ };
+ if reciever_is_part_of_indivisible_expression {
+ return None;
+ }
+
let kind = NameRefKind::DotAccess(DotAccess {
receiver_ty: receiver.as_ref().and_then(|it| sema.type_of_expr(it)),
kind: DotAccessKind::Field { receiver_is_ambiguous_float_literal },
@@ -1317,6 +1329,22 @@ fn previous_non_trivia_token(e: impl Into<SyntaxElement>) -> Option<SyntaxToken>
None
}
+fn next_non_trivia_token(e: impl Into<SyntaxElement>) -> Option<SyntaxToken> {
+ let mut token = match e.into() {
+ SyntaxElement::Node(n) => n.last_token()?,
+ SyntaxElement::Token(t) => t,
+ }
+ .next_token();
+ while let Some(inner) = token {
+ if !inner.kind().is_trivia() {
+ return Some(inner);
+ } else {
+ token = inner.next_token();
+ }
+ }
+ None
+}
+
fn next_non_trivia_sibling(ele: SyntaxElement) -> Option<SyntaxElement> {
let mut e = ele.next_sibling_or_token();
while let Some(inner) = e {