diff options
author | Dawer <[email protected]> | 2021-04-18 12:43:12 +0100 |
---|---|---|
committer | Dawer <[email protected]> | 2021-04-18 12:54:09 +0100 |
commit | 51d65caed490122a492622f3ffba4f0f8a81a9e0 (patch) | |
tree | 996cbddb9dda6585a3cf7ddfc16ead8b9ff82e48 /crates | |
parent | 76285f16deabe8175f0bfa9ebd913b9edef302f8 (diff) |
Prevent adding useless match arms
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ide_assists/src/handlers/fill_match_arms.rs | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/crates/ide_assists/src/handlers/fill_match_arms.rs b/crates/ide_assists/src/handlers/fill_match_arms.rs index 6408d7f0b..800ce972c 100644 --- a/crates/ide_assists/src/handlers/fill_match_arms.rs +++ b/crates/ide_assists/src/handlers/fill_match_arms.rs | |||
@@ -8,7 +8,7 @@ use itertools::Itertools; | |||
8 | use syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat}; | 8 | use syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat}; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | utils::{does_pat_match_variant, render_snippet, Cursor}, | 11 | utils::{self, render_snippet, Cursor}, |
12 | AssistContext, AssistId, AssistKind, Assists, | 12 | AssistContext, AssistId, AssistKind, Assists, |
13 | }; | 13 | }; |
14 | 14 | ||
@@ -135,14 +135,18 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option< | |||
135 | } | 135 | } |
136 | 136 | ||
137 | fn is_variant_missing(existing_pats: &[Pat], var: &Pat) -> bool { | 137 | fn is_variant_missing(existing_pats: &[Pat], var: &Pat) -> bool { |
138 | !existing_pats.iter().any(|pat| match (pat, var) { | 138 | !existing_pats.iter().any(|pat| does_pat_match_variant(pat, var)) |
139 | } | ||
140 | |||
141 | // Fixme: this is still somewhat limited, use hir_ty::diagnostics::match_check? | ||
142 | fn does_pat_match_variant(pat: &Pat, var: &Pat) -> bool { | ||
143 | match (pat, var) { | ||
144 | (Pat::WildcardPat(_), _) => true, | ||
139 | (Pat::TuplePat(tpat), Pat::TuplePat(tvar)) => { | 145 | (Pat::TuplePat(tpat), Pat::TuplePat(tvar)) => { |
140 | // `does_pat_match_variant` gives false positives for tuple patterns | ||
141 | // Fixme: this is still somewhat limited | ||
142 | tpat.fields().zip(tvar.fields()).all(|(p, v)| does_pat_match_variant(&p, &v)) | 146 | tpat.fields().zip(tvar.fields()).all(|(p, v)| does_pat_match_variant(&p, &v)) |
143 | } | 147 | } |
144 | _ => does_pat_match_variant(pat, var), | 148 | _ => utils::does_pat_match_variant(pat, var), |
145 | }) | 149 | } |
146 | } | 150 | } |
147 | 151 | ||
148 | fn resolve_enum_def(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<hir::Enum> { | 152 | fn resolve_enum_def(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<hir::Enum> { |
@@ -504,11 +508,6 @@ fn main() { | |||
504 | ); | 508 | ); |
505 | } | 509 | } |
506 | 510 | ||
507 | // Fixme: This fails with extra useless match arms added. | ||
508 | // To fix, it needs full fledged match exhaustiveness checking from | ||
509 | // hir_ty::diagnostics::match_check | ||
510 | // see https://github.com/rust-analyzer/rust-analyzer/issues/8493 | ||
511 | #[ignore] | ||
512 | #[test] | 511 | #[test] |
513 | fn fill_match_arms_tuple_of_enum_partial_with_wildcards() { | 512 | fn fill_match_arms_tuple_of_enum_partial_with_wildcards() { |
514 | let ra_fixture = r#" | 513 | let ra_fixture = r#" |
@@ -539,6 +538,23 @@ fn main() { | |||
539 | } | 538 | } |
540 | 539 | ||
541 | #[test] | 540 | #[test] |
541 | fn fill_match_arms_partial_with_deep_pattern() { | ||
542 | // Fixme: cannot handle deep patterns | ||
543 | let ra_fixture = r#" | ||
544 | fn main() { | ||
545 | match $0Some(true) { | ||
546 | Some(true) => {} | ||
547 | None => {} | ||
548 | } | ||
549 | } | ||
550 | "#; | ||
551 | check_assist_not_applicable( | ||
552 | fill_match_arms, | ||
553 | &format!("//- /main.rs crate:main deps:core{}{}", ra_fixture, FamousDefs::FIXTURE), | ||
554 | ); | ||
555 | } | ||
556 | |||
557 | #[test] | ||
542 | fn fill_match_arms_tuple_of_enum_not_applicable() { | 558 | fn fill_match_arms_tuple_of_enum_not_applicable() { |
543 | check_assist_not_applicable( | 559 | check_assist_not_applicable( |
544 | fill_match_arms, | 560 | fill_match_arms, |