]> git.lizzy.rs Git - rust.git/blob - src/imports.rs
Simplify UseTree::has_comment
[rust.git] / src / imports.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use std::cmp::Ordering;
12
13 use config::lists::*;
14 use syntax::ast::{self, UseTreeKind};
15 use syntax::codemap::{self, BytePos, Span, DUMMY_SP};
16
17 use codemap::SpanUtils;
18 use config::IndentStyle;
19 use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator};
20 use rewrite::{Rewrite, RewriteContext};
21 use shape::Shape;
22 use spanned::Spanned;
23 use utils::mk_sp;
24 use visitor::FmtVisitor;
25
26 use std::borrow::Cow;
27 use std::fmt;
28
29 /// Returns a name imported by a `use` declaration. e.g. returns `Ordering`
30 /// for `std::cmp::Ordering` and `self` for `std::cmp::self`.
31 pub fn path_to_imported_ident(path: &ast::Path) -> ast::Ident {
32     path.segments.last().unwrap().ident
33 }
34
35 impl<'a> FmtVisitor<'a> {
36     pub fn format_import(&mut self, item: &ast::Item, tree: &ast::UseTree) {
37         let span = item.span;
38         let shape = self.shape();
39         let rw = UseTree::from_ast(
40             &self.get_context(),
41             tree,
42             None,
43             Some(item.vis.clone()),
44             Some(item.span.lo()),
45             Some(item.attrs.clone()),
46         ).rewrite_top_level(&self.get_context(), shape);
47         match rw {
48             Some(ref s) if s.is_empty() => {
49                 // Format up to last newline
50                 let prev_span = mk_sp(self.last_pos, source!(self, span).lo());
51                 let trimmed_snippet = self.snippet(prev_span).trim_right();
52                 let span_end = self.last_pos + BytePos(trimmed_snippet.len() as u32);
53                 self.format_missing(span_end);
54                 // We have an excessive newline from the removed import.
55                 if self.buffer.ends_with('\n') {
56                     self.buffer.pop();
57                     self.line_number -= 1;
58                 }
59                 self.last_pos = source!(self, span).hi();
60             }
61             Some(ref s) => {
62                 self.format_missing_with_indent(source!(self, span).lo());
63                 self.push_str(s);
64                 self.last_pos = source!(self, span).hi();
65             }
66             None => {
67                 self.format_missing_with_indent(source!(self, span).lo());
68                 self.format_missing(source!(self, span).hi());
69             }
70         }
71     }
72 }
73
74 // Ordering of imports
75
76 // We order imports by translating to our own representation and then sorting.
77 // The Rust AST data structures are really bad for this. Rustfmt applies a bunch
78 // of normalisations to imports and since we want to sort based on the result
79 // of these (and to maintain idempotence) we must apply the same normalisations
80 // to the data structures for sorting.
81 //
82 // We sort `self` and `super` before other imports, then identifier imports,
83 // then glob imports, then lists of imports. We do not take aliases into account
84 // when ordering unless the imports are identical except for the alias (rare in
85 // practice).
86
87 // FIXME(#2531) - we should unify the comparison code here with the formatting
88 // code elsewhere since we are essentially string-ifying twice. Furthermore, by
89 // parsing to our own format on comparison, we repeat a lot of work when
90 // sorting.
91
92 // FIXME we do a lot of allocation to make our own representation.
93 #[derive(Clone, Eq, PartialEq)]
94 pub enum UseSegment {
95     Ident(String, Option<String>),
96     Slf(Option<String>),
97     Super(Option<String>),
98     Glob,
99     List(Vec<UseTree>),
100 }
101
102 #[derive(Clone)]
103 pub struct UseTree {
104     pub path: Vec<UseSegment>,
105     pub span: Span,
106     // Comment information within nested use tree.
107     pub list_item: Option<ListItem>,
108     // Additional fields for top level use items.
109     // Should we have another struct for top-level use items rather than reusing this?
110     visibility: Option<ast::Visibility>,
111     attrs: Option<Vec<ast::Attribute>>,
112 }
113
114 impl PartialEq for UseTree {
115     fn eq(&self, other: &UseTree) -> bool {
116         self.path == other.path
117     }
118 }
119 impl Eq for UseTree {}
120
121 impl UseSegment {
122     // Clone a version of self with any top-level alias removed.
123     fn remove_alias(&self) -> UseSegment {
124         match *self {
125             UseSegment::Ident(ref s, _) => UseSegment::Ident(s.clone(), None),
126             UseSegment::Slf(_) => UseSegment::Slf(None),
127             UseSegment::Super(_) => UseSegment::Super(None),
128             _ => self.clone(),
129         }
130     }
131
132     fn from_path_segment(path_seg: &ast::PathSegment) -> Option<UseSegment> {
133         let name = path_seg.ident.name.as_str();
134         if name == "{{root}}" {
135             return None;
136         }
137         Some(if name == "self" {
138             UseSegment::Slf(None)
139         } else if name == "super" {
140             UseSegment::Super(None)
141         } else {
142             UseSegment::Ident((*name).to_owned(), None)
143         })
144     }
145 }
146
147 pub fn merge_use_trees(use_trees: Vec<UseTree>) -> Vec<UseTree> {
148     let mut result = Vec::with_capacity(use_trees.len());
149     for use_tree in use_trees {
150         if use_tree.has_comment() || use_tree.attrs.is_some() {
151             result.push(use_tree);
152             continue;
153         }
154
155         for flattened in use_tree.flatten() {
156             merge_use_trees_inner(&mut result, flattened);
157         }
158     }
159     result
160 }
161
162 fn merge_use_trees_inner(trees: &mut Vec<UseTree>, use_tree: UseTree) {
163     for tree in trees.iter_mut() {
164         if tree.share_prefix(&use_tree) {
165             tree.merge(use_tree);
166             return;
167         }
168     }
169
170     trees.push(use_tree);
171 }
172
173 impl fmt::Debug for UseTree {
174     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
175         write!(f, "{}", self)
176     }
177 }
178
179 impl fmt::Debug for UseSegment {
180     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
181         write!(f, "{}", self)
182     }
183 }
184
185 impl fmt::Display for UseSegment {
186     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
187         match *self {
188             UseSegment::Glob => write!(f, "*"),
189             UseSegment::Ident(ref s, _) => write!(f, "{}", s),
190             UseSegment::Slf(..) => write!(f, "self"),
191             UseSegment::Super(..) => write!(f, "super"),
192             UseSegment::List(ref list) => {
193                 write!(f, "{{")?;
194                 for (i, item) in list.iter().enumerate() {
195                     let is_last = i == list.len() - 1;
196                     write!(f, "{}", item)?;
197                     if !is_last {
198                         write!(f, ", ")?;
199                     }
200                 }
201                 write!(f, "}}")
202             }
203         }
204     }
205 }
206 impl fmt::Display for UseTree {
207     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
208         for (i, segment) in self.path.iter().enumerate() {
209             let is_last = i == self.path.len() - 1;
210             write!(f, "{}", segment)?;
211             if !is_last {
212                 write!(f, "::")?;
213             }
214         }
215         write!(f, "")
216     }
217 }
218
219 impl UseTree {
220     // Rewrite use tree with `use ` and a trailing `;`.
221     pub fn rewrite_top_level(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
222         let mut result = String::with_capacity(256);
223         if let Some(ref attrs) = self.attrs {
224             result.push_str(&attrs.rewrite(context, shape).expect("rewrite attr"));
225             if !result.is_empty() {
226                 result.push_str(&shape.indent.to_string_with_newline(context.config));
227             }
228         }
229
230         let vis = self.visibility
231             .as_ref()
232             .map_or(Cow::from(""), |vis| ::utils::format_visibility(&vis));
233         result.push_str(&self.rewrite(context, shape.offset_left(vis.len())?)
234             .map(|s| {
235                 if s.is_empty() {
236                     s.to_owned()
237                 } else {
238                     format!("{}use {};", vis, s)
239                 }
240             })?);
241         Some(result)
242     }
243
244     // FIXME: Use correct span?
245     fn from_path(path: Vec<UseSegment>, span: Span) -> UseTree {
246         UseTree {
247             path,
248             span,
249             list_item: None,
250             visibility: None,
251             attrs: None,
252         }
253     }
254
255     pub fn from_ast_with_normalization(
256         context: &RewriteContext,
257         item: &ast::Item,
258     ) -> Option<UseTree> {
259         match item.node {
260             ast::ItemKind::Use(ref use_tree) => Some(
261                 UseTree::from_ast(
262                     context,
263                     use_tree,
264                     None,
265                     Some(item.vis.clone()),
266                     Some(item.span().lo()),
267                     if item.attrs.is_empty() {
268                         None
269                     } else {
270                         Some(item.attrs.clone())
271                     },
272                 ).normalize(context.config.reorder_imported_names()),
273             ),
274             _ => None,
275         }
276     }
277
278     fn from_ast(
279         context: &RewriteContext,
280         a: &ast::UseTree,
281         list_item: Option<ListItem>,
282         visibility: Option<ast::Visibility>,
283         opt_lo: Option<BytePos>,
284         attrs: Option<Vec<ast::Attribute>>,
285     ) -> UseTree {
286         let span = if let Some(lo) = opt_lo {
287             mk_sp(lo, a.span.hi())
288         } else {
289             a.span
290         };
291         let mut result = UseTree {
292             path: vec![],
293             span,
294             list_item,
295             visibility,
296             attrs,
297         };
298         for p in &a.prefix.segments {
299             if let Some(use_segment) = UseSegment::from_path_segment(p) {
300                 result.path.push(use_segment);
301             }
302         }
303         match a.kind {
304             UseTreeKind::Glob => {
305                 result.path.push(UseSegment::Glob);
306             }
307             UseTreeKind::Nested(ref list) => {
308                 // Extract comments between nested use items.
309                 // This needs to be done before sorting use items.
310                 let items: Vec<_> = itemize_list(
311                     context.snippet_provider,
312                     list.iter().map(|(tree, _)| tree),
313                     "}",
314                     ",",
315                     |tree| tree.span.lo(),
316                     |tree| tree.span.hi(),
317                     |_| Some("".to_owned()), // We only need comments for now.
318                     context.snippet_provider.span_after(a.span, "{"),
319                     a.span.hi(),
320                     false,
321                 ).collect();
322                 result.path.push(UseSegment::List(
323                     list.iter()
324                         .zip(items.into_iter())
325                         .map(|(t, list_item)| {
326                             Self::from_ast(context, &t.0, Some(list_item), None, None, None)
327                         })
328                         .collect(),
329                 ));
330             }
331             UseTreeKind::Simple(ref rename) => {
332                 let mut name = (*path_to_imported_ident(&a.prefix).name.as_str()).to_owned();
333                 let alias = rename.and_then(|ident| {
334                     if ident == path_to_imported_ident(&a.prefix) {
335                         None
336                     } else {
337                         Some(ident.to_string())
338                     }
339                 });
340
341                 let segment = if &name == "self" {
342                     UseSegment::Slf(alias)
343                 } else if &name == "super" {
344                     UseSegment::Super(alias)
345                 } else {
346                     UseSegment::Ident(name, alias)
347                 };
348
349                 // `name` is already in result.
350                 result.path.pop();
351                 result.path.push(segment);
352             }
353         }
354         result
355     }
356
357     // Do the adjustments that rustfmt does elsewhere to use paths.
358     pub fn normalize(mut self, do_sort: bool) -> UseTree {
359         let mut last = self.path.pop().expect("Empty use tree?");
360         // Hack around borrow checker.
361         let mut normalize_sole_list = false;
362         let mut aliased_self = false;
363
364         // Remove foo::{} or self without attributes.
365         match last {
366             _ if self.attrs.is_some() => (),
367             UseSegment::List(ref list) if list.is_empty() => {
368                 self.path = vec![];
369                 return self;
370             }
371             UseSegment::Slf(None) if self.path.is_empty() && self.visibility.is_some() => {
372                 self.path = vec![];
373                 return self;
374             }
375             _ => (),
376         }
377
378         // Normalise foo::self -> foo.
379         if let UseSegment::Slf(None) = last {
380             if self.path.len() > 0 {
381                 return self;
382             }
383         }
384
385         // Normalise foo::self as bar -> foo as bar.
386         if let UseSegment::Slf(_) = last {
387             match self.path.last() {
388                 None => {}
389                 Some(UseSegment::Ident(_, None)) => {
390                     aliased_self = true;
391                 }
392                 _ => unreachable!(),
393             }
394         }
395
396         let mut done = false;
397         if aliased_self {
398             match self.path.last_mut() {
399                 Some(UseSegment::Ident(_, ref mut old_rename)) => {
400                     assert!(old_rename.is_none());
401                     if let UseSegment::Slf(Some(rename)) = last.clone() {
402                         *old_rename = Some(rename);
403                         done = true;
404                     }
405                 }
406                 _ => unreachable!(),
407             }
408         }
409
410         if done {
411             return self;
412         }
413
414         // Normalise foo::{bar} -> foo::bar
415         if let UseSegment::List(ref list) = last {
416             if list.len() == 1 {
417                 normalize_sole_list = true;
418             }
419         }
420
421         if normalize_sole_list {
422             match last {
423                 UseSegment::List(list) => {
424                     for seg in &list[0].path {
425                         self.path.push(seg.clone());
426                     }
427                     return self.normalize(do_sort);
428                 }
429                 _ => unreachable!(),
430             }
431         }
432
433         // Recursively normalize elements of a list use (including sorting the list).
434         if let UseSegment::List(list) = last {
435             let mut list = list.into_iter()
436                 .map(|ut| ut.normalize(do_sort))
437                 .collect::<Vec<_>>();
438             if do_sort {
439                 list.sort();
440             }
441             last = UseSegment::List(list);
442         }
443
444         self.path.push(last);
445         self
446     }
447
448     fn has_comment(&self) -> bool {
449         self.list_item.as_ref().map_or(false, ListItem::has_comment)
450     }
451
452     fn same_visibility(&self, other: &UseTree) -> bool {
453         match (&self.visibility, &other.visibility) {
454             (
455                 Some(codemap::Spanned {
456                     node: ast::VisibilityKind::Inherited,
457                     ..
458                 }),
459                 None,
460             )
461             | (
462                 None,
463                 Some(codemap::Spanned {
464                     node: ast::VisibilityKind::Inherited,
465                     ..
466                 }),
467             )
468             | (None, None) => true,
469             (
470                 Some(codemap::Spanned { node: lnode, .. }),
471                 Some(codemap::Spanned { node: rnode, .. }),
472             ) => lnode == rnode,
473             _ => false,
474         }
475     }
476
477     fn share_prefix(&self, other: &UseTree) -> bool {
478         if self.path.is_empty() || other.path.is_empty() || self.attrs.is_some()
479             || !self.same_visibility(other)
480         {
481             false
482         } else {
483             self.path[0] == other.path[0]
484         }
485     }
486
487     fn flatten(self) -> Vec<UseTree> {
488         if self.path.is_empty() {
489             return vec![self];
490         }
491         match self.path.clone().last().unwrap() {
492             UseSegment::List(list) => {
493                 let prefix = &self.path[..self.path.len() - 1];
494                 let mut result = vec![];
495                 for nested_use_tree in list.into_iter() {
496                     for mut flattend in nested_use_tree.clone().flatten().iter_mut() {
497                         let mut new_path = prefix.to_vec();
498                         new_path.append(&mut flattend.path);
499                         result.push(UseTree {
500                             path: new_path,
501                             span: self.span,
502                             list_item: None,
503                             visibility: self.visibility.clone(),
504                             attrs: None,
505                         });
506                     }
507                 }
508
509                 result
510             }
511             _ => vec![self],
512         }
513     }
514
515     fn merge(&mut self, other: UseTree) {
516         let mut new_path = vec![];
517         let mut len = 0;
518         for (i, (mut a, b)) in self.path
519             .clone()
520             .iter_mut()
521             .zip(other.path.clone().into_iter())
522             .enumerate()
523         {
524             if *a == b {
525                 len = i + 1;
526                 new_path.push(b);
527             } else {
528                 len = i;
529                 break;
530             }
531         }
532         if let Some(merged) = merge_rest(&self.path, &other.path, len) {
533             new_path.push(merged);
534             self.span = self.span.to(other.span);
535         }
536         self.path = new_path;
537     }
538 }
539
540 fn merge_rest(a: &[UseSegment], b: &[UseSegment], len: usize) -> Option<UseSegment> {
541     let a_rest = &a[len..];
542     let b_rest = &b[len..];
543     if a_rest.is_empty() && b_rest.is_empty() {
544         return None;
545     }
546     if a_rest.is_empty() {
547         return Some(UseSegment::List(vec![
548             UseTree::from_path(vec![UseSegment::Slf(None)], DUMMY_SP),
549             UseTree::from_path(b_rest.to_vec(), DUMMY_SP),
550         ]));
551     }
552     if b_rest.is_empty() {
553         return Some(UseSegment::List(vec![
554             UseTree::from_path(vec![UseSegment::Slf(None)], DUMMY_SP),
555             UseTree::from_path(a_rest.to_vec(), DUMMY_SP),
556         ]));
557     }
558     if let UseSegment::List(mut list) = a_rest[0].clone() {
559         merge_use_trees_inner(&mut list, UseTree::from_path(b_rest.to_vec(), DUMMY_SP));
560         list.sort();
561         return Some(UseSegment::List(list.clone()));
562     }
563     let mut list = vec![
564         UseTree::from_path(a_rest.to_vec(), DUMMY_SP),
565         UseTree::from_path(b_rest.to_vec(), DUMMY_SP),
566     ];
567     list.sort();
568     Some(UseSegment::List(list))
569 }
570
571 impl PartialOrd for UseSegment {
572     fn partial_cmp(&self, other: &UseSegment) -> Option<Ordering> {
573         Some(self.cmp(other))
574     }
575 }
576 impl PartialOrd for UseTree {
577     fn partial_cmp(&self, other: &UseTree) -> Option<Ordering> {
578         Some(self.cmp(other))
579     }
580 }
581 impl Ord for UseSegment {
582     fn cmp(&self, other: &UseSegment) -> Ordering {
583         use self::UseSegment::*;
584
585         fn is_upper_snake_case(s: &str) -> bool {
586             s.chars().all(|c| c.is_uppercase() || c == '_')
587         }
588
589         match (self, other) {
590             (&Slf(ref a), &Slf(ref b)) | (&Super(ref a), &Super(ref b)) => a.cmp(b),
591             (&Glob, &Glob) => Ordering::Equal,
592             (&Ident(ref ia, ref aa), &Ident(ref ib, ref ab)) => {
593                 // snake_case < CamelCase < UPPER_SNAKE_CASE
594                 if ia.starts_with(char::is_uppercase) && ib.starts_with(char::is_lowercase) {
595                     return Ordering::Greater;
596                 }
597                 if ia.starts_with(char::is_lowercase) && ib.starts_with(char::is_uppercase) {
598                     return Ordering::Less;
599                 }
600                 if is_upper_snake_case(ia) && !is_upper_snake_case(ib) {
601                     return Ordering::Greater;
602                 }
603                 if !is_upper_snake_case(ia) && is_upper_snake_case(ib) {
604                     return Ordering::Less;
605                 }
606                 let ident_ord = ia.cmp(ib);
607                 if ident_ord != Ordering::Equal {
608                     return ident_ord;
609                 }
610                 if aa.is_none() && ab.is_some() {
611                     return Ordering::Less;
612                 }
613                 if aa.is_some() && ab.is_none() {
614                     return Ordering::Greater;
615                 }
616                 aa.cmp(ab)
617             }
618             (&List(ref a), &List(ref b)) => {
619                 for (a, b) in a.iter().zip(b.iter()) {
620                     let ord = a.cmp(b);
621                     if ord != Ordering::Equal {
622                         return ord;
623                     }
624                 }
625
626                 a.len().cmp(&b.len())
627             }
628             (&Slf(_), _) => Ordering::Less,
629             (_, &Slf(_)) => Ordering::Greater,
630             (&Super(_), _) => Ordering::Less,
631             (_, &Super(_)) => Ordering::Greater,
632             (&Ident(..), _) => Ordering::Less,
633             (_, &Ident(..)) => Ordering::Greater,
634             (&Glob, _) => Ordering::Less,
635             (_, &Glob) => Ordering::Greater,
636         }
637     }
638 }
639 impl Ord for UseTree {
640     fn cmp(&self, other: &UseTree) -> Ordering {
641         for (a, b) in self.path.iter().zip(other.path.iter()) {
642             let ord = a.cmp(b);
643             // The comparison without aliases is a hack to avoid situations like
644             // comparing `a::b` to `a as c` - where the latter should be ordered
645             // first since it is shorter.
646             if ord != Ordering::Equal && a.remove_alias().cmp(&b.remove_alias()) != Ordering::Equal
647             {
648                 return ord;
649             }
650         }
651
652         self.path.len().cmp(&other.path.len())
653     }
654 }
655
656 fn rewrite_nested_use_tree(
657     context: &RewriteContext,
658     use_tree_list: &[UseTree],
659     shape: Shape,
660 ) -> Option<String> {
661     let mut list_items = Vec::with_capacity(use_tree_list.len());
662     let nested_shape = match context.config.imports_indent() {
663         IndentStyle::Block => shape
664             .block_indent(context.config.tab_spaces())
665             .with_max_width(context.config)
666             .sub_width(1)?,
667         IndentStyle::Visual => shape.visual_indent(0),
668     };
669     for use_tree in use_tree_list {
670         if let Some(mut list_item) = use_tree.list_item.clone() {
671             list_item.item = use_tree.rewrite(context, nested_shape);
672             list_items.push(list_item);
673         } else {
674             list_items.push(ListItem::from_str(use_tree.rewrite(context, nested_shape)?));
675         }
676     }
677     let (tactic, remaining_width) = if use_tree_list.iter().any(|use_segment| {
678         use_segment
679             .path
680             .last()
681             .map_or(false, |last_segment| match last_segment {
682                 UseSegment::List(..) => true,
683                 _ => false,
684             })
685     }) {
686         (DefinitiveListTactic::Vertical, 0)
687     } else {
688         let remaining_width = shape.width.checked_sub(2).unwrap_or(0);
689         let tactic = definitive_tactic(
690             &list_items,
691             context.config.imports_layout(),
692             Separator::Comma,
693             remaining_width,
694         );
695         (tactic, remaining_width)
696     };
697     let ends_with_newline = context.config.imports_indent() == IndentStyle::Block
698         && tactic != DefinitiveListTactic::Horizontal;
699     let fmt = ListFormatting {
700         tactic,
701         separator: ",",
702         trailing_separator: if ends_with_newline {
703             context.config.trailing_comma()
704         } else {
705             SeparatorTactic::Never
706         },
707         separator_place: SeparatorPlace::Back,
708         shape: nested_shape,
709         ends_with_newline,
710         preserve_newline: true,
711         config: context.config,
712     };
713
714     let list_str = write_list(&list_items, &fmt)?;
715
716     let result = if (list_str.contains('\n') || list_str.len() > remaining_width)
717         && context.config.imports_indent() == IndentStyle::Block
718     {
719         format!(
720             "{{\n{}{}\n{}}}",
721             nested_shape.indent.to_string(context.config),
722             list_str,
723             shape.indent.to_string(context.config)
724         )
725     } else {
726         format!("{{{}}}", list_str)
727     };
728
729     Some(result)
730 }
731
732 impl Rewrite for UseSegment {
733     fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
734         Some(match *self {
735             UseSegment::Ident(ref ident, Some(ref rename)) => format!("{} as {}", ident, rename),
736             UseSegment::Ident(ref ident, None) => ident.clone(),
737             UseSegment::Slf(Some(ref rename)) => format!("self as {}", rename),
738             UseSegment::Slf(None) => "self".to_owned(),
739             UseSegment::Super(Some(ref rename)) => format!("super as {}", rename),
740             UseSegment::Super(None) => "super".to_owned(),
741             UseSegment::Glob => "*".to_owned(),
742             UseSegment::List(ref use_tree_list) => rewrite_nested_use_tree(
743                 context,
744                 use_tree_list,
745                 // 1 = "{" and "}"
746                 shape.offset_left(1)?.sub_width(1)?,
747             )?,
748         })
749     }
750 }
751
752 impl Rewrite for UseTree {
753     // This does NOT format attributes and visibility or add a trailing `;`.
754     fn rewrite(&self, context: &RewriteContext, mut shape: Shape) -> Option<String> {
755         let mut result = String::with_capacity(256);
756         let mut iter = self.path.iter().peekable();
757         while let Some(ref segment) = iter.next() {
758             let segment_str = segment.rewrite(context, shape)?;
759             result.push_str(&segment_str);
760             if iter.peek().is_some() {
761                 result.push_str("::");
762                 // 2 = "::"
763                 shape = shape.offset_left(2 + segment_str.len())?;
764             }
765         }
766         Some(result)
767     }
768 }
769
770 #[cfg(test)]
771 mod test {
772     use super::*;
773     use syntax::codemap::DUMMY_SP;
774
775     // Parse the path part of an import. This parser is not robust and is only
776     // suitable for use in a test harness.
777     fn parse_use_tree(s: &str) -> UseTree {
778         use std::iter::Peekable;
779         use std::mem::swap;
780         use std::str::Chars;
781
782         struct Parser<'a> {
783             input: Peekable<Chars<'a>>,
784         }
785
786         impl<'a> Parser<'a> {
787             fn bump(&mut self) {
788                 self.input.next().unwrap();
789             }
790             fn eat(&mut self, c: char) {
791                 assert!(self.input.next().unwrap() == c);
792             }
793             fn push_segment(
794                 result: &mut Vec<UseSegment>,
795                 buf: &mut String,
796                 alias_buf: &mut Option<String>,
797             ) {
798                 if !buf.is_empty() {
799                     let mut alias = None;
800                     swap(alias_buf, &mut alias);
801                     if buf == "self" {
802                         result.push(UseSegment::Slf(alias));
803                         *buf = String::new();
804                         *alias_buf = None;
805                     } else if buf == "super" {
806                         result.push(UseSegment::Super(alias));
807                         *buf = String::new();
808                         *alias_buf = None;
809                     } else {
810                         let mut name = String::new();
811                         swap(buf, &mut name);
812                         result.push(UseSegment::Ident(name, alias));
813                     }
814                 }
815             }
816             fn parse_in_list(&mut self) -> UseTree {
817                 let mut result = vec![];
818                 let mut buf = String::new();
819                 let mut alias_buf = None;
820                 while let Some(&c) = self.input.peek() {
821                     match c {
822                         '{' => {
823                             assert!(buf.is_empty());
824                             self.bump();
825                             result.push(UseSegment::List(self.parse_list()));
826                             self.eat('}');
827                         }
828                         '*' => {
829                             assert!(buf.is_empty());
830                             self.bump();
831                             result.push(UseSegment::Glob);
832                         }
833                         ':' => {
834                             self.bump();
835                             self.eat(':');
836                             Self::push_segment(&mut result, &mut buf, &mut alias_buf);
837                         }
838                         '}' | ',' => {
839                             Self::push_segment(&mut result, &mut buf, &mut alias_buf);
840                             return UseTree {
841                                 path: result,
842                                 span: DUMMY_SP,
843                                 list_item: None,
844                                 visibility: None,
845                                 attrs: None,
846                             };
847                         }
848                         ' ' => {
849                             self.bump();
850                             self.eat('a');
851                             self.eat('s');
852                             self.eat(' ');
853                             alias_buf = Some(String::new());
854                         }
855                         c => {
856                             self.bump();
857                             if let Some(ref mut buf) = alias_buf {
858                                 buf.push(c);
859                             } else {
860                                 buf.push(c);
861                             }
862                         }
863                     }
864                 }
865                 Self::push_segment(&mut result, &mut buf, &mut alias_buf);
866                 UseTree {
867                     path: result,
868                     span: DUMMY_SP,
869                     list_item: None,
870                     visibility: None,
871                     attrs: None,
872                 }
873             }
874
875             fn parse_list(&mut self) -> Vec<UseTree> {
876                 let mut result = vec![];
877                 loop {
878                     match self.input.peek().unwrap() {
879                         ',' | ' ' => self.bump(),
880                         '}' => {
881                             return result;
882                         }
883                         _ => result.push(self.parse_in_list()),
884                     }
885                 }
886             }
887         }
888
889         let mut parser = Parser {
890             input: s.chars().peekable(),
891         };
892         parser.parse_in_list()
893     }
894
895     macro parse_use_trees($($s:expr),* $(,)*) {
896         vec![
897             $(parse_use_tree($s),)*
898         ]
899     }
900
901     #[test]
902     fn test_use_tree_merge() {
903         macro test_merge([$($input:expr),* $(,)*], [$($output:expr),* $(,)*]) {
904             assert_eq!(
905                 merge_use_trees(parse_use_trees!($($input,)*)),
906                 parse_use_trees!($($output,)*),
907             );
908         }
909
910         test_merge!(["a::b::{c, d}", "a::b::{e, f}"], ["a::b::{c, d, e, f}"]);
911         test_merge!(["a::b::c", "a::b"], ["a::b::{self, c}"]);
912         test_merge!(["a::b", "a::b"], ["a::b"]);
913         test_merge!(["a", "a::b", "a::b::c"], ["a::{self, b::{self, c}}"]);
914         test_merge!(
915             ["a::{b::{self, c}, d::e}", "a::d::f"],
916             ["a::{b::{self, c}, d::{e, f}}"]
917         );
918         test_merge!(
919             ["a::d::f", "a::{b::{self, c}, d::e}"],
920             ["a::{b::{self, c}, d::{e, f}}"]
921         );
922         test_merge!(
923             ["a::{c, d, b}", "a::{d, e, b, a, f}", "a::{f, g, c}"],
924             ["a::{a, b, c, d, e, f, g}"]
925         );
926     }
927
928     #[test]
929     fn test_use_tree_flatten() {
930         assert_eq!(
931             parse_use_tree("a::b::{c, d, e, f}").flatten(),
932             parse_use_trees!("a::b::c", "a::b::d", "a::b::e", "a::b::f",)
933         );
934
935         assert_eq!(
936             parse_use_tree("a::b::{c::{d, e, f}, g, h::{i, j, k}}").flatten(),
937             parse_use_trees![
938                 "a::b::c::d",
939                 "a::b::c::e",
940                 "a::b::c::f",
941                 "a::b::g",
942                 "a::b::h::i",
943                 "a::b::h::j",
944                 "a::b::h::k",
945             ]
946         );
947     }
948
949     #[test]
950     fn test_use_tree_normalize() {
951         assert_eq!(
952             parse_use_tree("a::self").normalize(true),
953             parse_use_tree("a")
954         );
955         assert_eq!(
956             parse_use_tree("a::self as foo").normalize(true),
957             parse_use_tree("a as foo")
958         );
959         assert_eq!(
960             parse_use_tree("a::{self}").normalize(true),
961             parse_use_tree("a")
962         );
963         assert_eq!(
964             parse_use_tree("a::{b}").normalize(true),
965             parse_use_tree("a::b")
966         );
967         assert_eq!(
968             parse_use_tree("a::{b, c::self}").normalize(true),
969             parse_use_tree("a::{b, c}")
970         );
971         assert_eq!(
972             parse_use_tree("a::{b as bar, c::self}").normalize(true),
973             parse_use_tree("a::{b as bar, c}")
974         );
975     }
976
977     #[test]
978     fn test_use_tree_ord() {
979         assert!(parse_use_tree("a").normalize(true) < parse_use_tree("aa").normalize(true));
980         assert!(parse_use_tree("a").normalize(true) < parse_use_tree("a::a").normalize(true));
981         assert!(parse_use_tree("a").normalize(true) < parse_use_tree("*").normalize(true));
982         assert!(parse_use_tree("a").normalize(true) < parse_use_tree("{a, b}").normalize(true));
983         assert!(parse_use_tree("*").normalize(true) < parse_use_tree("{a, b}").normalize(true));
984
985         assert!(
986             parse_use_tree("aaaaaaaaaaaaaaa::{bb, cc, dddddddd}").normalize(true)
987                 < parse_use_tree("aaaaaaaaaaaaaaa::{bb, cc, ddddddddd}").normalize(true)
988         );
989         assert!(
990             parse_use_tree("serde::de::{Deserialize}").normalize(true)
991                 < parse_use_tree("serde_json").normalize(true)
992         );
993         assert!(
994             parse_use_tree("a::b::c").normalize(true) < parse_use_tree("a::b::*").normalize(true)
995         );
996         assert!(
997             parse_use_tree("foo::{Bar, Baz}").normalize(true)
998                 < parse_use_tree("{Bar, Baz}").normalize(true)
999         );
1000
1001         assert!(
1002             parse_use_tree("foo::{self as bar}").normalize(true)
1003                 < parse_use_tree("foo::{qux as bar}").normalize(true)
1004         );
1005         assert!(
1006             parse_use_tree("foo::{qux as bar}").normalize(true)
1007                 < parse_use_tree("foo::{baz, qux as bar}").normalize(true)
1008         );
1009         assert!(
1010             parse_use_tree("foo::{self as bar, baz}").normalize(true)
1011                 < parse_use_tree("foo::{baz, qux as bar}").normalize(true)
1012         );
1013
1014         assert!(parse_use_tree("foo").normalize(true) < parse_use_tree("Foo").normalize(true));
1015         assert!(parse_use_tree("foo").normalize(true) < parse_use_tree("foo::Bar").normalize(true));
1016
1017         assert!(
1018             parse_use_tree("std::cmp::{d, c, b, a}").normalize(true)
1019                 < parse_use_tree("std::cmp::{b, e, g, f}").normalize(true)
1020         );
1021     }
1022 }