@@ -166,6 +166,15 @@ impl UseSegment {
166
166
167
167
pub ( crate ) fn merge_use_trees ( use_trees : Vec < UseTree > , merge_by : SharedPrefix ) -> Vec < UseTree > {
168
168
let mut result = Vec :: with_capacity ( use_trees. len ( ) ) ;
169
+
170
+ // If `merge_by` is `SharedPrefix::One`, we firstly compute the result as if it's
171
+ // `SharedPrefix::Crate`, and then merge the result one more time.
172
+ let temp_merge_by = if merge_by == SharedPrefix :: One {
173
+ SharedPrefix :: Crate
174
+ } else {
175
+ merge_by
176
+ } ;
177
+
169
178
for use_tree in use_trees {
170
179
if use_tree. has_comment ( ) || use_tree. attrs . is_some ( ) {
171
180
result. push ( use_tree) ;
@@ -187,14 +196,19 @@ pub(crate) fn merge_use_trees(use_trees: Vec<UseTree>, merge_by: SharedPrefix) -
187
196
}
188
197
if let Some ( tree) = result
189
198
. iter_mut ( )
190
- . find ( |tree| tree. share_prefix ( & flattened, merge_by ) )
199
+ . find ( |tree| tree. share_prefix ( & flattened, temp_merge_by ) )
191
200
{
192
- tree. merge ( & flattened, merge_by ) ;
201
+ tree. merge ( & flattened, temp_merge_by ) ;
193
202
} else {
194
203
result. push ( flattened) ;
195
204
}
196
205
}
197
206
}
207
+
208
+ if merge_by == SharedPrefix :: One {
209
+ result = merge_use_trees_into_one ( result) ;
210
+ }
211
+
198
212
result
199
213
}
200
214
@@ -579,6 +593,7 @@ impl UseTree {
579
593
SharedPrefix :: Module => {
580
594
self . path [ ..self . path . len ( ) - 1 ] == other. path [ ..other. path . len ( ) - 1 ]
581
595
}
596
+ SharedPrefix :: One => unreachable ! ( ) ,
582
597
}
583
598
}
584
599
}
@@ -692,6 +707,39 @@ fn merge_use_trees_inner(trees: &mut Vec<UseTree>, use_tree: UseTree, merge_by:
692
707
trees. sort ( ) ;
693
708
}
694
709
710
+ fn merge_use_trees_into_one ( trees : Vec < UseTree > ) -> Vec < UseTree > {
711
+ let mut result = vec ! [ ] ;
712
+ for mut tree in trees {
713
+ if tree. attrs . is_some ( ) {
714
+ result. push ( tree) ;
715
+ } else if let Some ( UseSegment :: List ( list) ) = result. iter_mut ( ) . find_map ( |r| {
716
+ if r. same_visibility ( & tree) && r. attrs . is_none ( ) {
717
+ r. path . get_mut ( 0 )
718
+ } else {
719
+ None
720
+ }
721
+ } ) {
722
+ list. push ( tree) ;
723
+ } else {
724
+ tree. path = vec ! [ UseSegment :: List ( vec![ tree. clone( ) ] ) ] ;
725
+ result. push ( tree) ;
726
+ }
727
+ }
728
+
729
+ // As a result of merging into one, if a `UseTree` has only one crate path just like
730
+ // `use {a::{b, c}}`, outmost curly braces can be removed.
731
+ for r in result. iter_mut ( ) {
732
+ match r. path . get ( 0 ) {
733
+ Some ( UseSegment :: List ( list) ) if r. path . len ( ) == 1 && list. len ( ) == 1 => {
734
+ * r = list[ 0 ] . clone ( ) ;
735
+ }
736
+ _ => { }
737
+ }
738
+ }
739
+
740
+ result
741
+ }
742
+
695
743
impl Hash for UseTree {
696
744
fn hash < H : Hasher > ( & self , state : & mut H ) {
697
745
self . path . hash ( state) ;
@@ -897,6 +945,7 @@ impl Rewrite for UseTree {
897
945
pub ( crate ) enum SharedPrefix {
898
946
Crate ,
899
947
Module ,
948
+ One ,
900
949
}
901
950
902
951
#[ cfg( test) ]
@@ -1111,6 +1160,25 @@ mod test {
1111
1160
) ;
1112
1161
}
1113
1162
1163
+ #[ test]
1164
+ fn test_use_tree_merge_one ( ) {
1165
+ test_merge ! ( One , [ "a" , "b" ] , [ "{a, b}" ] ) ;
1166
+
1167
+ test_merge ! (
1168
+ One ,
1169
+ [ "a" , "a::{aa, ab::{aba, abb}}" ] ,
1170
+ [ "a::{self, aa, ab::{aba, abb}}" ]
1171
+ ) ;
1172
+
1173
+ test_merge ! ( One , [ "a" , "b::{ba, *}" ] , [ "{a, b::{ba, *}}" ] ) ;
1174
+
1175
+ test_merge ! (
1176
+ One ,
1177
+ [ "a" , "b::{ba, bb}" , "a::{aa::*, ab::aba}" ] ,
1178
+ [ "{a::{self, aa::*, ab::aba}, b::{ba, bb}}" ]
1179
+ ) ;
1180
+ }
1181
+
1114
1182
#[ test]
1115
1183
fn test_flatten_use_trees ( ) {
1116
1184
assert_eq ! (
0 commit comments