]> git.lizzy.rs Git - rust.git/blob - src/imports.rs
Use the traits added to the Rust 2021 Edition prelude
[rust.git] / src / imports.rs
1 use std::borrow::Cow;
2 use std::cmp::Ordering;
3 use std::fmt;
4
5 use rustc_ast::ast::{self, UseTreeKind};
6 use rustc_span::{
7     symbol::{self, sym},
8     BytePos, Span, DUMMY_SP,
9 };
10
11 use crate::comment::combine_strs_with_missing_comments;
12 use crate::config::lists::*;
13 use crate::config::ImportGranularity;
14 use crate::config::{Edition, IndentStyle};
15 use crate::lists::{
16     definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator,
17 };
18 use crate::rewrite::{Rewrite, RewriteContext};
19 use crate::shape::Shape;
20 use crate::source_map::SpanUtils;
21 use crate::spanned::Spanned;
22 use crate::utils::{is_same_visibility, mk_sp, rewrite_ident};
23 use crate::visitor::FmtVisitor;
24
25 /// Returns a name imported by a `use` declaration.
26 /// E.g., returns `Ordering` for `std::cmp::Ordering` and `self` for `std::cmp::self`.
27 pub(crate) fn path_to_imported_ident(path: &ast::Path) -> symbol::Ident {
28     path.segments.last().unwrap().ident
29 }
30
31 impl<'a> FmtVisitor<'a> {
32     pub(crate) fn format_import(&mut self, item: &ast::Item, tree: &ast::UseTree) {
33         let span = item.span();
34         let shape = self.shape();
35         let rw = UseTree::from_ast(
36             &self.get_context(),
37             tree,
38             None,
39             Some(item.vis.clone()),
40             Some(item.span.lo()),
41             Some(item.attrs.clone()),
42         )
43         .rewrite_top_level(&self.get_context(), shape);
44         match rw {
45             Some(ref s) if s.is_empty() => {
46                 // Format up to last newline
47                 let prev_span = mk_sp(self.last_pos, source!(self, span).lo());
48                 let trimmed_snippet = self.snippet(prev_span).trim_end();
49                 let span_end = self.last_pos + BytePos(trimmed_snippet.len() as u32);
50                 self.format_missing(span_end);
51                 // We have an excessive newline from the removed import.
52                 if self.buffer.ends_with('\n') {
53                     self.buffer.pop();
54                     self.line_number -= 1;
55                 }
56                 self.last_pos = source!(self, span).hi();
57             }
58             Some(ref s) => {
59                 self.format_missing_with_indent(source!(self, span).lo());
60                 self.push_str(s);
61                 self.last_pos = source!(self, span).hi();
62             }
63             None => {
64                 self.format_missing_with_indent(source!(self, span).lo());
65                 self.format_missing(source!(self, span).hi());
66             }
67         }
68     }
69 }
70
71 // Ordering of imports
72
73 // We order imports by translating to our own representation and then sorting.
74 // The Rust AST data structures are really bad for this. Rustfmt applies a bunch
75 // of normalisations to imports and since we want to sort based on the result
76 // of these (and to maintain idempotence) we must apply the same normalisations
77 // to the data structures for sorting.
78 //
79 // We sort `self` and `super` before other imports, then identifier imports,
80 // then glob imports, then lists of imports. We do not take aliases into account
81 // when ordering unless the imports are identical except for the alias (rare in
82 // practice).
83
84 // FIXME(#2531): we should unify the comparison code here with the formatting
85 // code elsewhere since we are essentially string-ifying twice. Furthermore, by
86 // parsing to our own format on comparison, we repeat a lot of work when
87 // sorting.
88
89 // FIXME we do a lot of allocation to make our own representation.
90 #[derive(Clone, Eq, PartialEq)]
91 pub(crate) enum UseSegment {
92     Ident(String, Option<String>),
93     Slf(Option<String>),
94     Super(Option<String>),
95     Crate(Option<String>),
96     Glob,
97     List(Vec<UseTree>),
98 }
99
100 #[derive(Clone)]
101 pub(crate) struct UseTree {
102     pub(crate) path: Vec<UseSegment>,
103     pub(crate) span: Span,
104     // Comment information within nested use tree.
105     pub(crate) list_item: Option<ListItem>,
106     // Additional fields for top level use items.
107     // Should we have another struct for top-level use items rather than reusing this?
108     visibility: Option<ast::Visibility>,
109     attrs: Option<Vec<ast::Attribute>>,
110 }
111
112 impl PartialEq for UseTree {
113     fn eq(&self, other: &UseTree) -> bool {
114         self.path == other.path
115     }
116 }
117 impl Eq for UseTree {}
118
119 impl Spanned for UseTree {
120     fn span(&self) -> Span {
121         let lo = if let Some(ref attrs) = self.attrs {
122             attrs.iter().next().map_or(self.span.lo(), |a| a.span.lo())
123         } else {
124             self.span.lo()
125         };
126         mk_sp(lo, self.span.hi())
127     }
128 }
129
130 impl UseSegment {
131     // Clone a version of self with any top-level alias removed.
132     fn remove_alias(&self) -> UseSegment {
133         match *self {
134             UseSegment::Ident(ref s, _) => UseSegment::Ident(s.clone(), None),
135             UseSegment::Slf(_) => UseSegment::Slf(None),
136             UseSegment::Super(_) => UseSegment::Super(None),
137             UseSegment::Crate(_) => UseSegment::Crate(None),
138             _ => self.clone(),
139         }
140     }
141
142     // Check if self == other with their aliases removed.
143     fn equal_except_alias(&self, other: &Self) -> bool {
144         match (self, other) {
145             (UseSegment::Ident(ref s1, _), UseSegment::Ident(ref s2, _)) => s1 == s2,
146             (UseSegment::Slf(_), UseSegment::Slf(_))
147             | (UseSegment::Super(_), UseSegment::Super(_))
148             | (UseSegment::Crate(_), UseSegment::Crate(_))
149             | (UseSegment::Glob, UseSegment::Glob) => true,
150             (UseSegment::List(ref list1), UseSegment::List(ref list2)) => list1 == list2,
151             _ => false,
152         }
153     }
154
155     fn get_alias(&self) -> Option<&str> {
156         match self {
157             UseSegment::Ident(_, a)
158             | UseSegment::Slf(a)
159             | UseSegment::Super(a)
160             | UseSegment::Crate(a) => a.as_deref(),
161             _ => None,
162         }
163     }
164
165     fn from_path_segment(
166         context: &RewriteContext<'_>,
167         path_seg: &ast::PathSegment,
168         modsep: bool,
169     ) -> Option<UseSegment> {
170         let name = rewrite_ident(context, path_seg.ident);
171         if name.is_empty() || name == "{{root}}" {
172             return None;
173         }
174         Some(match name {
175             "self" => UseSegment::Slf(None),
176             "super" => UseSegment::Super(None),
177             "crate" => UseSegment::Crate(None),
178             _ => {
179                 let mod_sep = if modsep { "::" } else { "" };
180                 UseSegment::Ident(format!("{}{}", mod_sep, name), None)
181             }
182         })
183     }
184 }
185
186 pub(crate) fn normalize_use_trees_with_granularity(
187     use_trees: Vec<UseTree>,
188     import_granularity: ImportGranularity,
189 ) -> Vec<UseTree> {
190     let merge_by = match import_granularity {
191         ImportGranularity::Item => return flatten_use_trees(use_trees, ImportGranularity::Item),
192         ImportGranularity::Preserve => return use_trees,
193         ImportGranularity::Crate => SharedPrefix::Crate,
194         ImportGranularity::Module => SharedPrefix::Module,
195         ImportGranularity::One => SharedPrefix::One,
196     };
197
198     let mut result = Vec::with_capacity(use_trees.len());
199     for use_tree in use_trees {
200         if use_tree.has_comment() || use_tree.attrs.is_some() {
201             result.push(use_tree);
202             continue;
203         }
204
205         for mut flattened in use_tree.flatten(import_granularity) {
206             if let Some(tree) = result
207                 .iter_mut()
208                 .find(|tree| tree.share_prefix(&flattened, merge_by))
209             {
210                 tree.merge(&flattened, merge_by);
211             } else {
212                 // If this is the first tree with this prefix, handle potential trailing ::self
213                 if merge_by == SharedPrefix::Module {
214                     flattened = flattened.nest_trailing_self();
215                 }
216                 result.push(flattened);
217             }
218         }
219     }
220     result
221 }
222
223 fn flatten_use_trees(
224     use_trees: Vec<UseTree>,
225     import_granularity: ImportGranularity,
226 ) -> Vec<UseTree> {
227     use_trees
228         .into_iter()
229         .flat_map(|tree| tree.flatten(import_granularity))
230         .map(UseTree::nest_trailing_self)
231         .collect()
232 }
233
234 impl fmt::Debug for UseTree {
235     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
236         fmt::Display::fmt(self, f)
237     }
238 }
239
240 impl fmt::Debug for UseSegment {
241     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
242         fmt::Display::fmt(self, f)
243     }
244 }
245
246 impl fmt::Display for UseSegment {
247     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
248         match *self {
249             UseSegment::Glob => write!(f, "*"),
250             UseSegment::Ident(ref s, Some(ref alias)) => write!(f, "{} as {}", s, alias),
251             UseSegment::Ident(ref s, None) => write!(f, "{}", s),
252             UseSegment::Slf(..) => write!(f, "self"),
253             UseSegment::Super(..) => write!(f, "super"),
254             UseSegment::Crate(..) => write!(f, "crate"),
255             UseSegment::List(ref list) => {
256                 write!(f, "{{")?;
257                 for (i, item) in list.iter().enumerate() {
258                     if i != 0 {
259                         write!(f, ", ")?;
260                     }
261                     write!(f, "{}", item)?;
262                 }
263                 write!(f, "}}")
264             }
265         }
266     }
267 }
268 impl fmt::Display for UseTree {
269     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
270         for (i, segment) in self.path.iter().enumerate() {
271             if i != 0 {
272                 write!(f, "::")?;
273             }
274             write!(f, "{}", segment)?;
275         }
276         Ok(())
277     }
278 }
279
280 impl UseTree {
281     // Rewrite use tree with `use ` and a trailing `;`.
282     pub(crate) fn rewrite_top_level(
283         &self,
284         context: &RewriteContext<'_>,
285         shape: Shape,
286     ) -> Option<String> {
287         let vis = self.visibility.as_ref().map_or(Cow::from(""), |vis| {
288             crate::utils::format_visibility(context, vis)
289         });
290         let use_str = self
291             .rewrite(context, shape.offset_left(vis.len())?)
292             .map(|s| {
293                 if s.is_empty() {
294                     s
295                 } else {
296                     format!("{}use {};", vis, s)
297                 }
298             })?;
299         match self.attrs {
300             Some(ref attrs) if !attrs.is_empty() => {
301                 let attr_str = attrs.rewrite(context, shape)?;
302                 let lo = attrs.last().as_ref()?.span.hi();
303                 let hi = self.span.lo();
304                 let span = mk_sp(lo, hi);
305
306                 let allow_extend = if attrs.len() == 1 {
307                     let line_len = attr_str.len() + 1 + use_str.len();
308                     !attrs.first().unwrap().is_doc_comment()
309                         && context.config.inline_attribute_width() >= line_len
310                 } else {
311                     false
312                 };
313
314                 combine_strs_with_missing_comments(
315                     context,
316                     &attr_str,
317                     &use_str,
318                     span,
319                     shape,
320                     allow_extend,
321                 )
322             }
323             _ => Some(use_str),
324         }
325     }
326
327     // FIXME: Use correct span?
328     // The given span is essentially incorrect, since we are reconstructing
329     // use-statements. This should not be a problem, though, since we have
330     // already tried to extract comment and observed that there are no comment
331     // around the given use item, and the span will not be used afterward.
332     fn from_path(path: Vec<UseSegment>, span: Span) -> UseTree {
333         UseTree {
334             path,
335             span,
336             list_item: None,
337             visibility: None,
338             attrs: None,
339         }
340     }
341
342     pub(crate) fn from_ast_with_normalization(
343         context: &RewriteContext<'_>,
344         item: &ast::Item,
345     ) -> Option<UseTree> {
346         match item.kind {
347             ast::ItemKind::Use(ref use_tree) => Some(
348                 UseTree::from_ast(
349                     context,
350                     use_tree,
351                     None,
352                     Some(item.vis.clone()),
353                     Some(item.span.lo()),
354                     if item.attrs.is_empty() {
355                         None
356                     } else {
357                         Some(item.attrs.clone())
358                     },
359                 )
360                 .normalize(),
361             ),
362             _ => None,
363         }
364     }
365
366     fn from_ast(
367         context: &RewriteContext<'_>,
368         a: &ast::UseTree,
369         list_item: Option<ListItem>,
370         visibility: Option<ast::Visibility>,
371         opt_lo: Option<BytePos>,
372         attrs: Option<Vec<ast::Attribute>>,
373     ) -> UseTree {
374         let span = if let Some(lo) = opt_lo {
375             mk_sp(lo, a.span.hi())
376         } else {
377             a.span
378         };
379         let mut result = UseTree {
380             path: vec![],
381             span,
382             list_item,
383             visibility,
384             attrs,
385         };
386
387         let leading_modsep =
388             context.config.edition() >= Edition::Edition2018 && a.prefix.is_global();
389
390         let mut modsep = leading_modsep;
391
392         for p in &a.prefix.segments {
393             if let Some(use_segment) = UseSegment::from_path_segment(context, p, modsep) {
394                 result.path.push(use_segment);
395                 modsep = false;
396             }
397         }
398
399         match a.kind {
400             UseTreeKind::Glob => {
401                 // in case of a global path and the glob starts at the root, e.g., "::*"
402                 if a.prefix.segments.len() == 1 && leading_modsep {
403                     result.path.push(UseSegment::Ident("".to_owned(), None));
404                 }
405                 result.path.push(UseSegment::Glob);
406             }
407             UseTreeKind::Nested(ref list) => {
408                 // Extract comments between nested use items.
409                 // This needs to be done before sorting use items.
410                 let items = itemize_list(
411                     context.snippet_provider,
412                     list.iter().map(|(tree, _)| tree),
413                     "}",
414                     ",",
415                     |tree| tree.span.lo(),
416                     |tree| tree.span.hi(),
417                     |_| Some("".to_owned()), // We only need comments for now.
418                     context.snippet_provider.span_after(a.span, "{"),
419                     a.span.hi(),
420                     false,
421                 );
422
423                 // in case of a global path and the nested list starts at the root,
424                 // e.g., "::{foo, bar}"
425                 if a.prefix.segments.len() == 1 && leading_modsep {
426                     result.path.push(UseSegment::Ident("".to_owned(), None));
427                 }
428                 result.path.push(UseSegment::List(
429                     list.iter()
430                         .zip(items)
431                         .map(|(t, list_item)| {
432                             Self::from_ast(context, &t.0, Some(list_item), None, None, None)
433                         })
434                         .collect(),
435                 ));
436             }
437             UseTreeKind::Simple(ref rename, ..) => {
438                 // If the path has leading double colons and is composed of only 2 segments, then we
439                 // bypass the call to path_to_imported_ident which would get only the ident and
440                 // lose the path root, e.g., `that` in `::that`.
441                 // The span of `a.prefix` contains the leading colons.
442                 let name = if a.prefix.segments.len() == 2 && leading_modsep {
443                     context.snippet(a.prefix.span).to_owned()
444                 } else {
445                     rewrite_ident(context, path_to_imported_ident(&a.prefix)).to_owned()
446                 };
447                 let alias = rename.and_then(|ident| {
448                     if ident.name == sym::underscore_imports {
449                         // for impl-only-use
450                         Some("_".to_owned())
451                     } else if ident == path_to_imported_ident(&a.prefix) {
452                         None
453                     } else {
454                         Some(rewrite_ident(context, ident).to_owned())
455                     }
456                 });
457                 let segment = match name.as_ref() {
458                     "self" => UseSegment::Slf(alias),
459                     "super" => UseSegment::Super(alias),
460                     "crate" => UseSegment::Crate(alias),
461                     _ => UseSegment::Ident(name, alias),
462                 };
463
464                 // `name` is already in result.
465                 result.path.pop();
466                 result.path.push(segment);
467             }
468         }
469         result
470     }
471
472     // Do the adjustments that rustfmt does elsewhere to use paths.
473     pub(crate) fn normalize(mut self) -> UseTree {
474         let mut last = self.path.pop().expect("Empty use tree?");
475         // Hack around borrow checker.
476         let mut normalize_sole_list = false;
477         let mut aliased_self = false;
478
479         // Remove foo::{} or self without attributes.
480         match last {
481             _ if self.attrs.is_some() => (),
482             UseSegment::List(ref list) if list.is_empty() => {
483                 self.path = vec![];
484                 return self;
485             }
486             UseSegment::Slf(None) if self.path.is_empty() && self.visibility.is_some() => {
487                 self.path = vec![];
488                 return self;
489             }
490             _ => (),
491         }
492
493         // Normalise foo::self -> foo.
494         if let UseSegment::Slf(None) = last {
495             if !self.path.is_empty() {
496                 return self;
497             }
498         }
499
500         // Normalise foo::self as bar -> foo as bar.
501         if let UseSegment::Slf(_) = last {
502             if let Some(UseSegment::Ident(_, None)) = self.path.last() {
503                 aliased_self = true;
504             }
505         }
506
507         let mut done = false;
508         if aliased_self {
509             match self.path.last_mut() {
510                 Some(UseSegment::Ident(_, ref mut old_rename)) => {
511                     assert!(old_rename.is_none());
512                     if let UseSegment::Slf(Some(rename)) = last.clone() {
513                         *old_rename = Some(rename);
514                         done = true;
515                     }
516                 }
517                 _ => unreachable!(),
518             }
519         }
520
521         if done {
522             return self;
523         }
524
525         // Normalise foo::{bar} -> foo::bar
526         if let UseSegment::List(ref list) = last {
527             if list.len() == 1 && list[0].to_string() != "self" {
528                 normalize_sole_list = true;
529             }
530         }
531
532         if normalize_sole_list {
533             match last {
534                 UseSegment::List(list) => {
535                     for seg in &list[0].path {
536                         self.path.push(seg.clone());
537                     }
538                     return self.normalize();
539                 }
540                 _ => unreachable!(),
541             }
542         }
543
544         // Recursively normalize elements of a list use (including sorting the list).
545         if let UseSegment::List(list) = last {
546             let mut list = list.into_iter().map(UseTree::normalize).collect::<Vec<_>>();
547             list.sort();
548             last = UseSegment::List(list);
549         }
550
551         self.path.push(last);
552         self
553     }
554
555     fn has_comment(&self) -> bool {
556         self.list_item.as_ref().map_or(false, ListItem::has_comment)
557     }
558
559     fn same_visibility(&self, other: &UseTree) -> bool {
560         match (&self.visibility, &other.visibility) {
561             (
562                 Some(ast::Visibility {
563                     kind: ast::VisibilityKind::Inherited,
564                     ..
565                 }),
566                 None,
567             )
568             | (
569                 None,
570                 Some(ast::Visibility {
571                     kind: ast::VisibilityKind::Inherited,
572                     ..
573                 }),
574             )
575             | (None, None) => true,
576             (Some(ref a), Some(ref b)) => is_same_visibility(a, b),
577             _ => false,
578         }
579     }
580
581     fn share_prefix(&self, other: &UseTree, shared_prefix: SharedPrefix) -> bool {
582         if self.path.is_empty()
583             || other.path.is_empty()
584             || self.attrs.is_some()
585             || !self.same_visibility(other)
586         {
587             false
588         } else {
589             match shared_prefix {
590                 SharedPrefix::Crate => self.path[0] == other.path[0],
591                 SharedPrefix::Module => {
592                     self.path[..self.path.len() - 1] == other.path[..other.path.len() - 1]
593                 }
594                 SharedPrefix::One => true,
595             }
596         }
597     }
598
599     fn flatten(self, import_granularity: ImportGranularity) -> Vec<UseTree> {
600         if self.path.is_empty() {
601             return vec![self];
602         }
603         match self.path.clone().last().unwrap() {
604             UseSegment::List(list) => {
605                 if list.len() == 1 && list[0].path.len() == 1 {
606                     if let UseSegment::Slf(..) = list[0].path[0] {
607                         return vec![self];
608                     };
609                 }
610                 let prefix = &self.path[..self.path.len() - 1];
611                 let mut result = vec![];
612                 for nested_use_tree in list {
613                     for flattend in &mut nested_use_tree.clone().flatten(import_granularity) {
614                         let mut new_path = prefix.to_vec();
615                         new_path.append(&mut flattend.path);
616                         result.push(UseTree {
617                             path: new_path,
618                             span: self.span,
619                             list_item: None,
620                             visibility: self.visibility.clone(),
621                             // only retain attributes for `ImportGranularity::Item`
622                             attrs: match import_granularity {
623                                 ImportGranularity::Item => self.attrs.clone(),
624                                 _ => None,
625                             },
626                         });
627                     }
628                 }
629
630                 result
631             }
632             _ => vec![self],
633         }
634     }
635
636     fn merge(&mut self, other: &UseTree, merge_by: SharedPrefix) {
637         let mut prefix = 0;
638         for (a, b) in self.path.iter().zip(other.path.iter()) {
639             // only discard the alias at the root of the tree
640             if (prefix == 0 && a.equal_except_alias(b)) || a == b {
641                 prefix += 1;
642             } else {
643                 break;
644             }
645         }
646         if let Some(new_path) = merge_rest(&self.path, &other.path, prefix, merge_by) {
647             self.path = new_path;
648             self.span = self.span.to(other.span);
649         }
650     }
651
652     /// If this tree ends in `::self`, rewrite it to `::{self}`.
653     fn nest_trailing_self(mut self) -> UseTree {
654         if let Some(UseSegment::Slf(..)) = self.path.last() {
655             let self_segment = self.path.pop().unwrap();
656             self.path.push(UseSegment::List(vec![UseTree::from_path(
657                 vec![self_segment],
658                 DUMMY_SP,
659             )]));
660         }
661         self
662     }
663 }
664
665 fn merge_rest(
666     a: &[UseSegment],
667     b: &[UseSegment],
668     mut len: usize,
669     merge_by: SharedPrefix,
670 ) -> Option<Vec<UseSegment>> {
671     if a.len() == len && b.len() == len {
672         return None;
673     }
674     if a.len() != len && b.len() != len {
675         if let UseSegment::List(ref list) = a[len] {
676             let mut list = list.clone();
677             merge_use_trees_inner(
678                 &mut list,
679                 UseTree::from_path(b[len..].to_vec(), DUMMY_SP),
680                 merge_by,
681             );
682             let mut new_path = b[..len].to_vec();
683             new_path.push(UseSegment::List(list));
684             return Some(new_path);
685         }
686     } else if len == 1 {
687         let (common, rest) = if a.len() == len {
688             (&a[0], &b[1..])
689         } else {
690             (&b[0], &a[1..])
691         };
692         let mut list = vec![UseTree::from_path(
693             vec![UseSegment::Slf(common.get_alias().map(ToString::to_string))],
694             DUMMY_SP,
695         )];
696         match rest {
697             [UseSegment::List(rest_list)] => list.extend(rest_list.clone()),
698             _ => list.push(UseTree::from_path(rest.to_vec(), DUMMY_SP)),
699         }
700         return Some(vec![b[0].clone(), UseSegment::List(list)]);
701     } else {
702         len -= 1;
703     }
704     let mut list = vec![
705         UseTree::from_path(a[len..].to_vec(), DUMMY_SP),
706         UseTree::from_path(b[len..].to_vec(), DUMMY_SP),
707     ];
708     list.sort();
709     let mut new_path = b[..len].to_vec();
710     new_path.push(UseSegment::List(list));
711     Some(new_path)
712 }
713
714 fn merge_use_trees_inner(trees: &mut Vec<UseTree>, use_tree: UseTree, merge_by: SharedPrefix) {
715     struct SimilarTree<'a> {
716         similarity: usize,
717         path_len: usize,
718         tree: &'a mut UseTree,
719     }
720
721     let similar_trees = trees.iter_mut().filter_map(|tree| {
722         if tree.share_prefix(&use_tree, merge_by) {
723             // In the case of `SharedPrefix::One`, `similarity` is used for deciding with which
724             // tree `use_tree` should be merge.
725             // In other cases `similarity` won't be used, so set it to `0` as a dummy value.
726             let similarity = if merge_by == SharedPrefix::One {
727                 tree.path
728                     .iter()
729                     .zip(&use_tree.path)
730                     .take_while(|(a, b)| a.equal_except_alias(b))
731                     .count()
732             } else {
733                 0
734             };
735
736             let path_len = tree.path.len();
737             Some(SimilarTree {
738                 similarity,
739                 tree,
740                 path_len,
741             })
742         } else {
743             None
744         }
745     });
746
747     if use_tree.path.len() == 1 && merge_by == SharedPrefix::Crate {
748         if let Some(tree) = similar_trees.min_by_key(|tree| tree.path_len) {
749             if tree.path_len == 1 {
750                 return;
751             }
752         }
753     } else if merge_by == SharedPrefix::One {
754         if let Some(sim_tree) = similar_trees.max_by_key(|tree| tree.similarity) {
755             if sim_tree.similarity > 0 {
756                 sim_tree.tree.merge(&use_tree, merge_by);
757                 return;
758             }
759         }
760     } else if let Some(sim_tree) = similar_trees.max_by_key(|tree| tree.path_len) {
761         if sim_tree.path_len > 1 {
762             sim_tree.tree.merge(&use_tree, merge_by);
763             return;
764         }
765     }
766     trees.push(use_tree);
767     trees.sort();
768 }
769
770 impl PartialOrd for UseSegment {
771     fn partial_cmp(&self, other: &UseSegment) -> Option<Ordering> {
772         Some(self.cmp(other))
773     }
774 }
775 impl PartialOrd for UseTree {
776     fn partial_cmp(&self, other: &UseTree) -> Option<Ordering> {
777         Some(self.cmp(other))
778     }
779 }
780 impl Ord for UseSegment {
781     fn cmp(&self, other: &UseSegment) -> Ordering {
782         use self::UseSegment::*;
783
784         fn is_upper_snake_case(s: &str) -> bool {
785             s.chars()
786                 .all(|c| c.is_uppercase() || c == '_' || c.is_numeric())
787         }
788
789         match (self, other) {
790             (&Slf(ref a), &Slf(ref b))
791             | (&Super(ref a), &Super(ref b))
792             | (&Crate(ref a), &Crate(ref b)) => a.cmp(b),
793             (&Glob, &Glob) => Ordering::Equal,
794             (&Ident(ref ia, ref aa), &Ident(ref ib, ref ab)) => {
795                 // snake_case < CamelCase < UPPER_SNAKE_CASE
796                 if ia.starts_with(char::is_uppercase) && ib.starts_with(char::is_lowercase) {
797                     return Ordering::Greater;
798                 }
799                 if ia.starts_with(char::is_lowercase) && ib.starts_with(char::is_uppercase) {
800                     return Ordering::Less;
801                 }
802                 if is_upper_snake_case(ia) && !is_upper_snake_case(ib) {
803                     return Ordering::Greater;
804                 }
805                 if !is_upper_snake_case(ia) && is_upper_snake_case(ib) {
806                     return Ordering::Less;
807                 }
808                 let ident_ord = ia.cmp(ib);
809                 if ident_ord != Ordering::Equal {
810                     return ident_ord;
811                 }
812                 if aa.is_none() && ab.is_some() {
813                     return Ordering::Less;
814                 }
815                 if aa.is_some() && ab.is_none() {
816                     return Ordering::Greater;
817                 }
818                 aa.cmp(ab)
819             }
820             (&List(ref a), &List(ref b)) => {
821                 for (a, b) in a.iter().zip(b.iter()) {
822                     let ord = a.cmp(b);
823                     if ord != Ordering::Equal {
824                         return ord;
825                     }
826                 }
827
828                 a.len().cmp(&b.len())
829             }
830             (&Slf(_), _) => Ordering::Less,
831             (_, &Slf(_)) => Ordering::Greater,
832             (&Super(_), _) => Ordering::Less,
833             (_, &Super(_)) => Ordering::Greater,
834             (&Crate(_), _) => Ordering::Less,
835             (_, &Crate(_)) => Ordering::Greater,
836             (&Ident(..), _) => Ordering::Less,
837             (_, &Ident(..)) => Ordering::Greater,
838             (&Glob, _) => Ordering::Less,
839             (_, &Glob) => Ordering::Greater,
840         }
841     }
842 }
843 impl Ord for UseTree {
844     fn cmp(&self, other: &UseTree) -> Ordering {
845         for (a, b) in self.path.iter().zip(other.path.iter()) {
846             let ord = a.cmp(b);
847             // The comparison without aliases is a hack to avoid situations like
848             // comparing `a::b` to `a as c` - where the latter should be ordered
849             // first since it is shorter.
850             if ord != Ordering::Equal && a.remove_alias().cmp(&b.remove_alias()) != Ordering::Equal
851             {
852                 return ord;
853             }
854         }
855
856         self.path.len().cmp(&other.path.len())
857     }
858 }
859
860 fn rewrite_nested_use_tree(
861     context: &RewriteContext<'_>,
862     use_tree_list: &[UseTree],
863     shape: Shape,
864 ) -> Option<String> {
865     let mut list_items = Vec::with_capacity(use_tree_list.len());
866     let nested_shape = match context.config.imports_indent() {
867         IndentStyle::Block => shape
868             .block_indent(context.config.tab_spaces())
869             .with_max_width(context.config)
870             .sub_width(1)?,
871         IndentStyle::Visual => shape.visual_indent(0),
872     };
873     for use_tree in use_tree_list {
874         if let Some(mut list_item) = use_tree.list_item.clone() {
875             list_item.item = use_tree.rewrite(context, nested_shape);
876             list_items.push(list_item);
877         } else {
878             list_items.push(ListItem::from_str(use_tree.rewrite(context, nested_shape)?));
879         }
880     }
881     let has_nested_list = use_tree_list.iter().any(|use_segment| {
882         use_segment.path.last().map_or(false, |last_segment| {
883             matches!(last_segment, UseSegment::List(..))
884         })
885     });
886
887     let remaining_width = if has_nested_list {
888         0
889     } else {
890         shape.width.saturating_sub(2)
891     };
892
893     let tactic = definitive_tactic(
894         &list_items,
895         context.config.imports_layout(),
896         Separator::Comma,
897         remaining_width,
898     );
899
900     let ends_with_newline = context.config.imports_indent() == IndentStyle::Block
901         && tactic != DefinitiveListTactic::Horizontal;
902     let trailing_separator = if ends_with_newline {
903         context.config.trailing_comma()
904     } else {
905         SeparatorTactic::Never
906     };
907     let fmt = ListFormatting::new(nested_shape, context.config)
908         .tactic(tactic)
909         .trailing_separator(trailing_separator)
910         .ends_with_newline(ends_with_newline)
911         .preserve_newline(true)
912         .nested(has_nested_list);
913
914     let list_str = write_list(&list_items, &fmt)?;
915
916     let result = if (list_str.contains('\n') || list_str.len() > remaining_width)
917         && context.config.imports_indent() == IndentStyle::Block
918     {
919         format!(
920             "{{\n{}{}\n{}}}",
921             nested_shape.indent.to_string(context.config),
922             list_str,
923             shape.indent.to_string(context.config)
924         )
925     } else {
926         format!("{{{}}}", list_str)
927     };
928
929     Some(result)
930 }
931
932 impl Rewrite for UseSegment {
933     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
934         Some(match self {
935             UseSegment::Ident(ref ident, Some(ref rename)) => format!("{} as {}", ident, rename),
936             UseSegment::Ident(ref ident, None) => ident.clone(),
937             UseSegment::Slf(Some(ref rename)) => format!("self as {}", rename),
938             UseSegment::Slf(None) => "self".to_owned(),
939             UseSegment::Super(Some(ref rename)) => format!("super as {}", rename),
940             UseSegment::Super(None) => "super".to_owned(),
941             UseSegment::Crate(Some(ref rename)) => format!("crate as {}", rename),
942             UseSegment::Crate(None) => "crate".to_owned(),
943             UseSegment::Glob => "*".to_owned(),
944             UseSegment::List(ref use_tree_list) => rewrite_nested_use_tree(
945                 context,
946                 use_tree_list,
947                 // 1 = "{" and "}"
948                 shape.offset_left(1)?.sub_width(1)?,
949             )?,
950         })
951     }
952 }
953
954 impl Rewrite for UseTree {
955     // This does NOT format attributes and visibility or add a trailing `;`.
956     fn rewrite(&self, context: &RewriteContext<'_>, mut shape: Shape) -> Option<String> {
957         let mut result = String::with_capacity(256);
958         let mut iter = self.path.iter().peekable();
959         while let Some(segment) = iter.next() {
960             let segment_str = segment.rewrite(context, shape)?;
961             result.push_str(&segment_str);
962             if iter.peek().is_some() {
963                 result.push_str("::");
964                 // 2 = "::"
965                 shape = shape.offset_left(2 + segment_str.len())?;
966             }
967         }
968         Some(result)
969     }
970 }
971
972 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
973 enum SharedPrefix {
974     Crate,
975     Module,
976     One,
977 }
978
979 #[cfg(test)]
980 mod test {
981     use super::*;
982     use rustc_span::DUMMY_SP;
983
984     // Parse the path part of an import. This parser is not robust and is only
985     // suitable for use in a test harness.
986     fn parse_use_tree(s: &str) -> UseTree {
987         use std::iter::Peekable;
988         use std::mem::swap;
989         use std::str::Chars;
990
991         struct Parser<'a> {
992             input: Peekable<Chars<'a>>,
993         }
994
995         impl<'a> Parser<'a> {
996             fn bump(&mut self) {
997                 self.input.next().unwrap();
998             }
999
1000             fn eat(&mut self, c: char) {
1001                 assert_eq!(self.input.next().unwrap(), c);
1002             }
1003
1004             fn push_segment(
1005                 result: &mut Vec<UseSegment>,
1006                 buf: &mut String,
1007                 alias_buf: &mut Option<String>,
1008             ) {
1009                 if !buf.is_empty() {
1010                     let mut alias = None;
1011                     swap(alias_buf, &mut alias);
1012
1013                     match buf.as_ref() {
1014                         "self" => {
1015                             result.push(UseSegment::Slf(alias));
1016                             *buf = String::new();
1017                             *alias_buf = None;
1018                         }
1019                         "super" => {
1020                             result.push(UseSegment::Super(alias));
1021                             *buf = String::new();
1022                             *alias_buf = None;
1023                         }
1024                         "crate" => {
1025                             result.push(UseSegment::Crate(alias));
1026                             *buf = String::new();
1027                             *alias_buf = None;
1028                         }
1029                         _ => {
1030                             let mut name = String::new();
1031                             swap(buf, &mut name);
1032                             result.push(UseSegment::Ident(name, alias));
1033                         }
1034                     }
1035                 }
1036             }
1037
1038             fn parse_in_list(&mut self) -> UseTree {
1039                 let mut result = vec![];
1040                 let mut buf = String::new();
1041                 let mut alias_buf = None;
1042                 while let Some(&c) = self.input.peek() {
1043                     match c {
1044                         '{' => {
1045                             assert!(buf.is_empty());
1046                             self.bump();
1047                             result.push(UseSegment::List(self.parse_list()));
1048                             self.eat('}');
1049                         }
1050                         '*' => {
1051                             assert!(buf.is_empty());
1052                             self.bump();
1053                             result.push(UseSegment::Glob);
1054                         }
1055                         ':' => {
1056                             self.bump();
1057                             self.eat(':');
1058                             Self::push_segment(&mut result, &mut buf, &mut alias_buf);
1059                         }
1060                         '}' | ',' => {
1061                             Self::push_segment(&mut result, &mut buf, &mut alias_buf);
1062                             return UseTree {
1063                                 path: result,
1064                                 span: DUMMY_SP,
1065                                 list_item: None,
1066                                 visibility: None,
1067                                 attrs: None,
1068                             };
1069                         }
1070                         ' ' => {
1071                             self.bump();
1072                             self.eat('a');
1073                             self.eat('s');
1074                             self.eat(' ');
1075                             alias_buf = Some(String::new());
1076                         }
1077                         c => {
1078                             self.bump();
1079                             if let Some(ref mut buf) = alias_buf {
1080                                 buf.push(c);
1081                             } else {
1082                                 buf.push(c);
1083                             }
1084                         }
1085                     }
1086                 }
1087                 Self::push_segment(&mut result, &mut buf, &mut alias_buf);
1088                 UseTree {
1089                     path: result,
1090                     span: DUMMY_SP,
1091                     list_item: None,
1092                     visibility: None,
1093                     attrs: None,
1094                 }
1095             }
1096
1097             fn parse_list(&mut self) -> Vec<UseTree> {
1098                 let mut result = vec![];
1099                 loop {
1100                     match self.input.peek().unwrap() {
1101                         ',' | ' ' => self.bump(),
1102                         '}' => {
1103                             return result;
1104                         }
1105                         _ => result.push(self.parse_in_list()),
1106                     }
1107                 }
1108             }
1109         }
1110
1111         let mut parser = Parser {
1112             input: s.chars().peekable(),
1113         };
1114         parser.parse_in_list()
1115     }
1116
1117     macro_rules! parse_use_trees {
1118         ($($s:expr),* $(,)*) => {
1119             vec![
1120                 $(parse_use_tree($s),)*
1121             ]
1122         }
1123     }
1124
1125     macro_rules! test_merge {
1126         ($by:ident, [$($input:expr),* $(,)*], [$($output:expr),* $(,)*]) => {
1127             assert_eq!(
1128                 normalize_use_trees_with_granularity(
1129                     parse_use_trees!($($input,)*),
1130                     ImportGranularity::$by,
1131                 ),
1132                 parse_use_trees!($($output,)*),
1133             );
1134         }
1135     }
1136
1137     #[test]
1138     fn test_use_tree_merge_crate() {
1139         test_merge!(
1140             Crate,
1141             ["a::b::{c, d}", "a::b::{e, f}"],
1142             ["a::b::{c, d, e, f}"]
1143         );
1144         test_merge!(Crate, ["a::b::c", "a::b"], ["a::{b, b::c}"]);
1145         test_merge!(Crate, ["a::b", "a::b"], ["a::b"]);
1146         test_merge!(Crate, ["a", "a::b", "a::b::c"], ["a::{self, b, b::c}"]);
1147         test_merge!(
1148             Crate,
1149             ["a", "a::b", "a::b::c", "a::b::c::d"],
1150             ["a::{self, b, b::{c, c::d}}"]
1151         );
1152         test_merge!(
1153             Crate,
1154             ["a", "a::b", "a::b::c", "a::b"],
1155             ["a::{self, b, b::c}"]
1156         );
1157         test_merge!(
1158             Crate,
1159             ["a::{b::{self, c}, d::e}", "a::d::f"],
1160             ["a::{b::{self, c}, d::{e, f}}"]
1161         );
1162         test_merge!(
1163             Crate,
1164             ["a::d::f", "a::{b::{self, c}, d::e}"],
1165             ["a::{b::{self, c}, d::{e, f}}"]
1166         );
1167         test_merge!(
1168             Crate,
1169             ["a::{c, d, b}", "a::{d, e, b, a, f}", "a::{f, g, c}"],
1170             ["a::{a, b, c, d, e, f, g}"]
1171         );
1172         test_merge!(
1173             Crate,
1174             ["a::{self}", "b::{self as foo}"],
1175             ["a::{self}", "b::{self as foo}"]
1176         );
1177     }
1178
1179     #[test]
1180     fn test_use_tree_merge_module() {
1181         test_merge!(
1182             Module,
1183             ["foo::b", "foo::{a, c, d::e}"],
1184             ["foo::{a, b, c}", "foo::d::e"]
1185         );
1186
1187         test_merge!(
1188             Module,
1189             ["foo::{a::b, a::c, d::e, d::f}"],
1190             ["foo::a::{b, c}", "foo::d::{e, f}"]
1191         );
1192     }
1193
1194     #[test]
1195     fn test_use_tree_merge_one() {
1196         test_merge!(One, ["a", "b"], ["{a, b}"]);
1197
1198         test_merge!(One, ["a::{aa, ab}", "b", "a"], ["{a::{self, aa, ab}, b}"]);
1199
1200         test_merge!(One, ["a as x", "b as y"], ["{a as x, b as y}"]);
1201
1202         test_merge!(
1203             One,
1204             ["a::{aa as xa, ab}", "b", "a"],
1205             ["{a::{self, aa as xa, ab}, b}"]
1206         );
1207
1208         test_merge!(
1209             One,
1210             ["a", "a::{aa, ab::{aba, abb}}"],
1211             ["a::{self, aa, ab::{aba, abb}}"]
1212         );
1213
1214         test_merge!(One, ["a", "b::{ba, *}"], ["{a, b::{ba, *}}"]);
1215
1216         test_merge!(One, ["a", "b", "a::aa"], ["{a::{self, aa}, b}"]);
1217
1218         test_merge!(
1219             One,
1220             ["a::aa::aaa", "a::ac::aca", "a::aa::*"],
1221             ["a::{aa::{aaa, *}, ac::aca}"]
1222         );
1223
1224         test_merge!(
1225             One,
1226             ["a", "b::{ba, bb}", "a::{aa::*, ab::aba}"],
1227             ["{a::{self, aa::*, ab::aba}, b::{ba, bb}}"]
1228         );
1229
1230         test_merge!(
1231             One,
1232             ["b", "a::ac::{aca, acb}", "a::{aa::*, ab}"],
1233             ["{a::{aa::*, ab, ac::{aca, acb}}, b}"]
1234         );
1235     }
1236
1237     #[test]
1238     fn test_flatten_use_trees() {
1239         assert_eq!(
1240             flatten_use_trees(
1241                 parse_use_trees!["foo::{a::{b, c}, d::e}"],
1242                 ImportGranularity::Item
1243             ),
1244             parse_use_trees!["foo::a::b", "foo::a::c", "foo::d::e"]
1245         );
1246
1247         assert_eq!(
1248             flatten_use_trees(
1249                 parse_use_trees!["foo::{self, a, b::{c, d}, e::*}"],
1250                 ImportGranularity::Item
1251             ),
1252             parse_use_trees![
1253                 "foo::{self}",
1254                 "foo::a",
1255                 "foo::b::c",
1256                 "foo::b::d",
1257                 "foo::e::*"
1258             ]
1259         );
1260     }
1261
1262     #[test]
1263     fn test_use_tree_flatten() {
1264         assert_eq!(
1265             parse_use_tree("a::b::{c, d, e, f}").flatten(ImportGranularity::Item),
1266             parse_use_trees!("a::b::c", "a::b::d", "a::b::e", "a::b::f",)
1267         );
1268
1269         assert_eq!(
1270             parse_use_tree("a::b::{c::{d, e, f}, g, h::{i, j, k}}")
1271                 .flatten(ImportGranularity::Item),
1272             parse_use_trees![
1273                 "a::b::c::d",
1274                 "a::b::c::e",
1275                 "a::b::c::f",
1276                 "a::b::g",
1277                 "a::b::h::i",
1278                 "a::b::h::j",
1279                 "a::b::h::k",
1280             ]
1281         );
1282     }
1283
1284     #[test]
1285     fn test_use_tree_normalize() {
1286         assert_eq!(parse_use_tree("a::self").normalize(), parse_use_tree("a"));
1287         assert_eq!(
1288             parse_use_tree("a::self as foo").normalize(),
1289             parse_use_tree("a as foo")
1290         );
1291         assert_eq!(
1292             parse_use_tree("a::{self}").normalize(),
1293             parse_use_tree("a::{self}")
1294         );
1295         assert_eq!(parse_use_tree("a::{b}").normalize(), parse_use_tree("a::b"));
1296         assert_eq!(
1297             parse_use_tree("a::{b, c::self}").normalize(),
1298             parse_use_tree("a::{b, c}")
1299         );
1300         assert_eq!(
1301             parse_use_tree("a::{b as bar, c::self}").normalize(),
1302             parse_use_tree("a::{b as bar, c}")
1303         );
1304     }
1305
1306     #[test]
1307     fn test_use_tree_ord() {
1308         assert!(parse_use_tree("a").normalize() < parse_use_tree("aa").normalize());
1309         assert!(parse_use_tree("a").normalize() < parse_use_tree("a::a").normalize());
1310         assert!(parse_use_tree("a").normalize() < parse_use_tree("*").normalize());
1311         assert!(parse_use_tree("a").normalize() < parse_use_tree("{a, b}").normalize());
1312         assert!(parse_use_tree("*").normalize() < parse_use_tree("{a, b}").normalize());
1313
1314         assert!(
1315             parse_use_tree("aaaaaaaaaaaaaaa::{bb, cc, dddddddd}").normalize()
1316                 < parse_use_tree("aaaaaaaaaaaaaaa::{bb, cc, ddddddddd}").normalize()
1317         );
1318         assert!(
1319             parse_use_tree("serde::de::{Deserialize}").normalize()
1320                 < parse_use_tree("serde_json").normalize()
1321         );
1322         assert!(parse_use_tree("a::b::c").normalize() < parse_use_tree("a::b::*").normalize());
1323         assert!(
1324             parse_use_tree("foo::{Bar, Baz}").normalize()
1325                 < parse_use_tree("{Bar, Baz}").normalize()
1326         );
1327
1328         assert!(
1329             parse_use_tree("foo::{qux as bar}").normalize()
1330                 < parse_use_tree("foo::{self as bar}").normalize()
1331         );
1332         assert!(
1333             parse_use_tree("foo::{qux as bar}").normalize()
1334                 < parse_use_tree("foo::{baz, qux as bar}").normalize()
1335         );
1336         assert!(
1337             parse_use_tree("foo::{self as bar, baz}").normalize()
1338                 < parse_use_tree("foo::{baz, qux as bar}").normalize()
1339         );
1340
1341         assert!(parse_use_tree("foo").normalize() < parse_use_tree("Foo").normalize());
1342         assert!(parse_use_tree("foo").normalize() < parse_use_tree("foo::Bar").normalize());
1343
1344         assert!(
1345             parse_use_tree("std::cmp::{d, c, b, a}").normalize()
1346                 < parse_use_tree("std::cmp::{b, e, g, f}").normalize()
1347         );
1348     }
1349
1350     #[test]
1351     fn test_use_tree_nest_trailing_self() {
1352         assert_eq!(
1353             parse_use_tree("a::b::self").nest_trailing_self(),
1354             parse_use_tree("a::b::{self}")
1355         );
1356         assert_eq!(
1357             parse_use_tree("a::b::c").nest_trailing_self(),
1358             parse_use_tree("a::b::c")
1359         );
1360         assert_eq!(
1361             parse_use_tree("a::b::{c, d}").nest_trailing_self(),
1362             parse_use_tree("a::b::{c, d}")
1363         );
1364         assert_eq!(
1365             parse_use_tree("a::b::{self, c}").nest_trailing_self(),
1366             parse_use_tree("a::b::{self, c}")
1367         );
1368     }
1369 }