mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 14:51:48 +00:00
feat: filter already present enum variants in match arms
This commit is contained in:
parent
68fd1ce313
commit
794988c53b
8 changed files with 114 additions and 16 deletions
|
@ -1,7 +1,7 @@
|
|||
//! Module responsible for analyzing the code surrounding the cursor for completion.
|
||||
use std::iter;
|
||||
|
||||
use hir::{Semantics, Type, TypeInfo};
|
||||
use hir::{Semantics, Type, TypeInfo, Variant};
|
||||
use ide_db::{active_parameter::ActiveParameter, RootDatabase};
|
||||
use syntax::{
|
||||
algo::{find_node_at_offset, non_trivia_sibling},
|
||||
|
@ -1111,6 +1111,9 @@ fn pattern_context_for(
|
|||
pat: ast::Pat,
|
||||
) -> PatternContext {
|
||||
let mut param_ctx = None;
|
||||
|
||||
let mut missing_variants = vec![];
|
||||
|
||||
let (refutability, has_type_ascription) =
|
||||
pat
|
||||
.syntax()
|
||||
|
@ -1140,7 +1143,52 @@ fn pattern_context_for(
|
|||
})();
|
||||
return (PatternRefutability::Irrefutable, has_type_ascription)
|
||||
},
|
||||
ast::MatchArm(_) => PatternRefutability::Refutable,
|
||||
ast::MatchArm(match_arm) => {
|
||||
let missing_variants_opt = match_arm
|
||||
.syntax()
|
||||
.parent()
|
||||
.and_then(ast::MatchArmList::cast)
|
||||
.and_then(|match_arm_list| {
|
||||
match_arm_list
|
||||
.syntax()
|
||||
.parent()
|
||||
.and_then(ast::MatchExpr::cast)
|
||||
.and_then(|match_expr| {
|
||||
let expr_opt = find_opt_node_in_file(&original_file, match_expr.expr());
|
||||
|
||||
expr_opt.and_then(|expr| {
|
||||
sema.type_of_expr(&expr)?
|
||||
.adjusted()
|
||||
.autoderef(sema.db)
|
||||
.find_map(|ty| match ty.as_adt() {
|
||||
Some(hir::Adt::Enum(e)) => Some(e),
|
||||
_ => None,
|
||||
}).and_then(|enum_| {
|
||||
Some(enum_.variants(sema.db))
|
||||
})
|
||||
})
|
||||
}).and_then(|variants| {
|
||||
Some(variants.iter().filter_map(|variant| {
|
||||
let variant_name = variant.name(sema.db).to_string();
|
||||
|
||||
let variant_already_present = match_arm_list.arms().any(|arm| {
|
||||
arm.pat().and_then(|pat| {
|
||||
let pat_already_present = pat.syntax().to_string().contains(&variant_name);
|
||||
pat_already_present.then(|| pat_already_present)
|
||||
}).is_some()
|
||||
});
|
||||
|
||||
(!variant_already_present).then_some(variant.clone())
|
||||
}).collect::<Vec<Variant>>())
|
||||
})
|
||||
});
|
||||
|
||||
if let Some(missing_variants_) = missing_variants_opt {
|
||||
missing_variants = missing_variants_;
|
||||
};
|
||||
|
||||
PatternRefutability::Refutable
|
||||
},
|
||||
ast::LetExpr(_) => PatternRefutability::Refutable,
|
||||
ast::ForExpr(_) => PatternRefutability::Irrefutable,
|
||||
_ => PatternRefutability::Irrefutable,
|
||||
|
@ -1162,6 +1210,7 @@ fn pattern_context_for(
|
|||
ref_token,
|
||||
record_pat: None,
|
||||
impl_: fetch_immediate_impl(sema, original_file, pat.syntax()),
|
||||
missing_variants,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue