@@ -46,19 +46,24 @@ pub(crate) fn fill_match_arms(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist
46
46
} ;
47
47
48
48
let expr = match_expr. expr ( ) ?;
49
- let enum_def = {
49
+ let ( enum_def, module ) = {
50
50
let analyzer = ctx. source_analyzer ( expr. syntax ( ) , None ) ;
51
- resolve_enum_def ( ctx. db , & analyzer, & expr) ?
51
+ ( resolve_enum_def ( ctx. db , & analyzer, & expr) ?, analyzer . module ( ) ? )
52
52
} ;
53
- let variant_list = enum_def. variant_list ( ) ?;
53
+ let variants = enum_def. variants ( ctx. db ) ;
54
+ if variants. is_empty ( ) {
55
+ return None ;
56
+ }
57
+
58
+ let db = ctx. db ;
54
59
55
60
ctx. add_assist ( AssistId ( "fill_match_arms" ) , "fill match arms" , |edit| {
56
61
let indent_level = IndentLevel :: from_node ( match_arm_list. syntax ( ) ) ;
57
62
58
63
let new_arm_list = {
59
- let variants = variant_list. variants ( ) ;
60
64
let arms = variants
61
- . filter_map ( build_pat)
65
+ . into_iter ( )
66
+ . filter_map ( |variant| build_pat ( db, module, variant) )
62
67
. map ( |pat| make:: match_arm ( iter:: once ( pat) , make:: expr_unit ( ) ) ) ;
63
68
indent_level. increase_indent ( make:: match_arm_list ( arms) )
64
69
} ;
@@ -80,23 +85,25 @@ fn resolve_enum_def(
80
85
db : & impl HirDatabase ,
81
86
analyzer : & hir:: SourceAnalyzer ,
82
87
expr : & ast:: Expr ,
83
- ) -> Option < ast :: EnumDef > {
88
+ ) -> Option < hir :: Enum > {
84
89
let expr_ty = analyzer. type_of ( db, & expr) ?;
85
90
86
- let res = expr_ty. autoderef ( db) . find_map ( |ty| match ty. as_adt ( ) {
87
- Some ( Adt :: Enum ( e) ) => Some ( e. source ( db ) . value ) ,
91
+ let result = expr_ty. autoderef ( db) . find_map ( |ty| match ty. as_adt ( ) {
92
+ Some ( Adt :: Enum ( e) ) => Some ( e) ,
88
93
_ => None ,
89
94
} ) ;
90
- res
95
+ result
91
96
}
92
97
93
- fn build_pat ( var : ast:: EnumVariant ) -> Option < ast:: Pat > {
94
- let path = make:: path_qualified (
95
- make:: path_from_name_ref ( make:: name_ref ( & var. parent_enum ( ) . name ( ) ?. syntax ( ) . to_string ( ) ) ) ,
96
- make:: name_ref ( & var. name ( ) ?. syntax ( ) . to_string ( ) ) ,
97
- ) ;
98
+ fn build_pat (
99
+ db : & impl HirDatabase ,
100
+ module : hir:: Module ,
101
+ var : hir:: EnumVariant ,
102
+ ) -> Option < ast:: Pat > {
103
+ let path = crate :: ast_transform:: path_to_ast ( module. find_use_path ( db, var. into ( ) ) ?) ;
98
104
99
- let pat: ast:: Pat = match var. kind ( ) {
105
+ // FIXME: use HIR for this; it doesn't currently expose struct vs. tuple vs. unit variants though
106
+ let pat: ast:: Pat = match var. source ( db) . value . kind ( ) {
100
107
ast:: StructKind :: Tuple ( field_list) => {
101
108
let pats =
102
109
iter:: repeat ( make:: placeholder_pat ( ) . into ( ) ) . take ( field_list. fields ( ) . count ( ) ) ;
@@ -106,7 +113,7 @@ fn build_pat(var: ast::EnumVariant) -> Option<ast::Pat> {
106
113
let pats = field_list. fields ( ) . map ( |f| make:: bind_pat ( f. name ( ) . unwrap ( ) ) . into ( ) ) ;
107
114
make:: record_pat ( path, pats) . into ( )
108
115
}
109
- ast:: StructKind :: Unit => make:: path_pat ( path) . into ( ) ,
116
+ ast:: StructKind :: Unit => make:: path_pat ( path) ,
110
117
} ;
111
118
112
119
Some ( pat)
@@ -252,4 +259,32 @@ mod tests {
252
259
"# ,
253
260
) ;
254
261
}
262
+
263
+ #[ test]
264
+ fn fill_match_arms_qualifies_path ( ) {
265
+ check_assist (
266
+ fill_match_arms,
267
+ r#"
268
+ mod foo { pub enum E { X, Y } }
269
+ use foo::E::X;
270
+
271
+ fn main() {
272
+ match X {
273
+ <|>
274
+ }
275
+ }
276
+ "# ,
277
+ r#"
278
+ mod foo { pub enum E { X, Y } }
279
+ use foo::E::X;
280
+
281
+ fn main() {
282
+ match <|>X {
283
+ X => (),
284
+ foo::E::Y => (),
285
+ }
286
+ }
287
+ "# ,
288
+ ) ;
289
+ }
255
290
}
0 commit comments