Skip to content

Commit b422cef

Browse files
bors[bot]matklad
andauthored
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>
2 parents 5d080dd + d8881d9 commit b422cef

File tree

3 files changed

+69
-11
lines changed

3 files changed

+69
-11
lines changed

crates/ra_assists/src/handlers/fill_match_arms.rs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ use hir::{Adt, HasSource, ModuleDef, Semantics};
44
use itertools::Itertools;
55
use ra_ide_db::RootDatabase;
66
use ra_syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat};
7+
use test_utils::tested_by;
78

8-
use crate::{AssistContext, AssistId, Assists};
9+
use crate::{utils::FamousDefs, AssistContext, AssistId, Assists};
910

1011
// Assist: fill_match_arms
1112
//
@@ -49,12 +50,18 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<
4950
let missing_arms: Vec<MatchArm> = if let Some(enum_def) = resolve_enum_def(&ctx.sema, &expr) {
5051
let variants = enum_def.variants(ctx.db);
5152

52-
variants
53+
let mut variants = variants
5354
.into_iter()
5455
.filter_map(|variant| build_pat(ctx.db, module, variant))
5556
.filter(|variant_pat| is_variant_missing(&mut arms, variant_pat))
5657
.map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block()))
57-
.collect()
58+
.collect::<Vec<_>>();
59+
if Some(enum_def) == FamousDefs(&ctx.sema, module.krate()).core_option_Option() {
60+
// Match `Some` variant first.
61+
tested_by!(option_order);
62+
variants.reverse()
63+
}
64+
variants
5865
} else if let Some(enum_defs) = resolve_tuple_of_enum_def(&ctx.sema, &expr) {
5966
// Partial fill not currently supported for tuple of enums.
6067
if !arms.is_empty() {
@@ -167,9 +174,13 @@ fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> O
167174

168175
#[cfg(test)]
169176
mod tests {
170-
use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
177+
use crate::{
178+
tests::{check_assist, check_assist_not_applicable, check_assist_target},
179+
utils::FamousDefs,
180+
};
171181

172182
use super::fill_match_arms;
183+
use test_utils::covers;
173184

174185
#[test]
175186
fn all_match_arms_provided() {
@@ -736,4 +747,29 @@ mod tests {
736747
"#,
737748
);
738749
}
750+
751+
#[test]
752+
fn option_order() {
753+
covers!(option_order);
754+
let before = r#"
755+
fn foo(opt: Option<i32>) {
756+
match opt<|> {
757+
}
758+
}"#;
759+
let before =
760+
&format!("//- main.rs crate:main deps:core\n{}{}", before, FamousDefs::FIXTURE);
761+
762+
check_assist(
763+
fill_match_arms,
764+
before,
765+
r#"
766+
fn foo(opt: Option<i32>) {
767+
match <|>opt {
768+
Some(_) => {}
769+
None => {}
770+
}
771+
}
772+
"#,
773+
);
774+
}
739775
}

crates/ra_assists/src/marks.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! See test_utils/src/marks.rs
22
33
test_utils::marks![
4+
option_order
45
introduce_var_in_comment_is_not_applicable
56
test_introduce_var_expr_stmt
67
test_introduce_var_last_expr

crates/ra_assists/src/utils.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ pub(crate) mod insert_use;
33

44
use std::{iter, ops};
55

6-
use hir::{Adt, Crate, Semantics, Trait, Type};
6+
use hir::{Adt, Crate, Enum, ScopeDef, Semantics, Trait, Type};
77
use ra_ide_db::RootDatabase;
88
use ra_syntax::{
99
ast::{self, make, NameOwner},
@@ -200,13 +200,19 @@ impl FamousDefs<'_, '_> {
200200
#[cfg(test)]
201201
pub(crate) const FIXTURE: &'static str = r#"
202202
//- /libcore.rs crate:core
203-
pub mod convert{
203+
pub mod convert {
204204
pub trait From<T> {
205205
fn from(T) -> Self;
206206
}
207207
}
208208
209-
pub mod prelude { pub use crate::convert::From }
209+
pub mod option {
210+
pub enum Option<T> { None, Some(T)}
211+
}
212+
213+
pub mod prelude {
214+
pub use crate::{convert::From, option::Option::{self, *}};
215+
}
210216
#[prelude_import]
211217
pub use prelude::*;
212218
"#;
@@ -215,7 +221,25 @@ pub use prelude::*;
215221
self.find_trait("core:convert:From")
216222
}
217223

224+
pub(crate) fn core_option_Option(&self) -> Option<Enum> {
225+
self.find_enum("core:option:Option")
226+
}
227+
218228
fn find_trait(&self, path: &str) -> Option<Trait> {
229+
match self.find_def(path)? {
230+
hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it),
231+
_ => None,
232+
}
233+
}
234+
235+
fn find_enum(&self, path: &str) -> Option<Enum> {
236+
match self.find_def(path)? {
237+
hir::ScopeDef::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Enum(it))) => Some(it),
238+
_ => None,
239+
}
240+
}
241+
242+
fn find_def(&self, path: &str) -> Option<ScopeDef> {
219243
let db = self.0.db;
220244
let mut path = path.split(':');
221245
let trait_ = path.next_back()?;
@@ -240,9 +264,6 @@ pub use prelude::*;
240264
}
241265
let def =
242266
module.scope(db, None).into_iter().find(|(name, _def)| &name.to_string() == trait_)?.1;
243-
match def {
244-
hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it),
245-
_ => None,
246-
}
267+
Some(def)
247268
}
248269
}

0 commit comments

Comments
 (0)