diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs index 62ef4081828..787eb2fd3f3 100644 --- a/crates/ide_completion/src/context.rs +++ b/crates/ide_completion/src/context.rs @@ -313,7 +313,8 @@ fn expected_type_and_name(&self) -> (Option, Option) { cov_mark::hit!(expected_type_let_with_leading_char); cov_mark::hit!(expected_type_let_without_leading_char); let ty = it.pat() - .and_then(|pat| self.sema.type_of_pat(&pat)); + .and_then(|pat| self.sema.type_of_pat(&pat)) + .or_else(|| it.initializer().and_then(|it| self.sema.type_of_expr(&it))); let name = if let Some(ast::Pat::IdentPat(ident)) = it.pat() { ident.name().map(NameOrNameRef::Name) } else { @@ -719,6 +720,26 @@ fn foo() { ); } + #[test] + fn expected_type_let_pat() { + check_expected_type_and_name( + r#" +fn foo() { + let x$0 = 0u32; +} +"#, + expect![[r#"ty: u32, name: ?"#]], + ); + check_expected_type_and_name( + r#" +fn foo() { + let $0 = 0u32; +} +"#, + expect![[r#"ty: u32, name: ?"#]], + ); + } + #[test] fn expected_type_fn_param_without_leading_char() { cov_mark::check!(expected_type_fn_param_without_leading_char); diff --git a/crates/parser/src/grammar/patterns.rs b/crates/parser/src/grammar/patterns.rs index 3ab34783454..f1d1f9eaa60 100644 --- a/crates/parser/src/grammar/patterns.rs +++ b/crates/parser/src/grammar/patterns.rs @@ -83,7 +83,7 @@ fn pattern_single_r(p: &mut Parser, recovery_set: TokenSet) { } const PAT_RECOVERY_SET: TokenSet = - TokenSet::new(&[T![let], T![if], T![while], T![loop], T![match], T![')'], T![,]]); + TokenSet::new(&[T![let], T![if], T![while], T![loop], T![match], T![')'], T![,], T![=]]); fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option { let m = match p.nth(0) {