1use std::borrow::Cow;
2use std::cmp::Ordering;
3use std::fmt;
4
5use core::hash::{Hash, Hasher};
6
7use itertools::Itertools;
8
9use rustc_ast::ast::{self, UseTreeKind};
10use rustc_span::{
11 BytePos, DUMMY_SP, Span,
12 symbol::{self, sym},
13};
14
15use crate::comment::combine_strs_with_missing_comments;
16use crate::config::ImportGranularity;
17use crate::config::lists::*;
18use crate::config::{Edition, IndentStyle, StyleEdition};
19use crate::lists::{
20 ListFormatting, ListItem, Separator, definitive_tactic, itemize_list, write_list,
21};
22use crate::rewrite::{Rewrite, RewriteContext, RewriteErrorExt, RewriteResult};
23use crate::shape::Shape;
24use crate::sort::version_sort;
25use crate::source_map::SpanUtils;
26use crate::spanned::Spanned;
27use crate::utils::{is_same_visibility, mk_sp, rewrite_ident};
28use crate::visitor::FmtVisitor;
29
30pub(crate) fn path_to_imported_ident(path: &ast::Path) -> symbol::Ident {
33 path.segments.last().unwrap().ident
34}
35
36fn module_prefix(path: &[UseSegment]) -> &[UseSegment] {
40 &path[..(path.len() - 1).max(1)]
41}
42
43impl<'a> FmtVisitor<'a> {
44 pub(crate) fn format_import(&mut self, item: &ast::Item, tree: &ast::UseTree) {
45 let span = item.span();
46 let shape = self.shape();
47 let rw = UseTree::from_ast(
48 &self.get_context(),
49 tree,
50 None,
51 Some(item.vis.clone()),
52 Some(item.span.lo()),
53 Some(item.attrs.clone()),
54 )
55 .rewrite_top_level(&self.get_context(), shape)
56 .ok();
57 match rw {
58 Some(ref s) if s.is_empty() => {
59 let prev_span = mk_sp(self.last_pos, source!(self, span).lo());
61 let trimmed_snippet = self.snippet(prev_span).trim_end();
62 let span_end = self.last_pos + BytePos(trimmed_snippet.len() as u32);
63 self.format_missing(span_end);
64 if self.buffer.ends_with('\n') {
66 self.buffer.pop();
67 self.line_number -= 1;
68 }
69 self.last_pos = source!(self, span).hi();
70 }
71 Some(ref s) => {
72 self.format_missing_with_indent(source!(self, span).lo());
73 self.push_str(s);
74 self.last_pos = source!(self, span).hi();
75 }
76 None => {
77 self.format_missing_with_indent(source!(self, span).lo());
78 self.format_missing(source!(self, span).hi());
79 }
80 }
81 }
82}
83
84#[derive(Clone, Eq, Hash, PartialEq)]
104pub(crate) enum UseSegmentKind {
105 Ident(String, Option<String>),
106 Slf(Option<String>),
107 Super(Option<String>),
108 Crate(Option<String>),
109 Glob,
110 List(Vec<UseTree>),
111}
112
113#[derive(Clone, Eq, PartialEq)]
114pub(crate) struct UseSegment {
115 pub(crate) kind: UseSegmentKind,
116 pub(crate) style_edition: StyleEdition,
117}
118
119#[derive(Clone)]
120pub(crate) struct UseTree {
121 pub(crate) path: Vec<UseSegment>,
122 pub(crate) span: Span,
123 pub(crate) list_item: Option<ListItem>,
125 visibility: Option<ast::Visibility>,
128 attrs: Option<ast::AttrVec>,
129}
130
131impl PartialEq for UseTree {
132 fn eq(&self, other: &UseTree) -> bool {
133 self.path == other.path
134 }
135}
136impl Eq for UseTree {}
137
138impl Spanned for UseTree {
139 fn span(&self) -> Span {
140 let lo = if let Some(ref attrs) = self.attrs {
141 attrs.iter().next().map_or(self.span.lo(), |a| a.span.lo())
142 } else {
143 self.span.lo()
144 };
145 mk_sp(lo, self.span.hi())
146 }
147}
148
149impl UseSegment {
150 fn remove_alias(&self) -> UseSegment {
152 let kind = match self.kind {
153 UseSegmentKind::Ident(ref s, _) => UseSegmentKind::Ident(s.clone(), None),
154 UseSegmentKind::Slf(_) => UseSegmentKind::Slf(None),
155 UseSegmentKind::Super(_) => UseSegmentKind::Super(None),
156 UseSegmentKind::Crate(_) => UseSegmentKind::Crate(None),
157 _ => return self.clone(),
158 };
159 UseSegment {
160 kind,
161 style_edition: self.style_edition,
162 }
163 }
164
165 fn equal_except_alias(&self, other: &Self) -> bool {
167 match (&self.kind, &other.kind) {
168 (UseSegmentKind::Ident(ref s1, _), UseSegmentKind::Ident(ref s2, _)) => s1 == s2,
169 (UseSegmentKind::Slf(_), UseSegmentKind::Slf(_))
170 | (UseSegmentKind::Super(_), UseSegmentKind::Super(_))
171 | (UseSegmentKind::Crate(_), UseSegmentKind::Crate(_))
172 | (UseSegmentKind::Glob, UseSegmentKind::Glob) => true,
173 (UseSegmentKind::List(ref list1), UseSegmentKind::List(ref list2)) => list1 == list2,
174 _ => false,
175 }
176 }
177
178 fn get_alias(&self) -> Option<&str> {
179 match &self.kind {
180 UseSegmentKind::Ident(_, a)
181 | UseSegmentKind::Slf(a)
182 | UseSegmentKind::Super(a)
183 | UseSegmentKind::Crate(a) => a.as_deref(),
184 _ => None,
185 }
186 }
187
188 fn from_path_segment(
189 context: &RewriteContext<'_>,
190 path_seg: &ast::PathSegment,
191 modsep: bool,
192 ) -> Option<UseSegment> {
193 let name = rewrite_ident(context, path_seg.ident);
194 if name.is_empty() {
195 return None;
196 }
197 let kind = match name {
198 "self" => UseSegmentKind::Slf(None),
199 "super" => UseSegmentKind::Super(None),
200 "crate" => UseSegmentKind::Crate(None),
201 _ => {
202 let mod_sep = if modsep { "::" } else { "" };
203 UseSegmentKind::Ident(format!("{mod_sep}{name}"), None)
204 }
205 };
206
207 Some(UseSegment {
208 kind,
209 style_edition: context.config.style_edition(),
210 })
211 }
212
213 fn contains_comment(&self) -> bool {
214 if let UseSegmentKind::List(list) = &self.kind {
215 list.iter().any(|subtree| subtree.contains_comment())
216 } else {
217 false
218 }
219 }
220}
221
222pub(crate) fn normalize_use_trees_with_granularity(
223 use_trees: Vec<UseTree>,
224 import_granularity: ImportGranularity,
225) -> Vec<UseTree> {
226 let merge_by = match import_granularity {
227 ImportGranularity::Item => return flatten_use_trees(use_trees, ImportGranularity::Item),
228 ImportGranularity::Preserve => return use_trees,
229 ImportGranularity::Crate => SharedPrefix::Crate,
230 ImportGranularity::Module => SharedPrefix::Module,
231 ImportGranularity::One => SharedPrefix::One,
232 };
233
234 let mut result = Vec::with_capacity(use_trees.len());
235 for use_tree in use_trees {
236 if use_tree.contains_comment() || use_tree.attrs.is_some() {
237 result.push(use_tree);
238 continue;
239 }
240
241 for mut flattened in use_tree.flatten(import_granularity) {
242 if let Some(tree) = result
243 .iter_mut()
244 .find(|tree| tree.share_prefix(&flattened, merge_by))
245 {
246 tree.merge(&flattened, merge_by);
247 } else {
248 if merge_by == SharedPrefix::Module {
250 flattened = flattened.nest_trailing_self();
251 }
252 result.push(flattened);
253 }
254 }
255 }
256 result
257}
258
259fn flatten_use_trees(
260 use_trees: Vec<UseTree>,
261 import_granularity: ImportGranularity,
262) -> Vec<UseTree> {
263 use_trees
266 .into_iter()
267 .flat_map(|tree| tree.flatten(import_granularity))
268 .map(UseTree::nest_trailing_self)
269 .unique()
270 .collect()
271}
272
273impl fmt::Debug for UseTree {
274 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
275 fmt::Display::fmt(self, f)
276 }
277}
278
279impl fmt::Debug for UseSegment {
280 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
281 fmt::Display::fmt(&self.kind, f)
282 }
283}
284
285impl fmt::Display for UseSegment {
286 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
287 fmt::Display::fmt(&self.kind, f)
288 }
289}
290
291impl Hash for UseSegment {
292 fn hash<H: Hasher>(&self, state: &mut H) {
293 self.kind.hash(state);
294 }
295}
296
297impl fmt::Debug for UseSegmentKind {
298 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
299 fmt::Display::fmt(self, f)
300 }
301}
302
303impl fmt::Display for UseSegmentKind {
304 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
305 match *self {
306 UseSegmentKind::Glob => write!(f, "*"),
307 UseSegmentKind::Ident(ref s, Some(ref alias)) => write!(f, "{s} as {alias}"),
308 UseSegmentKind::Ident(ref s, None) => write!(f, "{s}"),
309 UseSegmentKind::Slf(..) => write!(f, "self"),
310 UseSegmentKind::Super(..) => write!(f, "super"),
311 UseSegmentKind::Crate(..) => write!(f, "crate"),
312 UseSegmentKind::List(ref list) => {
313 write!(f, "{{")?;
314 for (i, item) in list.iter().enumerate() {
315 if i != 0 {
316 write!(f, ", ")?;
317 }
318 write!(f, "{item}")?;
319 }
320 write!(f, "}}")
321 }
322 }
323 }
324}
325impl fmt::Display for UseTree {
326 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
327 for (i, segment) in self.path.iter().enumerate() {
328 if i != 0 {
329 write!(f, "::")?;
330 }
331 write!(f, "{segment}")?;
332 }
333 Ok(())
334 }
335}
336
337impl UseTree {
338 pub(crate) fn rewrite_top_level(
340 &self,
341 context: &RewriteContext<'_>,
342 shape: Shape,
343 ) -> RewriteResult {
344 let vis = self.visibility.as_ref().map_or(Cow::from(""), |vis| {
345 crate::utils::format_visibility(context, vis)
346 });
347 let use_str = self
348 .rewrite_result(context, shape.offset_left(vis.len(), self.span())?)
349 .map(|s| {
350 if s.is_empty() {
351 s
352 } else {
353 format!("{}use {};", vis, s)
354 }
355 })?;
356 match self.attrs {
357 Some(ref attrs) if !attrs.is_empty() => {
358 let attr_str = attrs.rewrite_result(context, shape)?;
359 let lo = attrs.last().unknown_error()?.span.hi();
360 let hi = self.span.lo();
361 let span = mk_sp(lo, hi);
362
363 let allow_extend = if attrs.len() == 1 {
364 let line_len = attr_str.len() + 1 + use_str.len();
365 !attrs.first().unwrap().is_doc_comment()
366 && context.config.inline_attribute_width() >= line_len
367 } else {
368 false
369 };
370
371 combine_strs_with_missing_comments(
372 context,
373 &attr_str,
374 &use_str,
375 span,
376 shape,
377 allow_extend,
378 )
379 }
380 _ => Ok(use_str),
381 }
382 }
383
384 fn from_path(path: Vec<UseSegment>, span: Span) -> UseTree {
390 UseTree {
391 path,
392 span,
393 list_item: None,
394 visibility: None,
395 attrs: None,
396 }
397 }
398
399 pub(crate) fn from_ast_with_normalization(
400 context: &RewriteContext<'_>,
401 item: &ast::Item,
402 ) -> Option<UseTree> {
403 match item.kind {
404 ast::ItemKind::Use(ref use_tree) => Some(
405 UseTree::from_ast(
406 context,
407 use_tree,
408 None,
409 Some(item.vis.clone()),
410 Some(item.span.lo()),
411 if item.attrs.is_empty() {
412 None
413 } else {
414 Some(item.attrs.clone())
415 },
416 )
417 .normalize(),
418 ),
419 _ => None,
420 }
421 }
422
423 fn from_ast(
424 context: &RewriteContext<'_>,
425 a: &ast::UseTree,
426 list_item: Option<ListItem>,
427 visibility: Option<ast::Visibility>,
428 opt_lo: Option<BytePos>,
429 attrs: Option<ast::AttrVec>,
430 ) -> UseTree {
431 let span = if let Some(lo) = opt_lo {
432 mk_sp(lo, a.span.hi())
433 } else {
434 a.span
435 };
436 let mut result = UseTree {
437 path: vec![],
438 span,
439 list_item,
440 visibility,
441 attrs,
442 };
443
444 let leading_modsep =
445 context.config.edition() >= Edition::Edition2018 && a.prefix.is_global();
446
447 let mut modsep = leading_modsep;
448
449 for p in &a.prefix.segments {
450 if let Some(use_segment) = UseSegment::from_path_segment(context, p, modsep) {
451 result.path.push(use_segment);
452 modsep = false;
453 }
454 }
455
456 let style_edition = context.config.style_edition();
457
458 match a.kind {
459 UseTreeKind::Glob => {
460 if a.prefix.segments.len() == 1 && leading_modsep {
462 let kind = UseSegmentKind::Ident("".to_owned(), None);
463 result.path.push(UseSegment {
464 kind,
465 style_edition,
466 });
467 }
468 result.path.push(UseSegment {
469 kind: UseSegmentKind::Glob,
470 style_edition,
471 });
472 }
473 UseTreeKind::Nested {
474 items: ref list, ..
475 } => {
476 let items = itemize_list(
479 context.snippet_provider,
480 list.iter().map(|(tree, _)| tree),
481 "}",
482 ",",
483 |tree| tree.span.lo(),
484 |tree| tree.span.hi(),
485 |_| Ok("".to_owned()), context.snippet_provider.span_after(a.span, "{"),
487 a.span.hi(),
488 false,
489 );
490
491 if a.prefix.segments.len() == 1 && leading_modsep {
494 let kind = UseSegmentKind::Ident("".to_owned(), None);
495 result.path.push(UseSegment {
496 kind,
497 style_edition,
498 });
499 }
500 let kind = UseSegmentKind::List(
501 list.iter()
502 .zip(items)
503 .map(|(t, list_item)| {
504 Self::from_ast(context, &t.0, Some(list_item), None, None, None)
505 })
506 .collect(),
507 );
508 result.path.push(UseSegment {
509 kind,
510 style_edition,
511 });
512 }
513 UseTreeKind::Simple(ref rename) => {
514 let name = if a.prefix.segments.len() == 2 && leading_modsep {
519 context.snippet(a.prefix.span).to_owned()
520 } else {
521 rewrite_ident(context, path_to_imported_ident(&a.prefix)).to_owned()
522 };
523 let alias = rename.and_then(|ident| {
524 if ident.name == sym::underscore_imports {
525 Some("_".to_owned())
527 } else if ident == path_to_imported_ident(&a.prefix) {
528 None
529 } else {
530 Some(rewrite_ident(context, ident).to_owned())
531 }
532 });
533 let kind = match name.as_ref() {
534 "self" => UseSegmentKind::Slf(alias),
535 "super" => UseSegmentKind::Super(alias),
536 "crate" => UseSegmentKind::Crate(alias),
537 _ => UseSegmentKind::Ident(name, alias),
538 };
539
540 let segment = UseSegment {
541 kind,
542 style_edition,
543 };
544
545 result.path.pop();
547 result.path.push(segment);
548 }
549 }
550 result
551 }
552
553 pub(crate) fn normalize(mut self) -> UseTree {
555 let mut last = self.path.pop().expect("Empty use tree?");
556 let mut normalize_sole_list = false;
558 let mut aliased_self = false;
559
560 match last.kind {
562 _ if self.attrs.is_some() => (),
563 UseSegmentKind::List(ref list) if list.is_empty() => {
564 self.path = vec![];
565 return self;
566 }
567 UseSegmentKind::Slf(None) if self.path.is_empty() && self.visibility.is_some() => {
568 self.path = vec![];
569 return self;
570 }
571 _ => (),
572 }
573
574 if let UseSegmentKind::Slf(None) = last.kind {
576 if let Some(second_last) = self.path.pop() {
577 if matches!(second_last.kind, UseSegmentKind::Slf(_)) {
578 self.path.push(second_last);
579 } else {
580 self.path.push(second_last);
581 return self;
582 }
583 }
584 }
585
586 if let UseSegmentKind::Slf(_) = last.kind {
588 if let Some(UseSegment {
589 kind: UseSegmentKind::Ident(_, None),
590 ..
591 }) = self.path.last()
592 {
593 aliased_self = true;
594 }
595 }
596
597 let mut done = false;
598 if aliased_self {
599 match self.path.last_mut() {
600 Some(UseSegment {
601 kind: UseSegmentKind::Ident(_, ref mut old_rename),
602 ..
603 }) => {
604 assert!(old_rename.is_none());
605 if let UseSegmentKind::Slf(Some(rename)) = last.clone().kind {
606 *old_rename = Some(rename);
607 done = true;
608 }
609 }
610 _ => unreachable!(),
611 }
612 }
613
614 if done {
615 return self;
616 }
617
618 if let UseSegmentKind::List(ref list) = last.kind {
620 if list.len() == 1 && list[0].to_string() != "self" && !list[0].has_comment() {
621 normalize_sole_list = true;
622 }
623 }
624
625 if normalize_sole_list {
626 match last.kind {
627 UseSegmentKind::List(list) => {
628 for seg in &list[0].path {
629 self.path.push(seg.clone());
630 }
631 return self.normalize();
632 }
633 _ => unreachable!(),
634 }
635 }
636
637 if let UseSegmentKind::List(list) = last.kind {
639 let mut list = list.into_iter().map(UseTree::normalize).collect::<Vec<_>>();
640 list.sort();
641 list.dedup();
642 last = UseSegment {
643 kind: UseSegmentKind::List(list),
644 style_edition: last.style_edition,
645 };
646 }
647
648 self.path.push(last);
649 self
650 }
651
652 fn has_comment(&self) -> bool {
653 self.list_item.as_ref().map_or(false, ListItem::has_comment)
654 }
655
656 fn contains_comment(&self) -> bool {
657 self.has_comment() || self.path.iter().any(|path| path.contains_comment())
658 }
659
660 fn same_visibility(&self, other: &UseTree) -> bool {
661 match (&self.visibility, &other.visibility) {
662 (
663 Some(ast::Visibility {
664 kind: ast::VisibilityKind::Inherited,
665 ..
666 }),
667 None,
668 )
669 | (
670 None,
671 Some(ast::Visibility {
672 kind: ast::VisibilityKind::Inherited,
673 ..
674 }),
675 )
676 | (None, None) => true,
677 (Some(ref a), Some(ref b)) => is_same_visibility(a, b),
678 _ => false,
679 }
680 }
681
682 fn share_prefix(&self, other: &UseTree, shared_prefix: SharedPrefix) -> bool {
683 if self.path.is_empty()
684 || other.path.is_empty()
685 || self.attrs.is_some()
686 || self.contains_comment()
687 || !self.same_visibility(other)
688 {
689 false
690 } else {
691 match shared_prefix {
692 SharedPrefix::Crate => self.path[0] == other.path[0],
693 SharedPrefix::Module => module_prefix(&self.path) == module_prefix(&other.path),
694 SharedPrefix::One => true,
695 }
696 }
697 }
698
699 fn flatten(self, import_granularity: ImportGranularity) -> Vec<UseTree> {
700 if self.path.is_empty() || self.contains_comment() {
701 return vec![self];
702 }
703 match &self.path.clone().last().unwrap().kind {
704 UseSegmentKind::List(list) => {
705 if list.len() == 1 && list[0].path.len() == 1 {
706 if let UseSegmentKind::Slf(..) = list[0].path[0].kind {
707 return vec![self];
708 };
709 }
710 let prefix = &self.path[..self.path.len() - 1];
711 let mut result = vec![];
712 for nested_use_tree in list {
713 for flattened in &mut nested_use_tree.clone().flatten(import_granularity) {
714 let mut new_path = prefix.to_vec();
715 new_path.append(&mut flattened.path);
716 result.push(UseTree {
717 path: new_path,
718 span: self.span,
719 list_item: None,
720 visibility: self.visibility.clone(),
721 attrs: match import_granularity {
723 ImportGranularity::Item => self.attrs.clone(),
724 _ => None,
725 },
726 });
727 }
728 }
729
730 result
731 }
732 _ => vec![self],
733 }
734 }
735
736 fn merge(&mut self, other: &UseTree, merge_by: SharedPrefix) {
737 let mut prefix = 0;
738 for (a, b) in self.path.iter().zip(other.path.iter()) {
739 if (prefix == 0 && a.equal_except_alias(b)) || a == b {
741 prefix += 1;
742 } else {
743 break;
744 }
745 }
746 if let Some(new_path) = merge_rest(&self.path, &other.path, prefix, merge_by) {
747 self.path = new_path;
748 self.span = self.span.to(other.span);
749 }
750 }
751
752 fn nest_trailing_self(mut self) -> UseTree {
754 if let Some(UseSegment {
755 kind: UseSegmentKind::Slf(..),
756 ..
757 }) = self.path.last()
758 {
759 let self_segment = self.path.pop().unwrap();
760 let style_edition = self_segment.style_edition;
761 let kind = UseSegmentKind::List(vec![UseTree::from_path(vec![self_segment], DUMMY_SP)]);
762 self.path.push(UseSegment {
763 kind,
764 style_edition,
765 });
766 }
767 self
768 }
769}
770
771fn merge_rest(
772 a: &[UseSegment],
773 b: &[UseSegment],
774 mut len: usize,
775 merge_by: SharedPrefix,
776) -> Option<Vec<UseSegment>> {
777 if a.len() == len && b.len() == len {
778 return None;
779 }
780 if a.len() != len && b.len() != len {
781 let style_edition = a[len].style_edition;
782 if let UseSegmentKind::List(ref list) = a[len].kind {
783 let mut list = list.clone();
784 merge_use_trees_inner(
785 &mut list,
786 UseTree::from_path(b[len..].to_vec(), DUMMY_SP),
787 merge_by,
788 );
789 let mut new_path = b[..len].to_vec();
790 let kind = UseSegmentKind::List(list);
791 new_path.push(UseSegment {
792 kind,
793 style_edition,
794 });
795 return Some(new_path);
796 }
797 } else if len == 1 {
798 let (common, rest) = if a.len() == len {
799 (&a[0], &b[1..])
800 } else {
801 (&b[0], &a[1..])
802 };
803 let kind = UseSegmentKind::Slf(common.get_alias().map(ToString::to_string));
804 let style_edition = a[0].style_edition;
805 let mut list = vec![UseTree::from_path(
806 vec![UseSegment {
807 kind,
808 style_edition,
809 }],
810 DUMMY_SP,
811 )];
812 match rest {
813 [
814 UseSegment {
815 kind: UseSegmentKind::List(rest_list),
816 ..
817 },
818 ] => list.extend(rest_list.clone()),
819 _ => list.push(UseTree::from_path(rest.to_vec(), DUMMY_SP)),
820 }
821 return Some(vec![
822 b[0].clone(),
823 UseSegment {
824 kind: UseSegmentKind::List(list),
825 style_edition,
826 },
827 ]);
828 } else {
829 len -= 1;
830 }
831 let mut list = vec![
832 UseTree::from_path(a[len..].to_vec(), DUMMY_SP),
833 UseTree::from_path(b[len..].to_vec(), DUMMY_SP),
834 ];
835 list.sort();
836 list.dedup();
837 let mut new_path = b[..len].to_vec();
838 let kind = UseSegmentKind::List(list);
839 let style_edition = a[0].style_edition;
840 new_path.push(UseSegment {
841 kind,
842 style_edition,
843 });
844 Some(new_path)
845}
846
847fn merge_use_trees_inner(trees: &mut Vec<UseTree>, use_tree: UseTree, merge_by: SharedPrefix) {
848 struct SimilarTree<'a> {
849 similarity: usize,
850 path_len: usize,
851 tree: &'a mut UseTree,
852 }
853
854 let similar_trees = trees.iter_mut().filter_map(|tree| {
855 if tree.share_prefix(&use_tree, merge_by) {
856 let similarity = if merge_by == SharedPrefix::One {
860 tree.path
861 .iter()
862 .zip(&use_tree.path)
863 .take_while(|(a, b)| a.equal_except_alias(b))
864 .count()
865 } else {
866 0
867 };
868
869 let path_len = tree.path.len();
870 Some(SimilarTree {
871 similarity,
872 tree,
873 path_len,
874 })
875 } else {
876 None
877 }
878 });
879
880 if use_tree.path.len() == 1 && merge_by == SharedPrefix::Crate {
881 if let Some(tree) = similar_trees.min_by_key(|tree| tree.path_len) {
882 if tree.path_len == 1 {
883 return;
884 }
885 }
886 } else if merge_by == SharedPrefix::One {
887 if let Some(sim_tree) = similar_trees.max_by_key(|tree| tree.similarity) {
888 if sim_tree.similarity > 0 {
889 sim_tree.tree.merge(&use_tree, merge_by);
890 return;
891 }
892 }
893 } else if let Some(sim_tree) = similar_trees.max_by_key(|tree| tree.path_len) {
894 if sim_tree.path_len > 1 {
895 sim_tree.tree.merge(&use_tree, merge_by);
896 return;
897 }
898 }
899 trees.push(use_tree);
900 trees.sort();
901 trees.dedup();
902}
903
904impl Hash for UseTree {
905 fn hash<H: Hasher>(&self, state: &mut H) {
906 self.path.hash(state);
907 }
908}
909
910impl PartialOrd for UseSegment {
911 fn partial_cmp(&self, other: &UseSegment) -> Option<Ordering> {
912 Some(self.cmp(other))
913 }
914}
915impl PartialOrd for UseTree {
916 fn partial_cmp(&self, other: &UseTree) -> Option<Ordering> {
917 Some(self.cmp(other))
918 }
919}
920impl Ord for UseSegment {
921 fn cmp(&self, other: &UseSegment) -> Ordering {
922 use self::UseSegmentKind::*;
923
924 fn is_upper_snake_case(s: &str) -> bool {
925 s.chars()
926 .all(|c| c.is_uppercase() || c == '_' || c.is_numeric())
927 }
928
929 match (&self.kind, &other.kind) {
930 (Slf(ref a), Slf(ref b))
931 | (Super(ref a), Super(ref b))
932 | (Crate(ref a), Crate(ref b)) => match (a, b) {
933 (Some(sa), Some(sb)) => {
934 if self.style_edition >= StyleEdition::Edition2024 {
935 version_sort(sa.trim_start_matches("r#"), sb.trim_start_matches("r#"))
936 } else {
937 a.cmp(b)
938 }
939 }
940 (_, _) => a.cmp(b),
941 },
942 (Glob, Glob) => Ordering::Equal,
943 (Ident(ref pia, ref aa), Ident(ref pib, ref ab)) => {
944 let (ia, ib) = if self.style_edition >= StyleEdition::Edition2024 {
945 (pia.trim_start_matches("r#"), pib.trim_start_matches("r#"))
946 } else {
947 (pia.as_str(), pib.as_str())
948 };
949
950 let ident_ord = if self.style_edition >= StyleEdition::Edition2024 {
951 version_sort(ia, ib)
952 } else {
953 fn sorting_key(ident: &str) -> (bool, bool, &str) {
954 (
956 is_upper_snake_case(ident),
957 ident.starts_with(char::is_uppercase),
958 ident,
959 )
960 }
961
962 sorting_key(ia).cmp(&sorting_key(ib))
963 };
964
965 if ident_ord != Ordering::Equal {
966 return ident_ord;
967 }
968 match (aa, ab) {
969 (None, Some(_)) => Ordering::Less,
970 (Some(_), None) => Ordering::Greater,
971 (Some(aas), Some(abs)) => {
972 if self.style_edition >= StyleEdition::Edition2024 {
973 version_sort(aas.trim_start_matches("r#"), abs.trim_start_matches("r#"))
974 } else {
975 aas.cmp(abs)
976 }
977 }
978 (None, None) => Ordering::Equal,
979 }
980 }
981 (List(ref a), List(ref b)) => a.iter().cmp(b.iter()),
982 (Slf(_), _) => Ordering::Less,
983 (_, Slf(_)) => Ordering::Greater,
984 (Super(_), _) => Ordering::Less,
985 (_, Super(_)) => Ordering::Greater,
986 (Crate(_), _) => Ordering::Less,
987 (_, Crate(_)) => Ordering::Greater,
988 (Ident(..), _) => Ordering::Less,
989 (_, Ident(..)) => Ordering::Greater,
990 (Glob, _) => Ordering::Less,
991 (_, Glob) => Ordering::Greater,
992 }
993 }
994}
995impl Ord for UseTree {
996 fn cmp(&self, other: &UseTree) -> Ordering {
997 for (a, b) in self.path.iter().zip(other.path.iter()) {
998 let ord = a.cmp(b);
999 if ord != Ordering::Equal && a.remove_alias().cmp(&b.remove_alias()) != Ordering::Equal
1003 {
1004 return ord;
1005 }
1006 }
1007
1008 self.path.len().cmp(&other.path.len())
1009 }
1010}
1011
1012fn rewrite_nested_use_tree(
1013 context: &RewriteContext<'_>,
1014 use_tree_list: &[UseTree],
1015 shape: Shape,
1016) -> RewriteResult {
1017 let mut list_items = Vec::with_capacity(use_tree_list.len());
1018 let nested_shape = match context.config.imports_indent() {
1019 IndentStyle::Block => shape
1020 .block_indent(context.config.tab_spaces())
1021 .with_max_width(context.config)
1022 .sub_width_opt(1)
1023 .unknown_error()?,
1024 IndentStyle::Visual => shape.visual_indent(0),
1025 };
1026 for use_tree in use_tree_list {
1027 if let Some(mut list_item) = use_tree.list_item.clone() {
1028 list_item.item = use_tree.rewrite_result(context, nested_shape);
1029 list_items.push(list_item);
1030 } else {
1031 list_items.push(ListItem::from_str(
1032 use_tree.rewrite_result(context, nested_shape)?,
1033 ));
1034 }
1035 }
1036 let has_nested_list = use_tree_list.iter().any(|use_segment| {
1037 use_segment.path.last().map_or(false, |last_segment| {
1038 matches!(last_segment.kind, UseSegmentKind::List(..))
1039 })
1040 });
1041
1042 let remaining_width = if has_nested_list {
1043 0
1044 } else {
1045 shape.width.saturating_sub(2)
1046 };
1047
1048 let tactic = definitive_tactic(
1049 &list_items,
1050 context.config.imports_layout(),
1051 Separator::Comma,
1052 remaining_width,
1053 );
1054
1055 let ends_with_newline = context.config.imports_indent() == IndentStyle::Block
1056 && tactic != DefinitiveListTactic::Horizontal;
1057 let trailing_separator = if ends_with_newline {
1058 context.config.trailing_comma()
1059 } else {
1060 SeparatorTactic::Never
1061 };
1062 let fmt = ListFormatting::new(nested_shape, context.config)
1063 .tactic(tactic)
1064 .trailing_separator(trailing_separator)
1065 .ends_with_newline(ends_with_newline)
1066 .preserve_newline(true)
1067 .nested(has_nested_list);
1068
1069 let list_str = write_list(&list_items, &fmt)?;
1070
1071 let result = if (list_str.contains('\n')
1072 || list_str.len() > remaining_width
1073 || tactic == DefinitiveListTactic::Vertical)
1074 && context.config.imports_indent() == IndentStyle::Block
1075 {
1076 format!(
1077 "{{\n{}{}\n{}}}",
1078 nested_shape.indent.to_string(context.config),
1079 list_str,
1080 shape.indent.to_string(context.config)
1081 )
1082 } else {
1083 format!("{{{list_str}}}")
1084 };
1085
1086 Ok(result)
1087}
1088
1089impl Rewrite for UseSegment {
1090 fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
1091 self.rewrite_result(context, shape).ok()
1092 }
1093
1094 fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
1095 Ok(match self.kind {
1096 UseSegmentKind::Ident(ref ident, Some(ref rename)) => {
1097 format!("{ident} as {rename}")
1098 }
1099 UseSegmentKind::Ident(ref ident, None) => ident.clone(),
1100 UseSegmentKind::Slf(Some(ref rename)) => format!("self as {rename}"),
1101 UseSegmentKind::Slf(None) => "self".to_owned(),
1102 UseSegmentKind::Super(Some(ref rename)) => format!("super as {rename}"),
1103 UseSegmentKind::Super(None) => "super".to_owned(),
1104 UseSegmentKind::Crate(Some(ref rename)) => format!("crate as {rename}"),
1105 UseSegmentKind::Crate(None) => "crate".to_owned(),
1106 UseSegmentKind::Glob => "*".to_owned(),
1107 UseSegmentKind::List(ref use_tree_list) => {
1108 rewrite_nested_use_tree(
1109 context,
1110 use_tree_list,
1111 shape
1113 .offset_left_opt(1)
1114 .and_then(|s| s.sub_width_opt(1))
1115 .unknown_error()?,
1116 )?
1117 }
1118 })
1119 }
1120}
1121
1122impl Rewrite for UseTree {
1123 fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
1124 self.rewrite_result(context, shape).ok()
1125 }
1126
1127 fn rewrite_result(&self, context: &RewriteContext<'_>, mut shape: Shape) -> RewriteResult {
1129 let mut result = String::with_capacity(256);
1130 let mut iter = self.path.iter().peekable();
1131 while let Some(segment) = iter.next() {
1132 let segment_str = segment.rewrite_result(context, shape)?;
1133 result.push_str(&segment_str);
1134 if iter.peek().is_some() {
1135 result.push_str("::");
1136 shape = shape.offset_left(2 + segment_str.len(), self.span())?;
1138 }
1139 }
1140 Ok(result)
1141 }
1142}
1143
1144#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1145enum SharedPrefix {
1146 Crate,
1147 Module,
1148 One,
1149}
1150
1151#[cfg(test)]
1152mod test {
1153 use super::*;
1154
1155 fn parse_use_tree(s: &str) -> UseTree {
1158 use std::iter::Peekable;
1159 use std::mem::swap;
1160 use std::str::Chars;
1161
1162 struct Parser<'a> {
1163 input: Peekable<Chars<'a>>,
1164 style_edition: StyleEdition,
1165 }
1166
1167 impl<'a> Parser<'a> {
1168 fn bump(&mut self) {
1169 self.input.next().unwrap();
1170 }
1171
1172 fn eat(&mut self, c: char) {
1173 assert_eq!(self.input.next().unwrap(), c);
1174 }
1175
1176 fn push_segment(
1177 &self,
1178 result: &mut Vec<UseSegment>,
1179 buf: &mut String,
1180 alias_buf: &mut Option<String>,
1181 ) {
1182 let style_edition = self.style_edition;
1183 if !buf.is_empty() {
1184 let mut alias = None;
1185 swap(alias_buf, &mut alias);
1186
1187 match buf.as_ref() {
1188 "self" => {
1189 let kind = UseSegmentKind::Slf(alias);
1190 result.push(UseSegment {
1191 kind,
1192 style_edition,
1193 });
1194 *buf = String::new();
1195 *alias_buf = None;
1196 }
1197 "super" => {
1198 let kind = UseSegmentKind::Super(alias);
1199 result.push(UseSegment {
1200 kind,
1201 style_edition,
1202 });
1203 *buf = String::new();
1204 *alias_buf = None;
1205 }
1206 "crate" => {
1207 let kind = UseSegmentKind::Crate(alias);
1208 result.push(UseSegment {
1209 kind,
1210 style_edition,
1211 });
1212 *buf = String::new();
1213 *alias_buf = None;
1214 }
1215 _ => {
1216 let mut name = String::new();
1217 swap(buf, &mut name);
1218 let kind = UseSegmentKind::Ident(name, alias);
1219 result.push(UseSegment {
1220 kind,
1221 style_edition,
1222 });
1223 }
1224 }
1225 }
1226 }
1227
1228 fn parse_in_list(&mut self) -> UseTree {
1229 let mut result = vec![];
1230 let mut buf = String::new();
1231 let mut alias_buf = None;
1232 while let Some(&c) = self.input.peek() {
1233 match c {
1234 '{' => {
1235 assert!(buf.is_empty());
1236 self.bump();
1237 let kind = UseSegmentKind::List(self.parse_list());
1238 result.push(UseSegment {
1239 kind,
1240 style_edition: self.style_edition,
1241 });
1242 self.eat('}');
1243 }
1244 '*' => {
1245 assert!(buf.is_empty());
1246 self.bump();
1247 let kind = UseSegmentKind::Glob;
1248 result.push(UseSegment {
1249 kind,
1250 style_edition: self.style_edition,
1251 });
1252 }
1253 ':' => {
1254 self.bump();
1255 self.eat(':');
1256 self.push_segment(&mut result, &mut buf, &mut alias_buf);
1257 }
1258 '}' | ',' => {
1259 self.push_segment(&mut result, &mut buf, &mut alias_buf);
1260 return UseTree {
1261 path: result,
1262 span: DUMMY_SP,
1263 list_item: None,
1264 visibility: None,
1265 attrs: None,
1266 };
1267 }
1268 ' ' => {
1269 self.bump();
1270 self.eat('a');
1271 self.eat('s');
1272 self.eat(' ');
1273 alias_buf = Some(String::new());
1274 }
1275 c => {
1276 self.bump();
1277 if let Some(ref mut buf) = alias_buf {
1278 buf.push(c);
1279 } else {
1280 buf.push(c);
1281 }
1282 }
1283 }
1284 }
1285 self.push_segment(&mut result, &mut buf, &mut alias_buf);
1286 UseTree {
1287 path: result,
1288 span: DUMMY_SP,
1289 list_item: None,
1290 visibility: None,
1291 attrs: None,
1292 }
1293 }
1294
1295 fn parse_list(&mut self) -> Vec<UseTree> {
1296 let mut result = vec![];
1297 loop {
1298 match self.input.peek().unwrap() {
1299 ',' | ' ' => self.bump(),
1300 '}' => {
1301 return result;
1302 }
1303 _ => result.push(self.parse_in_list()),
1304 }
1305 }
1306 }
1307 }
1308
1309 let mut parser = Parser {
1310 input: s.chars().peekable(),
1311 style_edition: StyleEdition::Edition2015,
1312 };
1313 parser.parse_in_list()
1314 }
1315
1316 macro_rules! parse_use_trees {
1317 ($($s:expr),* $(,)*) => {
1318 vec![
1319 $(parse_use_tree($s),)*
1320 ]
1321 }
1322 }
1323
1324 macro_rules! test_merge {
1325 ($by:ident, [$($input:expr),* $(,)*], [$($output:expr),* $(,)*]) => {
1326 assert_eq!(
1327 normalize_use_trees_with_granularity(
1328 parse_use_trees!($($input,)*),
1329 ImportGranularity::$by,
1330 ),
1331 parse_use_trees!($($output,)*),
1332 );
1333 }
1334 }
1335
1336 #[test]
1337 fn test_use_tree_merge_crate() {
1338 test_merge!(
1339 Crate,
1340 ["a::b::{c, d}", "a::b::{e, f}"],
1341 ["a::b::{c, d, e, f}"]
1342 );
1343 test_merge!(Crate, ["a::b::c", "a::b"], ["a::{b, b::c}"]);
1344 test_merge!(Crate, ["a::b", "a::b"], ["a::b"]);
1345 test_merge!(Crate, ["a", "a::b", "a::b::c"], ["a::{self, b, b::c}"]);
1346 test_merge!(
1347 Crate,
1348 ["a", "a::b", "a::b::c", "a::b::c::d"],
1349 ["a::{self, b, b::{c, c::d}}"]
1350 );
1351 test_merge!(
1352 Crate,
1353 ["a", "a::b", "a::b::c", "a::b"],
1354 ["a::{self, b, b::c}"]
1355 );
1356 test_merge!(
1357 Crate,
1358 ["a::{b::{self, c}, d::e}", "a::d::f"],
1359 ["a::{b::{self, c}, d::{e, f}}"]
1360 );
1361 test_merge!(
1362 Crate,
1363 ["a::d::f", "a::{b::{self, c}, d::e}"],
1364 ["a::{b::{self, c}, d::{e, f}}"]
1365 );
1366 test_merge!(
1367 Crate,
1368 ["a::{c, d, b}", "a::{d, e, b, a, f}", "a::{f, g, c}"],
1369 ["a::{a, b, c, d, e, f, g}"]
1370 );
1371 test_merge!(
1372 Crate,
1373 ["a::{self}", "b::{self as foo}"],
1374 ["a::{self}", "b::{self as foo}"]
1375 );
1376 }
1377
1378 #[test]
1379 fn test_use_tree_merge_module() {
1380 test_merge!(
1381 Module,
1382 ["foo::b", "foo::{a, c, d::e}"],
1383 ["foo::{a, b, c}", "foo::d::e"]
1384 );
1385
1386 test_merge!(
1387 Module,
1388 ["foo::{a::b, a::c, d::e, d::f}"],
1389 ["foo::a::{b, c}", "foo::d::{e, f}"]
1390 );
1391 }
1392
1393 #[test]
1394 fn test_use_tree_merge_one() {
1395 test_merge!(One, ["a", "b"], ["{a, b}"]);
1396
1397 test_merge!(One, ["a::{aa, ab}", "b", "a"], ["{a::{self, aa, ab}, b}"]);
1398
1399 test_merge!(One, ["a as x", "b as y"], ["{a as x, b as y}"]);
1400
1401 test_merge!(
1402 One,
1403 ["a::{aa as xa, ab}", "b", "a"],
1404 ["{a::{self, aa as xa, ab}, b}"]
1405 );
1406
1407 test_merge!(
1408 One,
1409 ["a", "a::{aa, ab::{aba, abb}}"],
1410 ["a::{self, aa, ab::{aba, abb}}"]
1411 );
1412
1413 test_merge!(One, ["a", "b::{ba, *}"], ["{a, b::{ba, *}}"]);
1414
1415 test_merge!(One, ["a", "b", "a::aa"], ["{a::{self, aa}, b}"]);
1416
1417 test_merge!(
1418 One,
1419 ["a::aa::aaa", "a::ac::aca", "a::aa::*"],
1420 ["a::{aa::{aaa, *}, ac::aca}"]
1421 );
1422
1423 test_merge!(
1424 One,
1425 ["a", "b::{ba, bb}", "a::{aa::*, ab::aba}"],
1426 ["{a::{self, aa::*, ab::aba}, b::{ba, bb}}"]
1427 );
1428
1429 test_merge!(
1430 One,
1431 ["b", "a::ac::{aca, acb}", "a::{aa::*, ab}"],
1432 ["{a::{aa::*, ab, ac::{aca, acb}}, b}"]
1433 );
1434 }
1435
1436 #[test]
1437 fn test_flatten_use_trees() {
1438 assert_eq!(
1439 flatten_use_trees(
1440 parse_use_trees!["foo::{a::{b, c}, d::e}"],
1441 ImportGranularity::Item
1442 ),
1443 parse_use_trees!["foo::a::b", "foo::a::c", "foo::d::e"]
1444 );
1445
1446 assert_eq!(
1447 flatten_use_trees(
1448 parse_use_trees!["foo::{self, a, b::{c, d}, e::*}"],
1449 ImportGranularity::Item
1450 ),
1451 parse_use_trees![
1452 "foo::{self}",
1453 "foo::a",
1454 "foo::b::c",
1455 "foo::b::d",
1456 "foo::e::*"
1457 ]
1458 );
1459 }
1460
1461 #[test]
1462 fn test_use_tree_flatten() {
1463 assert_eq!(
1464 parse_use_tree("a::b::{c, d, e, f}").flatten(ImportGranularity::Item),
1465 parse_use_trees!("a::b::c", "a::b::d", "a::b::e", "a::b::f",)
1466 );
1467
1468 assert_eq!(
1469 parse_use_tree("a::b::{c::{d, e, f}, g, h::{i, j, k}}")
1470 .flatten(ImportGranularity::Item),
1471 parse_use_trees![
1472 "a::b::c::d",
1473 "a::b::c::e",
1474 "a::b::c::f",
1475 "a::b::g",
1476 "a::b::h::i",
1477 "a::b::h::j",
1478 "a::b::h::k",
1479 ]
1480 );
1481 }
1482
1483 #[test]
1484 fn test_use_tree_normalize() {
1485 assert_eq!(parse_use_tree("a::self").normalize(), parse_use_tree("a"));
1486 assert_eq!(
1487 parse_use_tree("a::self as foo").normalize(),
1488 parse_use_tree("a as foo")
1489 );
1490 assert_eq!(
1491 parse_use_tree("a::{self}").normalize(),
1492 parse_use_tree("a::{self}")
1493 );
1494 assert_eq!(parse_use_tree("a::{b}").normalize(), parse_use_tree("a::b"));
1495 assert_eq!(
1496 parse_use_tree("a::{b, c::self}").normalize(),
1497 parse_use_tree("a::{b, c}")
1498 );
1499 assert_eq!(
1500 parse_use_tree("a::{b as bar, c::self}").normalize(),
1501 parse_use_tree("a::{b as bar, c}")
1502 );
1503 }
1504
1505 #[test]
1506 fn test_use_tree_ord() {
1507 assert!(parse_use_tree("a").normalize() < parse_use_tree("aa").normalize());
1508 assert!(parse_use_tree("a").normalize() < parse_use_tree("a::a").normalize());
1509 assert!(parse_use_tree("a").normalize() < parse_use_tree("*").normalize());
1510 assert!(parse_use_tree("a").normalize() < parse_use_tree("{a, b}").normalize());
1511 assert!(parse_use_tree("*").normalize() < parse_use_tree("{a, b}").normalize());
1512
1513 assert!(parse_use_tree("A").normalize() > parse_use_tree("a").normalize());
1514 assert!(parse_use_tree("A").normalize() > parse_use_tree("_b").normalize());
1515 assert!(parse_use_tree("a").normalize() > parse_use_tree("_b").normalize());
1516
1517 assert!(
1518 parse_use_tree("aaaaaaaaaaaaaaa::{bb, cc, dddddddd}").normalize()
1519 < parse_use_tree("aaaaaaaaaaaaaaa::{bb, cc, ddddddddd}").normalize()
1520 );
1521 assert!(
1522 parse_use_tree("serde::de::{Deserialize}").normalize()
1523 < parse_use_tree("serde_json").normalize()
1524 );
1525 assert!(parse_use_tree("a::b::c").normalize() < parse_use_tree("a::b::*").normalize());
1526 assert!(
1527 parse_use_tree("foo::{Bar, Baz}").normalize()
1528 < parse_use_tree("{Bar, Baz}").normalize()
1529 );
1530
1531 assert!(
1532 parse_use_tree("foo::{qux as bar}").normalize()
1533 < parse_use_tree("foo::{self as bar}").normalize()
1534 );
1535 assert!(
1536 parse_use_tree("foo::{qux as bar}").normalize()
1537 < parse_use_tree("foo::{baz, qux as bar}").normalize()
1538 );
1539 assert!(
1540 parse_use_tree("foo::{self as bar, baz}").normalize()
1541 < parse_use_tree("foo::{baz, qux as bar}").normalize()
1542 );
1543
1544 assert!(parse_use_tree("foo").normalize() < parse_use_tree("Foo").normalize());
1545 assert!(parse_use_tree("foo").normalize() < parse_use_tree("foo::Bar").normalize());
1546
1547 assert!(
1548 parse_use_tree("std::cmp::{d, c, b, a}").normalize()
1549 < parse_use_tree("std::cmp::{b, e, g, f}").normalize()
1550 );
1551 }
1552
1553 #[test]
1554 fn test_use_tree_nest_trailing_self() {
1555 assert_eq!(
1556 parse_use_tree("a::b::self").nest_trailing_self(),
1557 parse_use_tree("a::b::{self}")
1558 );
1559 assert_eq!(
1560 parse_use_tree("a::b::c").nest_trailing_self(),
1561 parse_use_tree("a::b::c")
1562 );
1563 assert_eq!(
1564 parse_use_tree("a::b::{c, d}").nest_trailing_self(),
1565 parse_use_tree("a::b::{c, d}")
1566 );
1567 assert_eq!(
1568 parse_use_tree("a::b::{self, c}").nest_trailing_self(),
1569 parse_use_tree("a::b::{self, c}")
1570 );
1571 }
1572}