@@ -105,7 +105,8 @@ pub(crate) fn extract_struct_from_enum_variant(
105105 . generic_param_list ( )
106106 . and_then ( |known_generics| extract_generic_params ( & known_generics, & field_list) ) ;
107107 let generics = generic_params. as_ref ( ) . map ( |generics| generics. clone_for_update ( ) ) ;
108- let def = create_struct_def ( variant_name. clone ( ) , & field_list, generics, & enum_ast) ;
108+ let def =
109+ create_struct_def ( variant_name. clone ( ) , & variant, & field_list, generics, & enum_ast) ;
109110
110111 let enum_ast = variant. parent_enum ( ) ;
111112 let indent = enum_ast. indent_level ( ) ;
@@ -228,6 +229,7 @@ fn tag_generics_in_variant(ty: &ast::Type, generics: &mut [(ast::GenericParam, b
228229
229230fn create_struct_def (
230231 name : ast:: Name ,
232+ variant : & ast:: Variant ,
231233 field_list : & Either < ast:: RecordFieldList , ast:: TupleFieldList > ,
232234 generics : Option < ast:: GenericParamList > ,
233235 enum_ : & ast:: Enum ,
@@ -272,6 +274,12 @@ fn create_struct_def(
272274
273275 let strukt = make:: struct_ ( enum_vis, name, generics, field_list) . clone_for_update ( ) ;
274276
277+ // take comments from variant
278+ ted:: insert_all (
279+ ted:: Position :: first_child_of ( strukt. syntax ( ) ) ,
280+ take_all_comments ( variant. syntax ( ) ) ,
281+ ) ;
282+
275283 // copy attributes from enum
276284 ted:: insert_all (
277285 ted:: Position :: first_child_of ( strukt. syntax ( ) ) ,
@@ -340,6 +348,31 @@ fn update_variant(variant: &ast::Variant, generics: Option<ast::GenericParamList
340348 Some ( ( ) )
341349}
342350
351+ // Note: this also detaches whitespace after comments,
352+ // since `SyntaxNode::splice_children` (and by extension `ted::insert_all_raw`)
353+ // detaches nodes. If we only took the comments, we'd leave behind the old whitespace.
354+ fn take_all_comments ( node : & SyntaxNode ) -> Vec < SyntaxElement > {
355+ let mut remove_next_ws = false ;
356+ node. children_with_tokens ( )
357+ . filter_map ( move |child| match child. kind ( ) {
358+ COMMENT => {
359+ remove_next_ws = true ;
360+ child. detach ( ) ;
361+ Some ( child)
362+ }
363+ WHITESPACE if remove_next_ws => {
364+ remove_next_ws = false ;
365+ child. detach ( ) ;
366+ Some ( make:: tokens:: single_newline ( ) . into ( ) )
367+ }
368+ _ => {
369+ remove_next_ws = false ;
370+ None
371+ }
372+ } )
373+ . collect ( )
374+ }
375+
343376fn apply_references (
344377 insert_use_cfg : InsertUseConfig ,
345378 segment : ast:: PathSegment ,
@@ -602,7 +635,7 @@ enum A { One(One) }"#,
602635 }
603636
604637 #[ test]
605- fn test_extract_struct_keep_comments_and_attrs_on_variant_struct ( ) {
638+ fn test_extract_struct_move_struct_variant_comments ( ) {
606639 check_assist (
607640 extract_struct_from_enum_variant,
608641 r#"
@@ -616,22 +649,22 @@ enum A {
616649 }
617650}"# ,
618651 r#"
652+ /* comment */
653+ // other
654+ /// comment
619655struct One{
620656 a: u32
621657}
622658
623659enum A {
624- /* comment */
625- // other
626- /// comment
627660 #[attr]
628661 One(One)
629662}"# ,
630663 ) ;
631664 }
632665
633666 #[ test]
634- fn test_extract_struct_keep_comments_and_attrs_on_variant_tuple ( ) {
667+ fn test_extract_struct_move_tuple_variant_comments ( ) {
635668 check_assist (
636669 extract_struct_from_enum_variant,
637670 r#"
@@ -643,12 +676,12 @@ enum A {
643676 $0One(u32, u32)
644677}"# ,
645678 r#"
679+ /* comment */
680+ // other
681+ /// comment
646682struct One(u32, u32);
647683
648684enum A {
649- /* comment */
650- // other
651- /// comment
652685 #[attr]
653686 One(One)
654687}"# ,
0 commit comments