mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-17 15:55:23 +00:00
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 <ironyman@users.noreply.github.com> Co-authored-by: Changyu Li <changyl@microsoft.com>
This commit is contained in:
commit
0129790a8f
1 changed files with 57 additions and 2 deletions
|
@ -1,4 +1,5 @@
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
use hir::{
|
use hir::{
|
||||||
AdtDef, FieldSource, HasSource,
|
AdtDef, FieldSource, HasSource,
|
||||||
|
@ -8,14 +9,42 @@ use ra_syntax::ast::{self, AstNode};
|
||||||
|
|
||||||
use crate::{AssistCtx, Assist, AssistId};
|
use crate::{AssistCtx, Assist, AssistId};
|
||||||
|
|
||||||
|
fn is_trivial_arm(arm: &ast::MatchArm) -> bool {
|
||||||
|
fn single_pattern(arm: &ast::MatchArm) -> Option<ast::PatKind> {
|
||||||
|
let (pat,) = arm.pats().collect_tuple()?;
|
||||||
|
Some(pat.kind())
|
||||||
|
}
|
||||||
|
match single_pattern(arm) {
|
||||||
|
Some(ast::PatKind::PlaceholderPat(..)) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn fill_match_arms(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
|
pub(crate) fn fill_match_arms(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
|
||||||
let match_expr = ctx.node_at_offset::<ast::MatchExpr>()?;
|
let match_expr = ctx.node_at_offset::<ast::MatchExpr>()?;
|
||||||
|
|
||||||
// We already have some match arms, so we don't provide any assists.
|
// We already have some match arms, so we don't provide any assists.
|
||||||
|
// Unless if there is only one trivial match arm possibly created
|
||||||
|
// by match postfix complete. Trivial match arm is the catch all arm.
|
||||||
match match_expr.match_arm_list() {
|
match match_expr.match_arm_list() {
|
||||||
Some(arm_list) if arm_list.arms().count() > 0 => {
|
Some(arm_list) => {
|
||||||
|
let mut arm_iter = arm_list.arms();
|
||||||
|
let first = arm_iter.next();
|
||||||
|
|
||||||
|
match first {
|
||||||
|
// If there arm list is empty or there is only one trivial arm, then proceed.
|
||||||
|
Some(arm) if is_trivial_arm(arm) => {
|
||||||
|
if arm_iter.next() != None {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,4 +257,30 @@ mod tests {
|
||||||
"match E::X {}",
|
"match E::X {}",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fill_match_arms_trivial_arm() {
|
||||||
|
check_assist(
|
||||||
|
fill_match_arms,
|
||||||
|
r#"
|
||||||
|
enum E { X, Y }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
match E::X {
|
||||||
|
<|>_ => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
r#"
|
||||||
|
enum E { X, Y }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
match <|>E::X {
|
||||||
|
E::X => (),
|
||||||
|
E::Y => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue