@@ -160,7 +160,7 @@ impl UseSegment {
160160 }
161161}
162162
163- pub ( crate ) fn merge_use_trees ( use_trees : Vec < UseTree > ) -> Vec < UseTree > {
163+ pub ( crate ) fn merge_use_trees ( use_trees : Vec < UseTree > , merge_by : SharedPrefix ) -> Vec < UseTree > {
164164 let mut result = Vec :: with_capacity ( use_trees. len ( ) ) ;
165165 for use_tree in use_trees {
166166 if use_tree. has_comment ( ) || use_tree. attrs . is_some ( ) {
@@ -169,8 +169,11 @@ pub(crate) fn merge_use_trees(use_trees: Vec<UseTree>) -> Vec<UseTree> {
169169 }
170170
171171 for flattened in use_tree. flatten ( ) {
172- if let Some ( tree) = result. iter_mut ( ) . find ( |tree| tree. share_prefix ( & flattened) ) {
173- tree. merge ( & flattened) ;
172+ if let Some ( tree) = result
173+ . iter_mut ( )
174+ . find ( |tree| tree. share_prefix ( & flattened, merge_by) )
175+ {
176+ tree. merge ( & flattened, merge_by) ;
174177 } else {
175178 result. push ( flattened) ;
176179 }
@@ -179,48 +182,6 @@ pub(crate) fn merge_use_trees(use_trees: Vec<UseTree>) -> Vec<UseTree> {
179182 result
180183}
181184
182- /// Split apart nested imports in use trees.
183- pub ( crate ) fn unnest_use_trees ( mut use_trees : Vec < UseTree > ) -> Vec < UseTree > {
184- let mut result = Vec :: with_capacity ( use_trees. len ( ) ) ;
185- while let Some ( mut use_tree) = use_trees. pop ( ) {
186- if !use_tree. has_comment ( ) && use_tree. attrs . is_none ( ) {
187- if let Some ( ( UseSegment :: List ( list) , ref prefix) ) = use_tree. path . split_last_mut ( ) {
188- let span = use_tree. span ;
189- let visibility = & use_tree. visibility ;
190- list. retain ( |nested_use_tree| {
191- if matches ! (
192- nested_use_tree. path[ ..] ,
193- [ UseSegment :: Ident ( ..) ] | [ UseSegment :: Slf ( ..) ] | [ UseSegment :: Glob ]
194- ) {
195- return true ;
196- }
197- if nested_use_tree. has_comment ( ) {
198- return true ;
199- }
200- // nested item detected; flatten once, but process it again
201- // in case it has more nesting
202- use_trees. push ( UseTree {
203- path : prefix
204- . iter ( )
205- . cloned ( )
206- . chain ( nested_use_tree. path . iter ( ) . cloned ( ) )
207- . collect ( ) ,
208- span,
209- list_item : None ,
210- visibility : visibility. clone ( ) ,
211- attrs : None ,
212- } ) ;
213- // remove this item
214- false
215- } ) ;
216- use_tree = use_tree. normalize ( ) ;
217- }
218- }
219- result. push ( use_tree) ;
220- }
221- result
222- }
223-
224185impl fmt:: Debug for UseTree {
225186 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
226187 fmt:: Display :: fmt ( self , f)
@@ -568,15 +529,20 @@ impl UseTree {
568529 }
569530 }
570531
571- fn share_prefix ( & self , other : & UseTree ) -> bool {
532+ fn share_prefix ( & self , other : & UseTree , shared_prefix : SharedPrefix ) -> bool {
572533 if self . path . is_empty ( )
573534 || other. path . is_empty ( )
574535 || self . attrs . is_some ( )
575536 || !self . same_visibility ( other)
576537 {
577538 false
578539 } else {
579- self . path [ 0 ] == other. path [ 0 ]
540+ match shared_prefix {
541+ SharedPrefix :: Crate => self . path [ 0 ] == other. path [ 0 ] ,
542+ SharedPrefix :: Module => {
543+ self . path [ ..self . path . len ( ) - 1 ] == other. path [ ..other. path . len ( ) - 1 ]
544+ }
545+ }
580546 }
581547 }
582548
@@ -610,7 +576,7 @@ impl UseTree {
610576 }
611577 }
612578
613- fn merge ( & mut self , other : & UseTree ) {
579+ fn merge ( & mut self , other : & UseTree , merge_by : SharedPrefix ) {
614580 let mut prefix = 0 ;
615581 for ( a, b) in self . path . iter ( ) . zip ( other. path . iter ( ) ) {
616582 if * a == * b {
@@ -619,20 +585,30 @@ impl UseTree {
619585 break ;
620586 }
621587 }
622- if let Some ( new_path) = merge_rest ( & self . path , & other. path , prefix) {
588+ if let Some ( new_path) = merge_rest ( & self . path , & other. path , prefix, merge_by ) {
623589 self . path = new_path;
624590 self . span = self . span . to ( other. span ) ;
625591 }
626592 }
627593}
628594
629- fn merge_rest ( a : & [ UseSegment ] , b : & [ UseSegment ] , mut len : usize ) -> Option < Vec < UseSegment > > {
595+ fn merge_rest (
596+ a : & [ UseSegment ] ,
597+ b : & [ UseSegment ] ,
598+ mut len : usize ,
599+ merge_by : SharedPrefix ,
600+ ) -> Option < Vec < UseSegment > > {
630601 if a. len ( ) == len && b. len ( ) == len {
631602 return None ;
632603 }
633604 if a. len ( ) != len && b. len ( ) != len {
634- if let UseSegment :: List ( mut list) = a[ len] . clone ( ) {
635- merge_use_trees_inner ( & mut list, UseTree :: from_path ( b[ len..] . to_vec ( ) , DUMMY_SP ) ) ;
605+ if let UseSegment :: List ( ref list) = a[ len] {
606+ let mut list = list. clone ( ) ;
607+ merge_use_trees_inner (
608+ & mut list,
609+ UseTree :: from_path ( b[ len..] . to_vec ( ) , DUMMY_SP ) ,
610+ merge_by,
611+ ) ;
636612 let mut new_path = b[ ..len] . to_vec ( ) ;
637613 new_path. push ( UseSegment :: List ( list) ) ;
638614 return Some ( new_path) ;
@@ -659,17 +635,19 @@ fn merge_rest(a: &[UseSegment], b: &[UseSegment], mut len: usize) -> Option<Vec<
659635 Some ( new_path)
660636}
661637
662- fn merge_use_trees_inner ( trees : & mut Vec < UseTree > , use_tree : UseTree ) {
663- let similar_trees = trees. iter_mut ( ) . filter ( |tree| tree. share_prefix ( & use_tree) ) ;
664- if use_tree. path . len ( ) == 1 {
638+ fn merge_use_trees_inner ( trees : & mut Vec < UseTree > , use_tree : UseTree , merge_by : SharedPrefix ) {
639+ let similar_trees = trees
640+ . iter_mut ( )
641+ . filter ( |tree| tree. share_prefix ( & use_tree, merge_by) ) ;
642+ if use_tree. path . len ( ) == 1 && merge_by == SharedPrefix :: Crate {
665643 if let Some ( tree) = similar_trees. min_by_key ( |tree| tree. path . len ( ) ) {
666644 if tree. path . len ( ) == 1 {
667645 return ;
668646 }
669647 }
670648 } else if let Some ( tree) = similar_trees. max_by_key ( |tree| tree. path . len ( ) ) {
671649 if tree. path . len ( ) > 1 {
672- tree. merge ( & use_tree) ;
650+ tree. merge ( & use_tree, merge_by ) ;
673651 return ;
674652 }
675653 }
@@ -872,6 +850,12 @@ impl Rewrite for UseTree {
872850 }
873851}
874852
853+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
854+ pub ( crate ) enum SharedPrefix {
855+ Crate ,
856+ Module ,
857+ }
858+
875859#[ cfg( test) ]
876860mod test {
877861 use super :: * ;
@@ -1018,44 +1002,72 @@ mod test {
10181002 }
10191003 }
10201004
1021- #[ test]
1022- fn test_use_tree_merge ( ) {
1023- macro_rules! test_merge {
1024- ( [ $( $input: expr) ,* $( , ) * ] , [ $( $output: expr) ,* $( , ) * ] ) => {
1025- assert_eq!(
1026- merge_use_trees( parse_use_trees!( $( $input, ) * ) ) ,
1027- parse_use_trees!( $( $output, ) * ) ,
1028- ) ;
1029- }
1005+ macro_rules! test_merge {
1006+ ( $by: ident, [ $( $input: expr) ,* $( , ) * ] , [ $( $output: expr) ,* $( , ) * ] ) => {
1007+ assert_eq!(
1008+ merge_use_trees( parse_use_trees!( $( $input, ) * ) , SharedPrefix :: $by) ,
1009+ parse_use_trees!( $( $output, ) * ) ,
1010+ ) ;
10301011 }
1012+ }
10311013
1032- test_merge ! ( [ "a::b::{c, d}" , "a::b::{e, f}" ] , [ "a::b::{c, d, e, f}" ] ) ;
1033- test_merge ! ( [ "a::b::c" , "a::b" ] , [ "a::{b, b::c}" ] ) ;
1034- test_merge ! ( [ "a::b" , "a::b" ] , [ "a::b" ] ) ;
1035- test_merge ! ( [ "a" , "a::b" , "a::b::c" ] , [ "a::{self, b, b::c}" ] ) ;
1014+ #[ test]
1015+ fn test_use_tree_merge_crate ( ) {
1016+ test_merge ! (
1017+ Crate ,
1018+ [ "a::b::{c, d}" , "a::b::{e, f}" ] ,
1019+ [ "a::b::{c, d, e, f}" ]
1020+ ) ;
1021+ test_merge ! ( Crate , [ "a::b::c" , "a::b" ] , [ "a::{b, b::c}" ] ) ;
1022+ test_merge ! ( Crate , [ "a::b" , "a::b" ] , [ "a::b" ] ) ;
1023+ test_merge ! ( Crate , [ "a" , "a::b" , "a::b::c" ] , [ "a::{self, b, b::c}" ] ) ;
10361024 test_merge ! (
1025+ Crate ,
10371026 [ "a" , "a::b" , "a::b::c" , "a::b::c::d" ] ,
10381027 [ "a::{self, b, b::{c, c::d}}" ]
10391028 ) ;
1040- test_merge ! ( [ "a" , "a::b" , "a::b::c" , "a::b" ] , [ "a::{self, b, b::c}" ] ) ;
10411029 test_merge ! (
1030+ Crate ,
1031+ [ "a" , "a::b" , "a::b::c" , "a::b" ] ,
1032+ [ "a::{self, b, b::c}" ]
1033+ ) ;
1034+ test_merge ! (
1035+ Crate ,
10421036 [ "a::{b::{self, c}, d::e}" , "a::d::f" ] ,
10431037 [ "a::{b::{self, c}, d::{e, f}}" ]
10441038 ) ;
10451039 test_merge ! (
1040+ Crate ,
10461041 [ "a::d::f" , "a::{b::{self, c}, d::e}" ] ,
10471042 [ "a::{b::{self, c}, d::{e, f}}" ]
10481043 ) ;
10491044 test_merge ! (
1045+ Crate ,
10501046 [ "a::{c, d, b}" , "a::{d, e, b, a, f}" , "a::{f, g, c}" ] ,
10511047 [ "a::{a, b, c, d, e, f, g}" ]
10521048 ) ;
10531049 test_merge ! (
1050+ Crate ,
10541051 [ "a::{self}" , "b::{self as foo}" ] ,
10551052 [ "a::{self}" , "b::{self as foo}" ]
10561053 ) ;
10571054 }
10581055
1056+ #[ test]
1057+ fn test_use_tree_merge_module ( ) {
1058+ test_merge ! (
1059+ Module ,
1060+ [ "foo::b" , "foo::{a, c, d::e}" ] ,
1061+ [ "foo::{a, b, c}" , "foo::d::e" ]
1062+ ) ;
1063+
1064+ test_merge ! (
1065+ Module ,
1066+ [ "foo::{a::b, a::c, d::e, d::f}" ] ,
1067+ [ "foo::a::{b, c}" , "foo::d::{e, f}" ]
1068+ ) ;
1069+ }
1070+
10591071 #[ test]
10601072 fn test_use_tree_flatten ( ) {
10611073 assert_eq ! (
0 commit comments