@@ -160,7 +160,7 @@ impl UseSegment {
160
160
}
161
161
}
162
162
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 > {
164
164
let mut result = Vec :: with_capacity ( use_trees. len ( ) ) ;
165
165
for use_tree in use_trees {
166
166
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> {
169
169
}
170
170
171
171
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) ;
174
177
} else {
175
178
result. push ( flattened) ;
176
179
}
@@ -179,48 +182,6 @@ pub(crate) fn merge_use_trees(use_trees: Vec<UseTree>) -> Vec<UseTree> {
179
182
result
180
183
}
181
184
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
-
224
185
impl fmt:: Debug for UseTree {
225
186
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
226
187
fmt:: Display :: fmt ( self , f)
@@ -568,15 +529,20 @@ impl UseTree {
568
529
}
569
530
}
570
531
571
- fn share_prefix ( & self , other : & UseTree ) -> bool {
532
+ fn share_prefix ( & self , other : & UseTree , shared_prefix : SharedPrefix ) -> bool {
572
533
if self . path . is_empty ( )
573
534
|| other. path . is_empty ( )
574
535
|| self . attrs . is_some ( )
575
536
|| !self . same_visibility ( other)
576
537
{
577
538
false
578
539
} 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
+ }
580
546
}
581
547
}
582
548
@@ -610,7 +576,7 @@ impl UseTree {
610
576
}
611
577
}
612
578
613
- fn merge ( & mut self , other : & UseTree ) {
579
+ fn merge ( & mut self , other : & UseTree , merge_by : SharedPrefix ) {
614
580
let mut prefix = 0 ;
615
581
for ( a, b) in self . path . iter ( ) . zip ( other. path . iter ( ) ) {
616
582
if * a == * b {
@@ -619,20 +585,30 @@ impl UseTree {
619
585
break ;
620
586
}
621
587
}
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 ) {
623
589
self . path = new_path;
624
590
self . span = self . span . to ( other. span ) ;
625
591
}
626
592
}
627
593
}
628
594
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 > > {
630
601
if a. len ( ) == len && b. len ( ) == len {
631
602
return None ;
632
603
}
633
604
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
+ ) ;
636
612
let mut new_path = b[ ..len] . to_vec ( ) ;
637
613
new_path. push ( UseSegment :: List ( list) ) ;
638
614
return Some ( new_path) ;
@@ -659,17 +635,19 @@ fn merge_rest(a: &[UseSegment], b: &[UseSegment], mut len: usize) -> Option<Vec<
659
635
Some ( new_path)
660
636
}
661
637
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 {
665
643
if let Some ( tree) = similar_trees. min_by_key ( |tree| tree. path . len ( ) ) {
666
644
if tree. path . len ( ) == 1 {
667
645
return ;
668
646
}
669
647
}
670
648
} else if let Some ( tree) = similar_trees. max_by_key ( |tree| tree. path . len ( ) ) {
671
649
if tree. path . len ( ) > 1 {
672
- tree. merge ( & use_tree) ;
650
+ tree. merge ( & use_tree, merge_by ) ;
673
651
return ;
674
652
}
675
653
}
@@ -872,6 +850,12 @@ impl Rewrite for UseTree {
872
850
}
873
851
}
874
852
853
+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
854
+ pub ( crate ) enum SharedPrefix {
855
+ Crate ,
856
+ Module ,
857
+ }
858
+
875
859
#[ cfg( test) ]
876
860
mod test {
877
861
use super :: * ;
@@ -1018,44 +1002,72 @@ mod test {
1018
1002
}
1019
1003
}
1020
1004
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
+ ) ;
1030
1011
}
1012
+ }
1031
1013
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}" ] ) ;
1036
1024
test_merge ! (
1025
+ Crate ,
1037
1026
[ "a" , "a::b" , "a::b::c" , "a::b::c::d" ] ,
1038
1027
[ "a::{self, b, b::{c, c::d}}" ]
1039
1028
) ;
1040
- test_merge ! ( [ "a" , "a::b" , "a::b::c" , "a::b" ] , [ "a::{self, b, b::c}" ] ) ;
1041
1029
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 ,
1042
1036
[ "a::{b::{self, c}, d::e}" , "a::d::f" ] ,
1043
1037
[ "a::{b::{self, c}, d::{e, f}}" ]
1044
1038
) ;
1045
1039
test_merge ! (
1040
+ Crate ,
1046
1041
[ "a::d::f" , "a::{b::{self, c}, d::e}" ] ,
1047
1042
[ "a::{b::{self, c}, d::{e, f}}" ]
1048
1043
) ;
1049
1044
test_merge ! (
1045
+ Crate ,
1050
1046
[ "a::{c, d, b}" , "a::{d, e, b, a, f}" , "a::{f, g, c}" ] ,
1051
1047
[ "a::{a, b, c, d, e, f, g}" ]
1052
1048
) ;
1053
1049
test_merge ! (
1050
+ Crate ,
1054
1051
[ "a::{self}" , "b::{self as foo}" ] ,
1055
1052
[ "a::{self}" , "b::{self as foo}" ]
1056
1053
) ;
1057
1054
}
1058
1055
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
+
1059
1071
#[ test]
1060
1072
fn test_use_tree_flatten ( ) {
1061
1073
assert_eq ! (
0 commit comments