diff options
author | Aleksey Kladov <[email protected]> | 2020-04-29 10:57:06 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-04-29 10:59:11 +0100 |
commit | 7c3c289dab46d1dbe9196549c81307f291e631f7 (patch) | |
tree | 9f9249e03c3ecf09bff04bc1fa80c00280ff6be6 /crates/ra_assists/src/handlers | |
parent | 73bef854ab854ab1a289944966444453e6f4aadf (diff) |
Use specific pattern when translating if-let-else to match
We *probably* should actually use the same machinery here, as we do
for fill match arms, but just special-casing options and results seems
to be a good first step.
Diffstat (limited to 'crates/ra_assists/src/handlers')
3 files changed, 76 insertions, 10 deletions
diff --git a/crates/ra_assists/src/handlers/replace_if_let_with_match.rs b/crates/ra_assists/src/handlers/replace_if_let_with_match.rs index 0a0a88f3d..9841f6980 100644 --- a/crates/ra_assists/src/handlers/replace_if_let_with_match.rs +++ b/crates/ra_assists/src/handlers/replace_if_let_with_match.rs | |||
@@ -1,11 +1,10 @@ | |||
1 | use ra_fmt::unwrap_trivial_block; | 1 | use ra_fmt::unwrap_trivial_block; |
2 | use ra_syntax::{ | 2 | use ra_syntax::{ |
3 | ast::{self, make}, | 3 | ast::{self, edit::IndentLevel, make}, |
4 | AstNode, | 4 | AstNode, |
5 | }; | 5 | }; |
6 | 6 | ||
7 | use crate::{Assist, AssistCtx, AssistId}; | 7 | use crate::{utils::TryEnum, Assist, AssistCtx, AssistId}; |
8 | use ast::edit::IndentLevel; | ||
9 | 8 | ||
10 | // Assist: replace_if_let_with_match | 9 | // Assist: replace_if_let_with_match |
11 | // | 10 | // |
@@ -44,15 +43,21 @@ pub(crate) fn replace_if_let_with_match(ctx: AssistCtx) -> Option<Assist> { | |||
44 | ast::ElseBranch::IfExpr(_) => return None, | 43 | ast::ElseBranch::IfExpr(_) => return None, |
45 | }; | 44 | }; |
46 | 45 | ||
47 | ctx.add_assist(AssistId("replace_if_let_with_match"), "Replace with match", |edit| { | 46 | let sema = ctx.sema; |
47 | ctx.add_assist(AssistId("replace_if_let_with_match"), "Replace with match", move |edit| { | ||
48 | let match_expr = { | 48 | let match_expr = { |
49 | let then_arm = { | 49 | let then_arm = { |
50 | let then_expr = unwrap_trivial_block(then_block); | 50 | let then_expr = unwrap_trivial_block(then_block); |
51 | make::match_arm(vec![pat], then_expr) | 51 | make::match_arm(vec![pat.clone()], then_expr) |
52 | }; | 52 | }; |
53 | let else_arm = { | 53 | let else_arm = { |
54 | let pattern = sema | ||
55 | .type_of_pat(&pat) | ||
56 | .and_then(|ty| TryEnum::from_ty(sema, &ty)) | ||
57 | .map(|it| it.sad_pattern()) | ||
58 | .unwrap_or_else(|| make::placeholder_pat().into()); | ||
54 | let else_expr = unwrap_trivial_block(else_block); | 59 | let else_expr = unwrap_trivial_block(else_block); |
55 | make::match_arm(vec![make::placeholder_pat().into()], else_expr) | 60 | make::match_arm(vec![pattern], else_expr) |
56 | }; | 61 | }; |
57 | make::expr_match(expr, make::match_arm_list(vec![then_arm, else_arm])) | 62 | make::expr_match(expr, make::match_arm_list(vec![then_arm, else_arm])) |
58 | }; | 63 | }; |
@@ -68,6 +73,7 @@ pub(crate) fn replace_if_let_with_match(ctx: AssistCtx) -> Option<Assist> { | |||
68 | #[cfg(test)] | 73 | #[cfg(test)] |
69 | mod tests { | 74 | mod tests { |
70 | use super::*; | 75 | use super::*; |
76 | |||
71 | use crate::helpers::{check_assist, check_assist_target}; | 77 | use crate::helpers::{check_assist, check_assist_target}; |
72 | 78 | ||
73 | #[test] | 79 | #[test] |
@@ -145,4 +151,64 @@ impl VariantData { | |||
145 | }", | 151 | }", |
146 | ); | 152 | ); |
147 | } | 153 | } |
154 | |||
155 | #[test] | ||
156 | fn special_case_option() { | ||
157 | check_assist( | ||
158 | replace_if_let_with_match, | ||
159 | r#" | ||
160 | enum Option<T> { Some(T), None } | ||
161 | use Option::*; | ||
162 | |||
163 | fn foo(x: Option<i32>) { | ||
164 | <|>if let Some(x) = x { | ||
165 | println!("{}", x) | ||
166 | } else { | ||
167 | println!("none") | ||
168 | } | ||
169 | } | ||
170 | "#, | ||
171 | r#" | ||
172 | enum Option<T> { Some(T), None } | ||
173 | use Option::*; | ||
174 | |||
175 | fn foo(x: Option<i32>) { | ||
176 | <|>match x { | ||
177 | Some(x) => println!("{}", x), | ||
178 | None => println!("none"), | ||
179 | } | ||
180 | } | ||
181 | "#, | ||
182 | ); | ||
183 | } | ||
184 | |||
185 | #[test] | ||
186 | fn special_case_result() { | ||
187 | check_assist( | ||
188 | replace_if_let_with_match, | ||
189 | r#" | ||
190 | enum Result<T, E> { Ok(T), Err(E) } | ||
191 | use Result::*; | ||
192 | |||
193 | fn foo(x: Result<i32, ()>) { | ||
194 | <|>if let Ok(x) = x { | ||
195 | println!("{}", x) | ||
196 | } else { | ||
197 | println!("none") | ||
198 | } | ||
199 | } | ||
200 | "#, | ||
201 | r#" | ||
202 | enum Result<T, E> { Ok(T), Err(E) } | ||
203 | use Result::*; | ||
204 | |||
205 | fn foo(x: Result<i32, ()>) { | ||
206 | <|>match x { | ||
207 | Ok(x) => println!("{}", x), | ||
208 | Err(_) => println!("none"), | ||
209 | } | ||
210 | } | ||
211 | "#, | ||
212 | ); | ||
213 | } | ||
148 | } | 214 | } |
diff --git a/crates/ra_assists/src/handlers/replace_let_with_if_let.rs b/crates/ra_assists/src/handlers/replace_let_with_if_let.rs index fb134f677..0cf23b754 100644 --- a/crates/ra_assists/src/handlers/replace_let_with_if_let.rs +++ b/crates/ra_assists/src/handlers/replace_let_with_if_let.rs | |||
@@ -11,7 +11,7 @@ use ra_syntax::{ | |||
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | assist_ctx::{Assist, AssistCtx}, | 13 | assist_ctx::{Assist, AssistCtx}, |
14 | utils::happy_try_variant, | 14 | utils::TryEnum, |
15 | AssistId, | 15 | AssistId, |
16 | }; | 16 | }; |
17 | 17 | ||
@@ -45,7 +45,7 @@ pub(crate) fn replace_let_with_if_let(ctx: AssistCtx) -> Option<Assist> { | |||
45 | let init = let_stmt.initializer()?; | 45 | let init = let_stmt.initializer()?; |
46 | let original_pat = let_stmt.pat()?; | 46 | let original_pat = let_stmt.pat()?; |
47 | let ty = ctx.sema.type_of_expr(&init)?; | 47 | let ty = ctx.sema.type_of_expr(&init)?; |
48 | let happy_variant = happy_try_variant(ctx.sema, &ty); | 48 | let happy_variant = TryEnum::from_ty(ctx.sema, &ty).map(|it| it.happy_case()); |
49 | 49 | ||
50 | ctx.add_assist(AssistId("replace_let_with_if_let"), "Replace with if-let", |edit| { | 50 | ctx.add_assist(AssistId("replace_let_with_if_let"), "Replace with if-let", |edit| { |
51 | let with_placeholder: ast::Pat = match happy_variant { | 51 | let with_placeholder: ast::Pat = match happy_variant { |
diff --git a/crates/ra_assists/src/handlers/replace_unwrap_with_match.rs b/crates/ra_assists/src/handlers/replace_unwrap_with_match.rs index 89211b44a..62d4ea522 100644 --- a/crates/ra_assists/src/handlers/replace_unwrap_with_match.rs +++ b/crates/ra_assists/src/handlers/replace_unwrap_with_match.rs | |||
@@ -5,7 +5,7 @@ use ra_syntax::{ | |||
5 | AstNode, | 5 | AstNode, |
6 | }; | 6 | }; |
7 | 7 | ||
8 | use crate::{utils::happy_try_variant, Assist, AssistCtx, AssistId}; | 8 | use crate::{utils::TryEnum, Assist, AssistCtx, AssistId}; |
9 | 9 | ||
10 | // Assist: replace_unwrap_with_match | 10 | // Assist: replace_unwrap_with_match |
11 | // | 11 | // |
@@ -37,7 +37,7 @@ pub(crate) fn replace_unwrap_with_match(ctx: AssistCtx) -> Option<Assist> { | |||
37 | } | 37 | } |
38 | let caller = method_call.expr()?; | 38 | let caller = method_call.expr()?; |
39 | let ty = ctx.sema.type_of_expr(&caller)?; | 39 | let ty = ctx.sema.type_of_expr(&caller)?; |
40 | let happy_variant = happy_try_variant(ctx.sema, &ty)?; | 40 | let happy_variant = TryEnum::from_ty(ctx.sema, &ty)?.happy_case(); |
41 | 41 | ||
42 | ctx.add_assist(AssistId("replace_unwrap_with_match"), "Replace unwrap with match", |edit| { | 42 | ctx.add_assist(AssistId("replace_unwrap_with_match"), "Replace unwrap with match", |edit| { |
43 | let ok_path = make::path_unqualified(make::path_segment(make::name_ref(happy_variant))); | 43 | let ok_path = make::path_unqualified(make::path_segment(make::name_ref(happy_variant))); |