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) -> Option None } +fn next_non_trivia_token(e: impl Into) -> Option { + 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 { let mut e = ele.next_sibling_or_token(); while let Some(inner) = e {