8884: fix: add_explicit_type produces invalid code on `@` patterns r=Veykril a=iDawer

In
```rust
let name @ () = ();
```
 an explicit type should be inserted after the pattern, not just after the name.
`let` statement defined as `LetStmt = Attr* 'let' Pat (':' Type)? '=' initializer:Expr ';'`

Co-authored-by: Dawer <7803845+iDawer@users.noreply.github.com>
This commit is contained in:
bors[bot] 2021-05-19 18:30:36 +00:00 committed by GitHub
commit 2d76b176c0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,6 +1,6 @@
use hir::HirDisplay; use hir::HirDisplay;
use syntax::{ use syntax::{
ast::{self, AstNode, LetStmt, NameOwner}, ast::{self, AstNode, LetStmt},
TextRange, TextRange,
}; };
@ -31,9 +31,6 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext) -> Optio
_ => return None, _ => return None,
}; };
let pat_range = pat.syntax().text_range(); let pat_range = pat.syntax().text_range();
// The binding must have a name
let name = pat.name()?;
let name_range = name.syntax().text_range();
// Assist should only be applicable if cursor is between 'let' and '=' // Assist should only be applicable if cursor is between 'let' and '='
let cursor_in_range = { let cursor_in_range = {
@ -74,7 +71,7 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext) -> Optio
builder.replace(ascribed_ty.syntax().text_range(), inferred_type); builder.replace(ascribed_ty.syntax().text_range(), inferred_type);
} }
None => { None => {
builder.insert(name_range.end(), format!(": {}", inferred_type)); builder.insert(pat_range.end(), format!(": {}", inferred_type));
} }
}, },
) )
@ -243,6 +240,24 @@ struct Test<K, T = u8> { k: K, t: T }
fn main() { fn main() {
let test: Test<i32> = Test { t: 23u8, k: 33 }; let test: Test<i32> = Test { t: 23u8, k: 33 };
} }
"#,
);
}
#[test]
fn type_should_be_added_after_pattern() {
// LetStmt = Attr* 'let' Pat (':' Type)? '=' initializer:Expr ';'
check_assist(
add_explicit_type,
r#"
fn main() {
let $0test @ () = ();
}
"#,
r#"
fn main() {
let test @ (): () = ();
}
"#, "#,
); );
} }