Fix Some|None order in fill_match_arms
This commit is contained in:
parent
c0bcaea466
commit
d8881d98d3
@ -4,8 +4,9 @@
|
||||
use itertools::Itertools;
|
||||
use ra_ide_db::RootDatabase;
|
||||
use ra_syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat};
|
||||
use test_utils::tested_by;
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists};
|
||||
use crate::{utils::FamousDefs, AssistContext, AssistId, Assists};
|
||||
|
||||
// Assist: fill_match_arms
|
||||
//
|
||||
@ -49,12 +50,18 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<
|
||||
let missing_arms: Vec<MatchArm> = if let Some(enum_def) = resolve_enum_def(&ctx.sema, &expr) {
|
||||
let variants = enum_def.variants(ctx.db);
|
||||
|
||||
variants
|
||||
let mut variants = variants
|
||||
.into_iter()
|
||||
.filter_map(|variant| build_pat(ctx.db, module, variant))
|
||||
.filter(|variant_pat| is_variant_missing(&mut arms, variant_pat))
|
||||
.map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block()))
|
||||
.collect()
|
||||
.collect::<Vec<_>>();
|
||||
if Some(enum_def) == FamousDefs(&ctx.sema, module.krate()).core_option_Option() {
|
||||
// Match `Some` variant first.
|
||||
tested_by!(option_order);
|
||||
variants.reverse()
|
||||
}
|
||||
variants
|
||||
} else if let Some(enum_defs) = resolve_tuple_of_enum_def(&ctx.sema, &expr) {
|
||||
// Partial fill not currently supported for tuple of enums.
|
||||
if !arms.is_empty() {
|
||||
@ -167,9 +174,13 @@ fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> O
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
|
||||
use crate::{
|
||||
tests::{check_assist, check_assist_not_applicable, check_assist_target},
|
||||
utils::FamousDefs,
|
||||
};
|
||||
|
||||
use super::fill_match_arms;
|
||||
use test_utils::covers;
|
||||
|
||||
#[test]
|
||||
fn all_match_arms_provided() {
|
||||
@ -736,4 +747,29 @@ fn foo(a: A) {
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn option_order() {
|
||||
covers!(option_order);
|
||||
let before = r#"
|
||||
fn foo(opt: Option<i32>) {
|
||||
match opt<|> {
|
||||
}
|
||||
}"#;
|
||||
let before =
|
||||
&format!("//- main.rs crate:main deps:core\n{}{}", before, FamousDefs::FIXTURE);
|
||||
|
||||
check_assist(
|
||||
fill_match_arms,
|
||||
before,
|
||||
r#"
|
||||
fn foo(opt: Option<i32>) {
|
||||
match <|>opt {
|
||||
Some(_) => {}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
//! See test_utils/src/marks.rs
|
||||
|
||||
test_utils::marks![
|
||||
option_order
|
||||
introduce_var_in_comment_is_not_applicable
|
||||
test_introduce_var_expr_stmt
|
||||
test_introduce_var_last_expr
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
use std::{iter, ops};
|
||||
|
||||
use hir::{Adt, Crate, Semantics, Trait, Type};
|
||||
use hir::{Adt, Crate, Enum, ScopeDef, Semantics, Trait, Type};
|
||||
use ra_ide_db::RootDatabase;
|
||||
use ra_syntax::{
|
||||
ast::{self, make, NameOwner},
|
||||
@ -200,13 +200,19 @@ impl FamousDefs<'_, '_> {
|
||||
#[cfg(test)]
|
||||
pub(crate) const FIXTURE: &'static str = r#"
|
||||
//- /libcore.rs crate:core
|
||||
pub mod convert{
|
||||
pub mod convert {
|
||||
pub trait From<T> {
|
||||
fn from(T) -> Self;
|
||||
}
|
||||
}
|
||||
|
||||
pub mod prelude { pub use crate::convert::From }
|
||||
pub mod option {
|
||||
pub enum Option<T> { None, Some(T)}
|
||||
}
|
||||
|
||||
pub mod prelude {
|
||||
pub use crate::{convert::From, option::Option::{self, *}};
|
||||
}
|
||||
#[prelude_import]
|
||||
pub use prelude::*;
|
||||
"#;
|
||||
@ -215,7 +221,25 @@ pub(crate) fn core_convert_From(&self) -> Option<Trait> {
|
||||
self.find_trait("core:convert:From")
|
||||
}
|
||||
|
||||
pub(crate) fn core_option_Option(&self) -> Option<Enum> {
|
||||
self.find_enum("core:option:Option")
|
||||
}
|
||||
|
||||
fn find_trait(&self, path: &str) -> Option<Trait> {
|
||||
match self.find_def(path)? {
|
||||
hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn find_enum(&self, path: &str) -> Option<Enum> {
|
||||
match self.find_def(path)? {
|
||||
hir::ScopeDef::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Enum(it))) => Some(it),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn find_def(&self, path: &str) -> Option<ScopeDef> {
|
||||
let db = self.0.db;
|
||||
let mut path = path.split(':');
|
||||
let trait_ = path.next_back()?;
|
||||
@ -240,9 +264,6 @@ fn find_trait(&self, path: &str) -> Option<Trait> {
|
||||
}
|
||||
let def =
|
||||
module.scope(db, None).into_iter().find(|(name, _def)| &name.to_string() == trait_)?.1;
|
||||
match def {
|
||||
hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it),
|
||||
_ => None,
|
||||
}
|
||||
Some(def)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user