aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-06-25 22:06:17 +0100
committerbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-06-25 22:06:17 +0100
commit0129790a8f84a0858abcb1448e1052caa01fc41c (patch)
treeae3054305d4ee1c610135358e377a2331eaee871 /crates
parent4b0c37bd6e4cb3d47614ec6b42fb1deef9bc9324 (diff)
parent3a2a13756f325b1dd8ddd54a0a0b24b99180fb82 (diff)
Merge #1432
1432: Make fill_match_arm work with trivial arm r=matklad a=ironyman Addresses this issue https://github.com/rust-analyzer/rust-analyzer/issues/1399 One minor issue I noticed is that complete_postfix creates an arm like this ``` match E::X { <|>_ => {}, } ``` but fill_match_arms creates arms like this ``` E::X => (), ``` Co-authored-by: ironyman <[email protected]> Co-authored-by: Changyu Li <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_assists/src/fill_match_arms.rs59
1 files changed, 57 insertions, 2 deletions
diff --git a/crates/ra_assists/src/fill_match_arms.rs b/crates/ra_assists/src/fill_match_arms.rs
index c7a8bce20..71b101b40 100644
--- a/crates/ra_assists/src/fill_match_arms.rs
+++ b/crates/ra_assists/src/fill_match_arms.rs
@@ -1,4 +1,5 @@
1use std::fmt::Write; 1use std::fmt::Write;
2use itertools::Itertools;
2 3
3use hir::{ 4use hir::{
4 AdtDef, FieldSource, HasSource, 5 AdtDef, FieldSource, HasSource,
@@ -8,13 +9,41 @@ use ra_syntax::ast::{self, AstNode};
8 9
9use crate::{AssistCtx, Assist, AssistId}; 10use crate::{AssistCtx, Assist, AssistId};
10 11
12fn is_trivial_arm(arm: &ast::MatchArm) -> bool {
13 fn single_pattern(arm: &ast::MatchArm) -> Option<ast::PatKind> {
14 let (pat,) = arm.pats().collect_tuple()?;
15 Some(pat.kind())
16 }
17 match single_pattern(arm) {
18 Some(ast::PatKind::PlaceholderPat(..)) => true,
19 _ => false,
20 }
21}
22
11pub(crate) fn fill_match_arms(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> { 23pub(crate) fn fill_match_arms(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
12 let match_expr = ctx.node_at_offset::<ast::MatchExpr>()?; 24 let match_expr = ctx.node_at_offset::<ast::MatchExpr>()?;
13 25
14 // We already have some match arms, so we don't provide any assists. 26 // We already have some match arms, so we don't provide any assists.
27 // Unless if there is only one trivial match arm possibly created
28 // by match postfix complete. Trivial match arm is the catch all arm.
15 match match_expr.match_arm_list() { 29 match match_expr.match_arm_list() {
16 Some(arm_list) if arm_list.arms().count() > 0 => { 30 Some(arm_list) => {
17 return None; 31 let mut arm_iter = arm_list.arms();
32 let first = arm_iter.next();
33
34 match first {
35 // If there arm list is empty or there is only one trivial arm, then proceed.
36 Some(arm) if is_trivial_arm(arm) => {
37 if arm_iter.next() != None {
38 return None;
39 }
40 }
41 None => {}
42
43 _ => {
44 return None;
45 }
46 }
18 } 47 }
19 _ => {} 48 _ => {}
20 } 49 }
@@ -228,4 +257,30 @@ mod tests {
228 "match E::X {}", 257 "match E::X {}",
229 ); 258 );
230 } 259 }
260
261 #[test]
262 fn fill_match_arms_trivial_arm() {
263 check_assist(
264 fill_match_arms,
265 r#"
266 enum E { X, Y }
267
268 fn main() {
269 match E::X {
270 <|>_ => {},
271 }
272 }
273 "#,
274 r#"
275 enum E { X, Y }
276
277 fn main() {
278 match <|>E::X {
279 E::X => (),
280 E::Y => (),
281 }
282 }
283 "#,
284 );
285 }
231} 286}