aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDawer <[email protected]>2021-04-18 12:43:12 +0100
committerDawer <[email protected]>2021-04-18 12:54:09 +0100
commit51d65caed490122a492622f3ffba4f0f8a81a9e0 (patch)
tree996cbddb9dda6585a3cf7ddfc16ead8b9ff82e48
parent76285f16deabe8175f0bfa9ebd913b9edef302f8 (diff)
Prevent adding useless match arms
-rw-r--r--crates/ide_assists/src/handlers/fill_match_arms.rs38
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;
8use syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat}; 8use syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat};
9 9
10use crate::{ 10use 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
137fn is_variant_missing(existing_pats: &[Pat], var: &Pat) -> bool { 137fn 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?
142fn 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
148fn resolve_enum_def(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<hir::Enum> { 152fn 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#"
544fn 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,