@@ -46,19 +46,24 @@ pub(crate) fn fill_match_arms(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist
4646 } ;
4747
4848 let expr = match_expr. expr ( ) ?;
49- let enum_def = {
49+ let ( enum_def, module ) = {
5050 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 ( ) ? )
5252 } ;
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 ;
5459
5560 ctx. add_assist ( AssistId ( "fill_match_arms" ) , "fill match arms" , |edit| {
5661 let indent_level = IndentLevel :: from_node ( match_arm_list. syntax ( ) ) ;
5762
5863 let new_arm_list = {
59- let variants = variant_list. variants ( ) ;
6064 let arms = variants
61- . filter_map ( build_pat)
65+ . into_iter ( )
66+ . filter_map ( |variant| build_pat ( db, module, variant) )
6267 . map ( |pat| make:: match_arm ( iter:: once ( pat) , make:: expr_unit ( ) ) ) ;
6368 indent_level. increase_indent ( make:: match_arm_list ( arms) )
6469 } ;
@@ -80,23 +85,25 @@ fn resolve_enum_def(
8085 db : & impl HirDatabase ,
8186 analyzer : & hir:: SourceAnalyzer ,
8287 expr : & ast:: Expr ,
83- ) -> Option < ast :: EnumDef > {
88+ ) -> Option < hir :: Enum > {
8489 let expr_ty = analyzer. type_of ( db, & expr) ?;
8590
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) ,
8893 _ => None ,
8994 } ) ;
90- res
95+ result
9196}
9297
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 ( ) ) ?) ;
98104
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 ( ) {
100107 ast:: StructKind :: Tuple ( field_list) => {
101108 let pats =
102109 iter:: repeat ( make:: placeholder_pat ( ) . into ( ) ) . take ( field_list. fields ( ) . count ( ) ) ;
@@ -106,7 +113,7 @@ fn build_pat(var: ast::EnumVariant) -> Option<ast::Pat> {
106113 let pats = field_list. fields ( ) . map ( |f| make:: bind_pat ( f. name ( ) . unwrap ( ) ) . into ( ) ) ;
107114 make:: record_pat ( path, pats) . into ( )
108115 }
109- ast:: StructKind :: Unit => make:: path_pat ( path) . into ( ) ,
116+ ast:: StructKind :: Unit => make:: path_pat ( path) ,
110117 } ;
111118
112119 Some ( pat)
@@ -252,4 +259,32 @@ mod tests {
252259 "# ,
253260 ) ;
254261 }
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+ }
255290}
0 commit comments