Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/ide_completion/src/context.rs38
-rw-r--r--crates/ide_completion/src/render/pattern.rs6
-rw-r--r--crates/ide_completion/src/tests/pattern.rs15
3 files changed, 50 insertions, 9 deletions
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index 0cb484d507..ac01968126 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -58,6 +58,7 @@ pub(crate) struct PathCompletionContext {
pub(super) struct PatternContext {
pub(super) refutability: PatternRefutability,
pub(super) is_param: Option<ParamKind>,
+ pub(super) has_type_ascription: bool,
}
#[derive(Debug)]
@@ -597,7 +598,8 @@ impl<'a> CompletionContext<'a> {
.map(|c| (Some(c.return_type()), None))
.unwrap_or((None, None))
},
- ast::Stmt(_it) => (None, None),
+ ast::ParamList(__) => (None, None),
+ ast::Stmt(__) => (None, None),
ast::Item(__) => (None, None),
_ => {
match node.parent() {
@@ -708,15 +710,15 @@ impl<'a> CompletionContext<'a> {
return None;
}
let mut is_param = None;
- let refutability = bind_pat
+ let (refutability, has_type_ascription) = bind_pat
.syntax()
.ancestors()
.skip_while(|it| ast::Pat::can_cast(it.kind()))
.next()
- .map_or(PatternRefutability::Irrefutable, |node| {
- match_ast! {
+ .map_or((PatternRefutability::Irrefutable, false), |node| {
+ let refutability = match_ast! {
match node {
- ast::LetStmt(__) => PatternRefutability::Irrefutable,
+ ast::LetStmt(let_) => return (PatternRefutability::Irrefutable, let_.ty().is_some()),
ast::Param(param) => {
let is_closure_param = param
.syntax()
@@ -729,16 +731,17 @@ impl<'a> CompletionContext<'a> {
} else {
ParamKind::Function
});
- PatternRefutability::Irrefutable
+ return (PatternRefutability::Irrefutable, param.ty().is_some())
},
ast::MatchArm(__) => PatternRefutability::Refutable,
ast::Condition(__) => PatternRefutability::Refutable,
ast::ForExpr(__) => PatternRefutability::Irrefutable,
_ => PatternRefutability::Irrefutable,
}
- }
+ };
+ (refutability, false)
});
- Some(PatternContext { refutability, is_param })
+ Some(PatternContext { refutability, is_param, has_type_ascription })
}
fn classify_name_ref(
@@ -1172,4 +1175,23 @@ fn foo() {
expect![[r#"ty: Foo, name: ?"#]],
);
}
+
+ #[test]
+ fn expected_type_param_pat() {
+ check_expected_type_and_name(
+ r#"
+struct Foo { field: u32 }
+fn foo(a$0: Foo) {}
+"#,
+ expect![[r#"ty: Foo, name: ?"#]],
+ );
+ check_expected_type_and_name(
+ r#"
+struct Foo { field: u32 }
+fn foo($0: Foo) {}
+"#,
+ // FIXME make this work, currently fails due to pattern recovery eating the `:`
+ expect![[r#"ty: ?, name: ?"#]],
+ );
+ }
}
diff --git a/crates/ide_completion/src/render/pattern.rs b/crates/ide_completion/src/render/pattern.rs
index e553ec8f86..888a5b4b0a 100644
--- a/crates/ide_completion/src/render/pattern.rs
+++ b/crates/ide_completion/src/render/pattern.rs
@@ -86,7 +86,11 @@ fn render_pat(
if matches!(
ctx.completion.pattern_ctx,
- Some(PatternContext { is_param: Some(ParamKind::Function), .. })
+ Some(PatternContext {
+ is_param: Some(ParamKind::Function),
+ has_type_ascription: false,
+ ..
+ })
) {
pat.push(':');
pat.push(' ');
diff --git a/crates/ide_completion/src/tests/pattern.rs b/crates/ide_completion/src/tests/pattern.rs
index 3e10575b19..6dd1b66998 100644
--- a/crates/ide_completion/src/tests/pattern.rs
+++ b/crates/ide_completion/src/tests/pattern.rs
@@ -163,6 +163,21 @@ fn foo(a$0) {
ma makro!(…) #[macro_export] macro_rules! makro
"##]],
);
+ check(
+ r#"
+fn foo(a$0: Tuple) {
+}
+"#,
+ expect![[r##"
+ kw mut
+ bn Record Record { field$1 }$0
+ st Record
+ bn Tuple Tuple($1)$0
+ st Tuple
+ st Unit
+ ma makro!(…) #[macro_export] macro_rules! makro
+ "##]],
+ );
}
#[test]