Skip to content

Commit dc9842b

Browse files
committed
only check type namespace in extract_struct_from_enum_variant for collisions
1 parent 060c8b2 commit dc9842b

File tree

1 file changed

+53
-9
lines changed

1 file changed

+53
-9
lines changed

crates/assists/src/handlers/extract_struct_from_enum_variant.rs

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,27 @@ pub(crate) fn extract_struct_from_enum_variant(
3131
ctx: &AssistContext,
3232
) -> Option<()> {
3333
let variant = ctx.find_node_at_offset::<ast::Variant>()?;
34+
35+
fn is_applicable_variant(variant: &ast::Variant) -> bool {
36+
1 < match variant.kind() {
37+
ast::StructKind::Record(field_list) => field_list.fields().count(),
38+
ast::StructKind::Tuple(field_list) => field_list.fields().count(),
39+
ast::StructKind::Unit => 0,
40+
}
41+
}
42+
43+
if !is_applicable_variant(&variant) {
44+
return None;
45+
}
46+
3447
let field_list = match variant.kind() {
3548
ast::StructKind::Tuple(field_list) => field_list,
3649
_ => return None,
3750
};
3851

39-
// skip 1-tuple variants
40-
if field_list.fields().count() == 1 {
41-
return None;
42-
}
43-
4452
let variant_name = variant.name()?;
4553
let variant_hir = ctx.sema.to_def(&variant)?;
46-
if existing_struct_def(ctx.db(), &variant_name, &variant_hir) {
54+
if existing_definition(ctx.db(), &variant_name, &variant_hir) {
4755
return None;
4856
}
4957
let enum_ast = variant.parent_enum();
@@ -100,12 +108,21 @@ pub(crate) fn extract_struct_from_enum_variant(
100108
)
101109
}
102110

103-
fn existing_struct_def(db: &RootDatabase, variant_name: &ast::Name, variant: &EnumVariant) -> bool {
111+
fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &EnumVariant) -> bool {
104112
variant
105113
.parent_enum(db)
106114
.module(db)
107115
.scope(db, None)
108116
.into_iter()
117+
.filter(|(_, def)| match def {
118+
// only check type-namespace
119+
hir::ScopeDef::ModuleDef(def) => matches!(def,
120+
ModuleDef::Module(_) | ModuleDef::Adt(_) |
121+
ModuleDef::EnumVariant(_) | ModuleDef::Trait(_) |
122+
ModuleDef::TypeAlias(_) | ModuleDef::BuiltinType(_)
123+
),
124+
_ => false,
125+
})
109126
.any(|(name, _)| name == variant_name.as_name())
110127
}
111128

@@ -211,12 +228,39 @@ mod tests {
211228
use super::*;
212229

213230
#[test]
214-
fn test_extract_struct_several_fields() {
231+
fn test_extract_struct_several_fields_tuple() {
215232
check_assist(
216233
extract_struct_from_enum_variant,
217234
"enum A { <|>One(u32, u32) }",
218235
r#"struct One(pub u32, pub u32);
219236
237+
enum A { One(One) }"#,
238+
);
239+
}
240+
241+
#[test]
242+
fn test_extract_struct_several_fields_named() {
243+
check_assist(
244+
extract_struct_from_enum_variant,
245+
"enum A { <|>One { foo: u32, bar: u32 } }",
246+
r#"struct One {
247+
pub foo: u32,
248+
pub bar: u32
249+
}
250+
251+
enum A { One(One) }"#,
252+
);
253+
}
254+
255+
#[test]
256+
fn test_extract_enum_variant_name_value_namespace() {
257+
check_assist(
258+
extract_struct_from_enum_variant,
259+
r#"const One: () = ();
260+
enum A { <|>One(u32, u32) }"#,
261+
r#"const One: () = ();
262+
struct One(pub u32, pub u32);
263+
220264
enum A { One(One) }"#,
221265
);
222266
}
@@ -298,7 +342,7 @@ fn another_fn() {
298342
fn test_extract_enum_not_applicable_if_struct_exists() {
299343
check_not_applicable(
300344
r#"struct One;
301-
enum A { <|>One(u8) }"#,
345+
enum A { <|>One(u8, u32) }"#,
302346
);
303347
}
304348

0 commit comments

Comments
 (0)