Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21333 from A4-Tacks/expected-tuple-struct-pat
Fix tuple struct pat expected type
| -rw-r--r-- | crates/ide-completion/src/context/analysis.rs | 10 | ||||
| -rw-r--r-- | crates/ide-completion/src/context/tests.rs | 44 |
2 files changed, 54 insertions, 0 deletions
diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs index 4ab2850ece..bf899539a2 100644 --- a/crates/ide-completion/src/context/analysis.rs +++ b/crates/ide-completion/src/context/analysis.rs @@ -778,6 +778,16 @@ fn expected_type_and_name<'db>( let ty = sema.type_of_pat(&ast::Pat::from(it)).map(TypeInfo::original); (ty, None) }, + ast::TupleStructPat(it) => { + let fields = it.path().and_then(|path| match sema.resolve_path(&path)? { + hir::PathResolution::Def(hir::ModuleDef::Adt(adt)) => Some(adt.as_struct()?.fields(sema.db)), + hir::PathResolution::Def(hir::ModuleDef::Variant(variant)) => Some(variant.fields(sema.db)), + _ => None, + }); + let nr = it.fields().take_while(|it| it.syntax().text_range().end() <= token.text_range().start()).count(); + let ty = fields.and_then(|fields| Some(fields.get(nr)?.ty(sema.db).to_type(sema.db))); + (ty, None) + }, ast::Fn(it) => { cov_mark::hit!(expected_type_fn_ret_with_leading_char); cov_mark::hit!(expected_type_fn_ret_without_leading_char); diff --git a/crates/ide-completion/src/context/tests.rs b/crates/ide-completion/src/context/tests.rs index e97d9720e3..94d904932a 100644 --- a/crates/ide-completion/src/context/tests.rs +++ b/crates/ide-completion/src/context/tests.rs @@ -288,6 +288,50 @@ fn foo() -> Foo { } #[test] +fn expected_type_tuple_struct_pat() { + check_expected_type_and_name( + r#" +//- minicore: option +struct Foo(Option<i32>); +fn foo(x: Foo) -> Foo { + match x { Foo($0) => () } +} +"#, + expect![[r#"ty: Option<i32>, name: ?"#]], + ); + + check_expected_type_and_name( + r#" +struct Foo(i32, u32, f32); +fn foo(x: Foo) -> Foo { + match x { Foo($0) => () } +} +"#, + expect![[r#"ty: i32, name: ?"#]], + ); + + check_expected_type_and_name( + r#" +struct Foo(i32, u32, f32); +fn foo(x: Foo) -> Foo { + match x { Foo(num,$0) => () } +} +"#, + expect![[r#"ty: u32, name: ?"#]], + ); + + check_expected_type_and_name( + r#" +struct Foo(i32, u32, f32); +fn foo(x: Foo) -> Foo { + match x { Foo(num,$0,float) => () } +} +"#, + expect![[r#"ty: u32, name: ?"#]], + ); +} + +#[test] fn expected_type_if_let_without_leading_char() { cov_mark::check!(expected_type_if_let_without_leading_char); check_expected_type_and_name( |