@@ -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,6 +182,24 @@ pub(crate) fn merge_use_trees(use_trees: Vec<UseTree>) -> Vec<UseTree> {
179
182
result
180
183
}
181
184
185
+ pub ( crate ) fn flatten_use_trees ( use_trees : Vec < UseTree > ) -> Vec < UseTree > {
186
+ use_trees
187
+ . into_iter ( )
188
+ . flat_map ( UseTree :: flatten)
189
+ . map ( |mut tree| {
190
+ // If a path ends in `::self`, rewrite it to `::{self}`.
191
+ if let Some ( UseSegment :: Slf ( ..) ) = tree. path . last ( ) {
192
+ let self_segment = tree. path . pop ( ) . unwrap ( ) ;
193
+ tree. path . push ( UseSegment :: List ( vec ! [ UseTree :: from_path(
194
+ vec![ self_segment] ,
195
+ DUMMY_SP ,
196
+ ) ] ) ) ;
197
+ }
198
+ tree
199
+ } )
200
+ . collect ( )
201
+ }
202
+
182
203
impl fmt:: Debug for UseTree {
183
204
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
184
205
fmt:: Display :: fmt ( self , f)
@@ -333,7 +354,7 @@ impl UseTree {
333
354
} ;
334
355
335
356
let leading_modsep =
336
- context. config . edition ( ) = = Edition :: Edition2018 && a. prefix . is_global ( ) ;
357
+ context. config . edition ( ) > = Edition :: Edition2018 && a. prefix . is_global ( ) ;
337
358
338
359
let mut modsep = leading_modsep;
339
360
@@ -564,15 +585,20 @@ impl UseTree {
564
585
}
565
586
}
566
587
567
- fn share_prefix ( & self , other : & UseTree ) -> bool {
588
+ fn share_prefix ( & self , other : & UseTree , shared_prefix : SharedPrefix ) -> bool {
568
589
if self . path . is_empty ( )
569
590
|| other. path . is_empty ( )
570
591
|| self . attrs . is_some ( )
571
592
|| !self . same_visibility ( other)
572
593
{
573
594
false
574
595
} else {
575
- self . path [ 0 ] == other. path [ 0 ]
596
+ match shared_prefix {
597
+ SharedPrefix :: Crate => self . path [ 0 ] == other. path [ 0 ] ,
598
+ SharedPrefix :: Module => {
599
+ self . path [ ..self . path . len ( ) - 1 ] == other. path [ ..other. path . len ( ) - 1 ]
600
+ }
601
+ }
576
602
}
577
603
}
578
604
@@ -606,7 +632,7 @@ impl UseTree {
606
632
}
607
633
}
608
634
609
- fn merge ( & mut self , other : & UseTree ) {
635
+ fn merge ( & mut self , other : & UseTree , merge_by : SharedPrefix ) {
610
636
let mut prefix = 0 ;
611
637
for ( a, b) in self . path . iter ( ) . zip ( other. path . iter ( ) ) {
612
638
if * a == * b {
@@ -615,20 +641,30 @@ impl UseTree {
615
641
break ;
616
642
}
617
643
}
618
- if let Some ( new_path) = merge_rest ( & self . path , & other. path , prefix) {
644
+ if let Some ( new_path) = merge_rest ( & self . path , & other. path , prefix, merge_by ) {
619
645
self . path = new_path;
620
646
self . span = self . span . to ( other. span ) ;
621
647
}
622
648
}
623
649
}
624
650
625
- fn merge_rest ( a : & [ UseSegment ] , b : & [ UseSegment ] , mut len : usize ) -> Option < Vec < UseSegment > > {
651
+ fn merge_rest (
652
+ a : & [ UseSegment ] ,
653
+ b : & [ UseSegment ] ,
654
+ mut len : usize ,
655
+ merge_by : SharedPrefix ,
656
+ ) -> Option < Vec < UseSegment > > {
626
657
if a. len ( ) == len && b. len ( ) == len {
627
658
return None ;
628
659
}
629
660
if a. len ( ) != len && b. len ( ) != len {
630
- if let UseSegment :: List ( mut list) = a[ len] . clone ( ) {
631
- merge_use_trees_inner ( & mut list, UseTree :: from_path ( b[ len..] . to_vec ( ) , DUMMY_SP ) ) ;
661
+ if let UseSegment :: List ( ref list) = a[ len] {
662
+ let mut list = list. clone ( ) ;
663
+ merge_use_trees_inner (
664
+ & mut list,
665
+ UseTree :: from_path ( b[ len..] . to_vec ( ) , DUMMY_SP ) ,
666
+ merge_by,
667
+ ) ;
632
668
let mut new_path = b[ ..len] . to_vec ( ) ;
633
669
new_path. push ( UseSegment :: List ( list) ) ;
634
670
return Some ( new_path) ;
@@ -655,17 +691,19 @@ fn merge_rest(a: &[UseSegment], b: &[UseSegment], mut len: usize) -> Option<Vec<
655
691
Some ( new_path)
656
692
}
657
693
658
- fn merge_use_trees_inner ( trees : & mut Vec < UseTree > , use_tree : UseTree ) {
659
- let similar_trees = trees. iter_mut ( ) . filter ( |tree| tree. share_prefix ( & use_tree) ) ;
660
- if use_tree. path . len ( ) == 1 {
694
+ fn merge_use_trees_inner ( trees : & mut Vec < UseTree > , use_tree : UseTree , merge_by : SharedPrefix ) {
695
+ let similar_trees = trees
696
+ . iter_mut ( )
697
+ . filter ( |tree| tree. share_prefix ( & use_tree, merge_by) ) ;
698
+ if use_tree. path . len ( ) == 1 && merge_by == SharedPrefix :: Crate {
661
699
if let Some ( tree) = similar_trees. min_by_key ( |tree| tree. path . len ( ) ) {
662
700
if tree. path . len ( ) == 1 {
663
701
return ;
664
702
}
665
703
}
666
704
} else if let Some ( tree) = similar_trees. max_by_key ( |tree| tree. path . len ( ) ) {
667
705
if tree. path . len ( ) > 1 {
668
- tree. merge ( & use_tree) ;
706
+ tree. merge ( & use_tree, merge_by ) ;
669
707
return ;
670
708
}
671
709
}
@@ -868,6 +906,12 @@ impl Rewrite for UseTree {
868
906
}
869
907
}
870
908
909
+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
910
+ pub ( crate ) enum SharedPrefix {
911
+ Crate ,
912
+ Module ,
913
+ }
914
+
871
915
#[ cfg( test) ]
872
916
mod test {
873
917
use super :: * ;
@@ -1014,44 +1058,91 @@ mod test {
1014
1058
}
1015
1059
}
1016
1060
1017
- #[ test]
1018
- fn test_use_tree_merge ( ) {
1019
- macro_rules! test_merge {
1020
- ( [ $( $input: expr) ,* $( , ) * ] , [ $( $output: expr) ,* $( , ) * ] ) => {
1021
- assert_eq!(
1022
- merge_use_trees( parse_use_trees!( $( $input, ) * ) ) ,
1023
- parse_use_trees!( $( $output, ) * ) ,
1024
- ) ;
1025
- }
1061
+ macro_rules! test_merge {
1062
+ ( $by: ident, [ $( $input: expr) ,* $( , ) * ] , [ $( $output: expr) ,* $( , ) * ] ) => {
1063
+ assert_eq!(
1064
+ merge_use_trees( parse_use_trees!( $( $input, ) * ) , SharedPrefix :: $by) ,
1065
+ parse_use_trees!( $( $output, ) * ) ,
1066
+ ) ;
1026
1067
}
1068
+ }
1027
1069
1028
- test_merge ! ( [ "a::b::{c, d}" , "a::b::{e, f}" ] , [ "a::b::{c, d, e, f}" ] ) ;
1029
- test_merge ! ( [ "a::b::c" , "a::b" ] , [ "a::{b, b::c}" ] ) ;
1030
- test_merge ! ( [ "a::b" , "a::b" ] , [ "a::b" ] ) ;
1031
- test_merge ! ( [ "a" , "a::b" , "a::b::c" ] , [ "a::{self, b, b::c}" ] ) ;
1070
+ #[ test]
1071
+ fn test_use_tree_merge_crate ( ) {
1072
+ test_merge ! (
1073
+ Crate ,
1074
+ [ "a::b::{c, d}" , "a::b::{e, f}" ] ,
1075
+ [ "a::b::{c, d, e, f}" ]
1076
+ ) ;
1077
+ test_merge ! ( Crate , [ "a::b::c" , "a::b" ] , [ "a::{b, b::c}" ] ) ;
1078
+ test_merge ! ( Crate , [ "a::b" , "a::b" ] , [ "a::b" ] ) ;
1079
+ test_merge ! ( Crate , [ "a" , "a::b" , "a::b::c" ] , [ "a::{self, b, b::c}" ] ) ;
1032
1080
test_merge ! (
1081
+ Crate ,
1033
1082
[ "a" , "a::b" , "a::b::c" , "a::b::c::d" ] ,
1034
1083
[ "a::{self, b, b::{c, c::d}}" ]
1035
1084
) ;
1036
- test_merge ! ( [ "a" , "a::b" , "a::b::c" , "a::b" ] , [ "a::{self, b, b::c}" ] ) ;
1037
1085
test_merge ! (
1086
+ Crate ,
1087
+ [ "a" , "a::b" , "a::b::c" , "a::b" ] ,
1088
+ [ "a::{self, b, b::c}" ]
1089
+ ) ;
1090
+ test_merge ! (
1091
+ Crate ,
1038
1092
[ "a::{b::{self, c}, d::e}" , "a::d::f" ] ,
1039
1093
[ "a::{b::{self, c}, d::{e, f}}" ]
1040
1094
) ;
1041
1095
test_merge ! (
1096
+ Crate ,
1042
1097
[ "a::d::f" , "a::{b::{self, c}, d::e}" ] ,
1043
1098
[ "a::{b::{self, c}, d::{e, f}}" ]
1044
1099
) ;
1045
1100
test_merge ! (
1101
+ Crate ,
1046
1102
[ "a::{c, d, b}" , "a::{d, e, b, a, f}" , "a::{f, g, c}" ] ,
1047
1103
[ "a::{a, b, c, d, e, f, g}" ]
1048
1104
) ;
1049
1105
test_merge ! (
1106
+ Crate ,
1050
1107
[ "a::{self}" , "b::{self as foo}" ] ,
1051
1108
[ "a::{self}" , "b::{self as foo}" ]
1052
1109
) ;
1053
1110
}
1054
1111
1112
+ #[ test]
1113
+ fn test_use_tree_merge_module ( ) {
1114
+ test_merge ! (
1115
+ Module ,
1116
+ [ "foo::b" , "foo::{a, c, d::e}" ] ,
1117
+ [ "foo::{a, b, c}" , "foo::d::e" ]
1118
+ ) ;
1119
+
1120
+ test_merge ! (
1121
+ Module ,
1122
+ [ "foo::{a::b, a::c, d::e, d::f}" ] ,
1123
+ [ "foo::a::{b, c}" , "foo::d::{e, f}" ]
1124
+ ) ;
1125
+ }
1126
+
1127
+ #[ test]
1128
+ fn test_flatten_use_trees ( ) {
1129
+ assert_eq ! (
1130
+ flatten_use_trees( parse_use_trees![ "foo::{a::{b, c}, d::e}" ] ) ,
1131
+ parse_use_trees![ "foo::a::b" , "foo::a::c" , "foo::d::e" ]
1132
+ ) ;
1133
+
1134
+ assert_eq ! (
1135
+ flatten_use_trees( parse_use_trees![ "foo::{self, a, b::{c, d}, e::*}" ] ) ,
1136
+ parse_use_trees![
1137
+ "foo::{self}" ,
1138
+ "foo::a" ,
1139
+ "foo::b::c" ,
1140
+ "foo::b::d" ,
1141
+ "foo::e::*"
1142
+ ]
1143
+ ) ;
1144
+ }
1145
+
1055
1146
#[ test]
1056
1147
fn test_use_tree_flatten ( ) {
1057
1148
assert_eq ! (
0 commit comments