mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Add assignment type analysis for ide-completion
This commit is contained in:
parent
922e04a134
commit
22d6136462
@ -562,6 +562,7 @@ fn expected_type_and_name<'db>(
|
||||
token: &SyntaxToken,
|
||||
name_like: &ast::NameLike,
|
||||
) -> (Option<Type<'db>>, Option<NameOrNameRef>) {
|
||||
let token = prev_assign_token_at_whitespace(token.clone());
|
||||
let mut node = match token.parent() {
|
||||
Some(it) => it,
|
||||
None => return (None, None),
|
||||
@ -632,6 +633,17 @@ fn expected_type_and_name<'db>(
|
||||
.map(TypeInfo::original);
|
||||
(ty, None)
|
||||
},
|
||||
ast::BinExpr(it) => {
|
||||
if let Some(ast::BinaryOp::Assignment { op: None }) = it.op_kind() {
|
||||
let ty = it.lhs()
|
||||
.and_then(|lhs| sema.type_of_expr(&lhs))
|
||||
.or_else(|| it.rhs().and_then(|rhs| sema.type_of_expr(&rhs)))
|
||||
.map(TypeInfo::original);
|
||||
(ty, None)
|
||||
} else {
|
||||
(None, None)
|
||||
}
|
||||
},
|
||||
ast::ArgList(_) => {
|
||||
cov_mark::hit!(expected_type_fn_param);
|
||||
ActiveParameter::at_token(
|
||||
@ -1870,3 +1882,23 @@ fn next_non_trivia_sibling(ele: SyntaxElement) -> Option<SyntaxElement> {
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn prev_assign_token_at_whitespace(mut token: SyntaxToken) -> SyntaxToken {
|
||||
while token.kind() == SyntaxKind::WHITESPACE
|
||||
&& let Some(prev) = token.prev_token()
|
||||
&& let T![=]
|
||||
| T![+=]
|
||||
| T![/=]
|
||||
| T![*=]
|
||||
| T![%=]
|
||||
| T![>>=]
|
||||
| T![<<=]
|
||||
| T![-=]
|
||||
| T![|=]
|
||||
| T![&=]
|
||||
| T![^=] = prev.kind()
|
||||
{
|
||||
token = prev
|
||||
}
|
||||
token
|
||||
}
|
||||
|
@ -434,3 +434,53 @@ fn f(thing: u32) -> &u32 {
|
||||
expect!["ty: u32, name: ?"],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn expected_type_assign() {
|
||||
check_expected_type_and_name(
|
||||
r#"
|
||||
enum State { Stop }
|
||||
fn foo() {
|
||||
let x: &mut State = &mut State::Stop;
|
||||
x = $0;
|
||||
}
|
||||
"#,
|
||||
expect![[r#"ty: &'_ mut State, name: ?"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn expected_type_deref_assign() {
|
||||
check_expected_type_and_name(
|
||||
r#"
|
||||
enum State { Stop }
|
||||
fn foo() {
|
||||
let x: &mut State = &mut State::Stop;
|
||||
match x {
|
||||
State::Stop => {
|
||||
*x = $0;
|
||||
},
|
||||
}
|
||||
}
|
||||
"#,
|
||||
expect![[r#"ty: State, name: ?"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn expected_type_deref_assign_at_block_end() {
|
||||
check_expected_type_and_name(
|
||||
r#"
|
||||
enum State { Stop }
|
||||
fn foo() {
|
||||
let x: &mut State = &mut State::Stop;
|
||||
match x {
|
||||
State::Stop => {
|
||||
*x = $0
|
||||
},
|
||||
}
|
||||
}
|
||||
"#,
|
||||
expect![[r#"ty: State, name: ?"#]],
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user