10720: fix: Don't ascribe types in pattern completion for param patterns twice r=Veykril a=Veykril

Fixes #10323
bors r+

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
bors[bot] 2021-11-08 13:12:03 +00:00 committed by GitHub
commit c5c11b87cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 9 deletions

View file

@ -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: ?"#]],
);
}
}

View file

@ -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(' ');

View file

@ -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]