Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/handlers/replace_if_let_with_match.rs')
| -rw-r--r-- | crates/ide-assists/src/handlers/replace_if_let_with_match.rs | 702 |
1 files changed, 698 insertions, 4 deletions
diff --git a/crates/ide-assists/src/handlers/replace_if_let_with_match.rs b/crates/ide-assists/src/handlers/replace_if_let_with_match.rs index 56dd6cf29a..4313cc1ac9 100644 --- a/crates/ide-assists/src/handlers/replace_if_let_with_match.rs +++ b/crates/ide-assists/src/handlers/replace_if_let_with_match.rs @@ -17,7 +17,7 @@ use syntax::{ }; use crate::{ - utils::{does_nested_pattern, does_pat_match_variant, unwrap_trivial_block}, + utils::{does_pat_match_variant, does_pat_variant_nested_or_literal, unwrap_trivial_block}, AssistContext, AssistId, AssistKind, Assists, }; @@ -163,7 +163,7 @@ fn make_else_arm( Some(it) => { if does_pat_match_variant(pat, &it.sad_pattern()) { it.happy_pattern_wildcard() - } else if does_nested_pattern(pat) { + } else if does_pat_variant_nested_or_literal(ctx, pat) { make::wildcard_pat().into() } else { it.sad_pattern() @@ -702,11 +702,11 @@ fn main() { } #[test] - fn nested_type() { + fn test_if_let_with_match_nested_tuple_struct() { check_assist( replace_if_let_with_match, r#" -//- minicore: result +//- minicore: result, option fn foo(x: Result<i32, ()>) { let bar: Result<_, ()> = Ok(Some(1)); $0if let Ok(Some(_)) = bar { @@ -726,6 +726,700 @@ fn foo(x: Result<i32, ()>) { } "#, ); + + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +struct MyStruct(i32, i32); +fn foo(x: Result<MyStruct, ()>) { + let bar: Result<MyStruct, ()> = Ok(MyStruct(1, 2)); + $0if let Ok(MyStruct(a, b)) = bar { + () + } else { + () + } +} +"#, + r#" +struct MyStruct(i32, i32); +fn foo(x: Result<MyStruct, ()>) { + let bar: Result<MyStruct, ()> = Ok(MyStruct(1, 2)); + match bar { + Ok(MyStruct(a, b)) => (), + Err(_) => (), + } +} +"#, + ); + } + + #[test] + fn test_if_let_with_match_nested_slice() { + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<&[i32], ()>) { + let foo: Result<&[_], ()> = Ok(&[0, 1, 2]); + $0if let Ok([]) = foo { + () + } else { + () + } +} + "#, + r#" +fn foo(x: Result<&[i32], ()>) { + let foo: Result<&[_], ()> = Ok(&[0, 1, 2]); + match foo { + Ok([]) => (), + _ => (), + } +} + "#, + ); + + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<[&'static str; 2], ()>) { + let foobar: Result<_, ()> = Ok(["foo", "bar"]); + $0if let Ok([_, "bar"]) = foobar { + () + } else { + () + } +} +"#, + r#" +fn foo(x: Result<[&'static str; 2], ()>) { + let foobar: Result<_, ()> = Ok(["foo", "bar"]); + match foobar { + Ok([_, "bar"]) => (), + _ => (), + } +} +"#, + ); + + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<[&'static str; 2], ()>) { + let foobar: Result<_, ()> = Ok(["foo", "bar"]); + $0if let Ok([..]) = foobar { + () + } else { + () + } +} +"#, + r#" +fn foo(x: Result<[&'static str; 2], ()>) { + let foobar: Result<_, ()> = Ok(["foo", "bar"]); + match foobar { + Ok([..]) => (), + Err(_) => (), + } +} +"#, + ); + + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<&[&'static str], ()>) { + let foobar: Result<&[&'static str], ()> = Ok(&["foo", "bar"]); + $0if let Ok([a, ..]) = foobar { + () + } else { + () + } +} +"#, + r#" +fn foo(x: Result<&[&'static str], ()>) { + let foobar: Result<&[&'static str], ()> = Ok(&["foo", "bar"]); + match foobar { + Ok([a, ..]) => (), + _ => (), + } +} +"#, + ); + + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<&[&'static str], ()>) { + let foobar: Result<&[&'static str], ()> = Ok(&["foo", "bar"]); + $0if let Ok([a, .., b, c]) = foobar { + () + } else { + () + } +} +"#, + r#" +fn foo(x: Result<&[&'static str], ()>) { + let foobar: Result<&[&'static str], ()> = Ok(&["foo", "bar"]); + match foobar { + Ok([a, .., b, c]) => (), + _ => (), + } +} +"#, + ); + + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<Option<[&'static str; 2]>, ()>) { + let foobar: Result<_, ()> = Ok(Some(["foo", "bar"])); + $0if let Ok(Some([_, "bar"])) = foobar { + () + } else { + () + } +} +"#, + r#" +fn foo(x: Result<Option<[&'static str; 2]>, ()>) { + let foobar: Result<_, ()> = Ok(Some(["foo", "bar"])); + match foobar { + Ok(Some([_, "bar"])) => (), + _ => (), + } +} +"#, + ); + } + + #[test] + fn test_if_let_with_match_nested_literal() { + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<&'static str, ()>) { + let bar: Result<&_, ()> = Ok("bar"); + $0if let Ok("foo") = bar { + () + } else { + () + } +} +"#, + r#" +fn foo(x: Result<&'static str, ()>) { + let bar: Result<&_, ()> = Ok("bar"); + match bar { + Ok("foo") => (), + _ => (), + } +} +"#, + ); + } + + #[test] + fn test_if_let_with_match_nested_tuple() { + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<(i32, i32, i32), ()>) { + let bar: Result<(i32, i32, i32), ()> = Ok((1, 2, 3)); + $0if let Ok((1, second, third)) = bar { + () + } else { + () + } +} +"#, + r#" +fn foo(x: Result<(i32, i32, i32), ()>) { + let bar: Result<(i32, i32, i32), ()> = Ok((1, 2, 3)); + match bar { + Ok((1, second, third)) => (), + _ => (), + } +} +"#, + ); + + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<(i32, i32, i32), ()>) { + let bar: Result<(i32, i32, i32), ()> = Ok((1, 2, 3)); + $0if let Ok((first, second, third)) = bar { + () + } else { + () + } +} +"#, + r#" +fn foo(x: Result<(i32, i32, i32), ()>) { + let bar: Result<(i32, i32, i32), ()> = Ok((1, 2, 3)); + match bar { + Ok((first, second, third)) => (), + Err(_) => (), + } +} +"#, + ); + } + + #[test] + fn test_if_let_with_match_nested_or() { + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<i32, ()>) { + let bar: Result<i32, ()> = Ok(1); + $0if let Ok(1 | 2) = bar { + () + } else { + () + } +} +"#, + r#" +fn foo(x: Result<i32, ()>) { + let bar: Result<i32, ()> = Ok(1); + match bar { + Ok(1 | 2) => (), + _ => (), + } +} +"#, + ); + + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<(i32, i32), ()>) { + let bar: Result<(i32, i32), ()> = Ok((1, 2)); + $0if let Ok((b, a) | (a, b)) = bar { + () + } else { + () + } +} +"#, + r#" +fn foo(x: Result<(i32, i32), ()>) { + let bar: Result<(i32, i32), ()> = Ok((1, 2)); + match bar { + Ok((b, a) | (a, b)) => (), + Err(_) => (), + } +} +"#, + ); + + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<(i32, i32), ()>) { + let bar: Result<(i32, i32), ()> = Ok((1, 2)); + $0if let Ok((1, a) | (a, 2)) = bar { + () + } else { + () + } +} +"#, + r#" +fn foo(x: Result<(i32, i32), ()>) { + let bar: Result<(i32, i32), ()> = Ok((1, 2)); + match bar { + Ok((1, a) | (a, 2)) => (), + _ => (), + } +} +"#, + ); + } + + #[test] + fn test_if_let_with_match_nested_range() { + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<i32, ()>) { + let bar: Result<i32, ()> = Ok(1); + $0if let Ok(1..2) = bar { + () + } else { + () + } +} +"#, + r#" +fn foo(x: Result<i32, ()>) { + let bar: Result<i32, ()> = Ok(1); + match bar { + Ok(1..2) => (), + _ => (), + } +} +"#, + ); + } + + #[test] + fn test_if_let_with_match_nested_paren() { + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<(i32, i32), ()>) { + let bar: Result<(i32, i32), ()> = Ok((1, 1)); + $0if let Ok(((1, 2))) = bar { + () + } else { + () + } +} +"#, + r#" +fn foo(x: Result<(i32, i32), ()>) { + let bar: Result<(i32, i32), ()> = Ok((1, 1)); + match bar { + Ok(((1, 2))) => (), + _ => (), + } +} +"#, + ); + + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<(i32, i32), ()>) { + let bar: Result<(i32, i32), ()> = Ok((1, 1)); + $0if let Ok(((a, b))) = bar { + () + } else { + () + } +} +"#, + r#" +fn foo(x: Result<(i32, i32), ()>) { + let bar: Result<(i32, i32), ()> = Ok((1, 1)); + match bar { + Ok(((a, b))) => (), + Err(_) => (), + } +} +"#, + ); + } + + #[test] + fn test_if_let_with_match_nested_macro() { + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<i32, ()>) { + macro_rules! is_42 { + () => { + 42 + }; + } + + let bar: Result<i32, ()> = Ok(1); + $0if let Ok(is_42!()) = bar { + () + } else { + () + } +} +"#, + r#" +fn foo(x: Result<i32, ()>) { + macro_rules! is_42 { + () => { + 42 + }; + } + + let bar: Result<i32, ()> = Ok(1); + match bar { + Ok(is_42!()) => (), + _ => (), + } +} +"#, + ); + } + + #[test] + fn test_if_let_with_match_nested_path() { + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +enum MyEnum { + Foo, + Bar, +} + +fn foo(x: Result<MyEnum, ()>) { + let bar: Result<MyEnum, ()> = Ok(MyEnum::Foo); + $0if let Ok(MyEnum::Foo) = bar { + () + } else { + () + } +} +"#, + r#" +enum MyEnum { + Foo, + Bar, +} + +fn foo(x: Result<MyEnum, ()>) { + let bar: Result<MyEnum, ()> = Ok(MyEnum::Foo); + match bar { + Ok(MyEnum::Foo) => (), + _ => (), + } +} +"#, + ); + } + + #[test] + fn test_if_let_with_match_nested_record() { + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +struct MyStruct { + foo: i32, + bar: i32, +} + +fn foo(x: Result<MyStruct, ()>) { + let bar: Result<MyStruct, ()> = Ok(MyStruct { foo: 1, bar: 2 }); + $0if let Ok(MyStruct { foo, bar }) = bar { + () + } else { + () + } +} +"#, + r#" +struct MyStruct { + foo: i32, + bar: i32, +} + +fn foo(x: Result<MyStruct, ()>) { + let bar: Result<MyStruct, ()> = Ok(MyStruct { foo: 1, bar: 2 }); + match bar { + Ok(MyStruct { foo, bar }) => (), + Err(_) => (), + } +} +"#, + ); + + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +struct MyStruct { + foo: i32, + bar: i32, +} + +fn foo(x: Result<MyStruct, ()>) { + let bar: Result<MyStruct, ()> = Ok(MyStruct { foo: 1, bar: 2 }); + $0if let Ok(MyStruct { foo, bar: 12 }) = bar { + () + } else { + () + } +} +"#, + r#" +struct MyStruct { + foo: i32, + bar: i32, +} + +fn foo(x: Result<MyStruct, ()>) { + let bar: Result<MyStruct, ()> = Ok(MyStruct { foo: 1, bar: 2 }); + match bar { + Ok(MyStruct { foo, bar: 12 }) => (), + _ => (), + } +} +"#, + ); + + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +struct MyStruct { + foo: i32, + bar: i32, +} + +fn foo(x: Result<MyStruct, ()>) { + let bar: Result<MyStruct, ()> = Ok(MyStruct { foo: 1, bar: 2 }); + $0if let Ok(MyStruct { foo, .. }) = bar { + () + } else { + () + } +} +"#, + r#" +struct MyStruct { + foo: i32, + bar: i32, +} + +fn foo(x: Result<MyStruct, ()>) { + let bar: Result<MyStruct, ()> = Ok(MyStruct { foo: 1, bar: 2 }); + match bar { + Ok(MyStruct { foo, .. }) => (), + Err(_) => (), + } +} +"#, + ); + + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +enum MyEnum { + Foo(i32, i32), + Bar { a: i32, b: i32 }, +} + +fn foo(x: Result<MyEnum, ()>) { + let bar: Result<MyEnum, ()> = Ok(MyEnum::Foo(1, 2)); + $0if let Ok(MyEnum::Bar { a, b }) = bar { + () + } else { + () + } +} +"#, + r#" +enum MyEnum { + Foo(i32, i32), + Bar { a: i32, b: i32 }, +} + +fn foo(x: Result<MyEnum, ()>) { + let bar: Result<MyEnum, ()> = Ok(MyEnum::Foo(1, 2)); + match bar { + Ok(MyEnum::Bar { a, b }) => (), + _ => (), + } +} +"#, + ); + } + + #[test] + fn test_if_let_with_match_nested_ident() { + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<i32, ()>) { + let bar: Result<i32, ()> = Ok(1); + $0if let Ok(a @ 1..2) = bar { + () + } else { + () + } +} +"#, + r#" +fn foo(x: Result<i32, ()>) { + let bar: Result<i32, ()> = Ok(1); + match bar { + Ok(a @ 1..2) => (), + _ => (), + } +} +"#, + ); + + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<i32, ()>) { + let bar: Result<i32, ()> = Ok(1); + $0if let Ok(a) = bar { + () + } else { + () + } +} +"#, + r#" +fn foo(x: Result<i32, ()>) { + let bar: Result<i32, ()> = Ok(1); + match bar { + Ok(a) => (), + Err(_) => (), + } +} +"#, + ); + + check_assist( + replace_if_let_with_match, + r#" +//- minicore: result +fn foo(x: Result<i32, ()>) { + let bar: Result<i32, ()> = Ok(1); + $0if let Ok(a @ b @ c @ d) = bar { + () + } else { + () + } +} +"#, + r#" +fn foo(x: Result<i32, ()>) { + let bar: Result<i32, ()> = Ok(1); + match bar { + Ok(a @ b @ c @ d) => (), + Err(_) => (), + } +} +"#, + ); } #[test] |