Merge #4529
4529: Fix Some|None order in fill_match_arms r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
b422cef7dc
@ -4,8 +4,9 @@
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use ra_ide_db::RootDatabase;
|
use ra_ide_db::RootDatabase;
|
||||||
use ra_syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat};
|
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
|
// 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 missing_arms: Vec<MatchArm> = if let Some(enum_def) = resolve_enum_def(&ctx.sema, &expr) {
|
||||||
let variants = enum_def.variants(ctx.db);
|
let variants = enum_def.variants(ctx.db);
|
||||||
|
|
||||||
variants
|
let mut variants = variants
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|variant| build_pat(ctx.db, module, variant))
|
.filter_map(|variant| build_pat(ctx.db, module, variant))
|
||||||
.filter(|variant_pat| is_variant_missing(&mut arms, variant_pat))
|
.filter(|variant_pat| is_variant_missing(&mut arms, variant_pat))
|
||||||
.map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block()))
|
.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) {
|
} else if let Some(enum_defs) = resolve_tuple_of_enum_def(&ctx.sema, &expr) {
|
||||||
// Partial fill not currently supported for tuple of enums.
|
// Partial fill not currently supported for tuple of enums.
|
||||||
if !arms.is_empty() {
|
if !arms.is_empty() {
|
||||||
@ -167,9 +174,13 @@ fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> O
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
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 super::fill_match_arms;
|
||||||
|
use test_utils::covers;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn all_match_arms_provided() {
|
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
|
//! See test_utils/src/marks.rs
|
||||||
|
|
||||||
test_utils::marks![
|
test_utils::marks![
|
||||||
|
option_order
|
||||||
introduce_var_in_comment_is_not_applicable
|
introduce_var_in_comment_is_not_applicable
|
||||||
test_introduce_var_expr_stmt
|
test_introduce_var_expr_stmt
|
||||||
test_introduce_var_last_expr
|
test_introduce_var_last_expr
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
use std::{iter, ops};
|
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_ide_db::RootDatabase;
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{self, make, NameOwner},
|
ast::{self, make, NameOwner},
|
||||||
@ -206,7 +206,13 @@ pub trait From<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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]
|
#[prelude_import]
|
||||||
pub use prelude::*;
|
pub use prelude::*;
|
||||||
"#;
|
"#;
|
||||||
@ -215,7 +221,25 @@ pub(crate) fn core_convert_From(&self) -> Option<Trait> {
|
|||||||
self.find_trait("core:convert:From")
|
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> {
|
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 db = self.0.db;
|
||||||
let mut path = path.split(':');
|
let mut path = path.split(':');
|
||||||
let trait_ = path.next_back()?;
|
let trait_ = path.next_back()?;
|
||||||
@ -240,9 +264,6 @@ fn find_trait(&self, path: &str) -> Option<Trait> {
|
|||||||
}
|
}
|
||||||
let def =
|
let def =
|
||||||
module.scope(db, None).into_iter().find(|(name, _def)| &name.to_string() == trait_)?.1;
|
module.scope(db, None).into_iter().find(|(name, _def)| &name.to_string() == trait_)?.1;
|
||||||
match def {
|
Some(def)
|
||||||
hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user