@@ -193,9 +193,10 @@ fn rewrite_reorderable_item(
193
193
}
194
194
}
195
195
196
- /// Rewrite a list of items with reordering. Every item in `items` must have
197
- /// the same `ast::ItemKind`.
198
- fn rewrite_reorderable_items (
196
+ /// Rewrite a list of items with reordering and/or regrouping. Every item
197
+ /// in `items` must have the same `ast::ItemKind`. Whether reordering, regrouping,
198
+ /// or both ore done is determined from the `context`.
199
+ fn rewrite_reorderable_or_regroupable_items (
199
200
context : & RewriteContext < ' _ > ,
200
201
reorderable_items : & [ & ast:: Item ] ,
201
202
shape : Shape ,
@@ -229,16 +230,20 @@ fn rewrite_reorderable_items(
229
230
normalized_items = merge_use_trees ( normalized_items) ;
230
231
}
231
232
232
- let reordered_imports = if context. config . group_imports ( ) != GroupImportsTactic :: None {
233
- group_and_sort_imports ( normalized_items)
233
+ let mut regrouped_items = if context. config . group_imports ( ) != GroupImportsTactic :: None
234
+ {
235
+ group_imports ( normalized_items)
234
236
} else {
235
- normalized_items. sort ( ) ;
236
237
vec ! [ normalized_items]
237
238
} ;
238
239
240
+ if context. config . reorder_imports ( ) {
241
+ regrouped_items. iter_mut ( ) . for_each ( |items| items. sort ( ) )
242
+ }
243
+
239
244
// 4 = "use ", 1 = ";"
240
245
let nested_shape = shape. offset_left ( 4 ) ?. sub_width ( 1 ) ?;
241
- let item_vec: Vec < _ > = reordered_imports
246
+ let item_vec: Vec < _ > = regrouped_items
242
247
. into_iter ( )
243
248
. filter ( |use_group| !use_group. is_empty ( ) )
244
249
. map ( |use_group| {
@@ -284,7 +289,7 @@ fn contains_macro_use_attr(attrs: &[ast::Attribute]) -> bool {
284
289
285
290
/// Divides imports into three groups, corresponding to standard, external
286
291
/// and local imports. Sorts each subgroup.
287
- fn group_and_sort_imports ( uts : Vec < UseTree > ) -> Vec < Vec < UseTree > > {
292
+ fn group_imports ( uts : Vec < UseTree > ) -> Vec < Vec < UseTree > > {
288
293
let mut std_imports = Vec :: new ( ) ;
289
294
let mut external_imports = Vec :: new ( ) ;
290
295
let mut local_imports = Vec :: new ( ) ;
@@ -307,10 +312,6 @@ fn group_and_sort_imports(uts: Vec<UseTree>) -> Vec<Vec<UseTree>> {
307
312
}
308
313
}
309
314
310
- std_imports. sort ( ) ;
311
- external_imports. sort ( ) ;
312
- local_imports. sort ( ) ;
313
-
314
315
vec ! [ std_imports, external_imports, local_imports]
315
316
}
316
317
@@ -357,6 +358,15 @@ impl ReorderableItemKind {
357
358
}
358
359
}
359
360
361
+ fn is_regroupable ( self , config : & Config ) -> bool {
362
+ match self {
363
+ ReorderableItemKind :: ExternCrate
364
+ | ReorderableItemKind :: Mod
365
+ | ReorderableItemKind :: Other => false ,
366
+ ReorderableItemKind :: Use => config. group_imports ( ) != GroupImportsTactic :: None ,
367
+ }
368
+ }
369
+
360
370
fn in_group ( self , config : & Config ) -> bool {
361
371
match self {
362
372
ReorderableItemKind :: ExternCrate | ReorderableItemKind :: Mod => true ,
@@ -367,10 +377,10 @@ impl ReorderableItemKind {
367
377
}
368
378
369
379
impl < ' b , ' a : ' b > FmtVisitor < ' a > {
370
- /// Format items with the same item kind and reorder them. If `in_group` is
371
- /// ` true`, then the items separated by an empty line will not be reordered
372
- /// together.
373
- fn walk_reorderable_items (
380
+ /// Format items with the same item kind and reorder them, regroup them, or
381
+ /// both. If `in_group` is ` true`, then the items separated by an empty line
382
+ /// will not be reordered together.
383
+ fn walk_reorderable_or_regroupable_items (
374
384
& mut self ,
375
385
items : & [ & ast:: Item ] ,
376
386
item_kind : ReorderableItemKind ,
@@ -400,7 +410,12 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
400
410
let lo = items. first ( ) . unwrap ( ) . span ( ) . lo ( ) ;
401
411
let hi = items. last ( ) . unwrap ( ) . span ( ) . hi ( ) ;
402
412
let span = mk_sp ( lo, hi) ;
403
- let rw = rewrite_reorderable_items ( & self . get_context ( ) , items, self . shape ( ) , span) ;
413
+ let rw = rewrite_reorderable_or_regroupable_items (
414
+ & self . get_context ( ) ,
415
+ items,
416
+ self . shape ( ) ,
417
+ span,
418
+ ) ;
404
419
self . push_rewrite ( span, rw) ;
405
420
} else {
406
421
for item in items {
@@ -419,9 +434,12 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
419
434
// subsequent items that have the same item kind to be reordered within
420
435
// `walk_reorderable_items`. Otherwise, just format the next item for output.
421
436
let item_kind = ReorderableItemKind :: from ( items[ 0 ] , self . file_mod_map ) ;
422
- if item_kind. is_reorderable ( self . config ) {
423
- let visited_items_num =
424
- self . walk_reorderable_items ( items, item_kind, item_kind. in_group ( self . config ) ) ;
437
+ if item_kind. is_reorderable ( self . config ) || item_kind. is_regroupable ( self . config ) {
438
+ let visited_items_num = self . walk_reorderable_or_regroupable_items (
439
+ items,
440
+ item_kind,
441
+ item_kind. in_group ( self . config ) ,
442
+ ) ;
425
443
let ( _, rest) = items. split_at ( visited_items_num) ;
426
444
items = rest;
427
445
} else {
0 commit comments