@@ -6,6 +6,7 @@ use ide_db::{
6
6
defs:: Definition ,
7
7
helpers:: mod_path_to_ast,
8
8
imports:: insert_use:: { insert_use, ImportScope , InsertUseConfig } ,
9
+ path_transform:: PathTransform ,
9
10
search:: FileReference ,
10
11
FxHashSet , RootDatabase ,
11
12
} ;
@@ -105,6 +106,16 @@ pub(crate) fn extract_struct_from_enum_variant(
105
106
. generic_param_list ( )
106
107
. and_then ( |known_generics| extract_generic_params ( & known_generics, & field_list) ) ;
107
108
let generics = generic_params. as_ref ( ) . map ( |generics| generics. clone_for_update ( ) ) ;
109
+
110
+ // resolve GenericArg in field_list to actual type
111
+ let field_list = field_list. clone_for_update ( ) ;
112
+ if let Some ( ( target_scope, source_scope) ) =
113
+ ctx. sema . scope ( enum_ast. syntax ( ) ) . zip ( ctx. sema . scope ( field_list. syntax ( ) ) )
114
+ {
115
+ PathTransform :: generic_transformation ( & target_scope, & source_scope)
116
+ . apply ( field_list. syntax ( ) ) ;
117
+ }
118
+
108
119
let def =
109
120
create_struct_def ( variant_name. clone ( ) , & variant, & field_list, generics, & enum_ast) ;
110
121
@@ -244,8 +255,6 @@ fn create_struct_def(
244
255
// for fields without any existing visibility, use visibility of enum
245
256
let field_list: ast:: FieldList = match field_list {
246
257
Either :: Left ( field_list) => {
247
- let field_list = field_list. clone_for_update ( ) ;
248
-
249
258
if let Some ( vis) = & enum_vis {
250
259
field_list
251
260
. fields ( )
@@ -254,11 +263,9 @@ fn create_struct_def(
254
263
. for_each ( |it| insert_vis ( it. syntax ( ) , vis. syntax ( ) ) ) ;
255
264
}
256
265
257
- field_list. into ( )
266
+ field_list. clone ( ) . into ( )
258
267
}
259
268
Either :: Right ( field_list) => {
260
- let field_list = field_list. clone_for_update ( ) ;
261
-
262
269
if let Some ( vis) = & enum_vis {
263
270
field_list
264
271
. fields ( )
@@ -267,7 +274,7 @@ fn create_struct_def(
267
274
. for_each ( |it| insert_vis ( it. syntax ( ) , vis. syntax ( ) ) ) ;
268
275
}
269
276
270
- field_list. into ( )
277
+ field_list. clone ( ) . into ( )
271
278
}
272
279
} ;
273
280
field_list. reindent_to ( IndentLevel :: single ( ) ) ;
@@ -425,6 +432,59 @@ mod tests {
425
432
426
433
use super :: * ;
427
434
435
+ #[ test]
436
+ fn issue_16197 ( ) {
437
+ check_assist (
438
+ extract_struct_from_enum_variant,
439
+ r#"
440
+ enum Foo {
441
+ Bar $0{ node: Box<Self> },
442
+ Nil,
443
+ }
444
+ "# ,
445
+ r#"
446
+ struct Bar{ node: Box<Foo> }
447
+
448
+ enum Foo {
449
+ Bar(Bar),
450
+ Nil,
451
+ }
452
+ "# ,
453
+ ) ;
454
+ check_assist (
455
+ extract_struct_from_enum_variant,
456
+ r#"
457
+ enum Foo {
458
+ Bar $0{ node: Box<Self>, a: Arc<Box<Self>> },
459
+ Nil,
460
+ }
461
+ "# ,
462
+ r#"
463
+ struct Bar{ node: Box<Foo>, a: Arc<Box<Foo>> }
464
+
465
+ enum Foo {
466
+ Bar(Bar),
467
+ Nil,
468
+ }
469
+ "# ,
470
+ ) ;
471
+ check_assist (
472
+ extract_struct_from_enum_variant,
473
+ r#"
474
+ enum Foo {
475
+ Nil(Box$0<Self>, Arc<Box<Self>>),
476
+ }
477
+ "# ,
478
+ r#"
479
+ struct Nil(Box<Foo>, Arc<Box<Foo>>);
480
+
481
+ enum Foo {
482
+ Nil(Nil),
483
+ }
484
+ "# ,
485
+ ) ;
486
+ }
487
+
428
488
#[ test]
429
489
fn test_extract_struct_several_fields_tuple ( ) {
430
490
check_assist (
0 commit comments