1- use std:: borrow:: Cow ;
21use std:: cmp:: Ordering ;
32use std:: fmt;
3+ use std:: { borrow:: Cow , vec} ;
44
55use core:: hash:: { Hash , Hasher } ;
66
@@ -130,7 +130,7 @@ pub(crate) struct UseTree {
130130
131131impl PartialEq for UseTree {
132132 fn eq ( & self , other : & UseTree ) -> bool {
133- self . path == other. path
133+ self . path == other. path && ! self . has_attrs ( ) && !other . has_attrs ( )
134134 }
135135}
136136impl Eq for UseTree { }
@@ -233,13 +233,19 @@ pub(crate) fn normalize_use_trees_with_granularity(
233233
234234 let mut result = Vec :: with_capacity ( use_trees. len ( ) ) ;
235235 for use_tree in use_trees {
236- if use_tree. contains_comment ( ) || use_tree. attrs . is_some ( ) {
236+ if use_tree. contains_comment ( ) || use_tree. has_attrs_disallow_outer_style ( ) {
237237 result. push ( use_tree) ;
238238 continue ;
239239 }
240+ let attrs = use_tree. attrs . clone ( ) ;
241+ let result_buf = if attrs. is_some ( ) {
242+ & mut vec ! [ ]
243+ } else {
244+ & mut result
245+ } ;
240246
241247 for mut flattened in use_tree. flatten ( import_granularity) {
242- if let Some ( tree) = result
248+ if let Some ( tree) = result_buf
243249 . iter_mut ( )
244250 . find ( |tree| tree. share_prefix ( & flattened, merge_by) )
245251 {
@@ -249,9 +255,19 @@ pub(crate) fn normalize_use_trees_with_granularity(
249255 if merge_by == SharedPrefix :: Module {
250256 flattened = flattened. nest_trailing_self ( ) ;
251257 }
252- result . push ( flattened) ;
258+ result_buf . push ( flattened) ;
253259 }
254260 }
261+ if let Some ( attrs) = attrs {
262+ let result_buf: Vec < _ > = result_buf
263+ . drain ( ..)
264+ . map ( |mut use_tree| {
265+ use_tree. attrs = Some ( attrs. clone ( ) ) ;
266+ use_tree
267+ } )
268+ . collect ( ) ;
269+ result. extend ( result_buf) ;
270+ }
255271 }
256272 result
257273}
@@ -559,7 +575,7 @@ impl UseTree {
559575
560576 // Remove foo::{} or self without attributes.
561577 match last. kind {
562- _ if self . attrs . is_some ( ) => ( ) ,
578+ _ if self . has_attrs ( ) => ( ) ,
563579 UseSegmentKind :: List ( ref list) if list. is_empty ( ) => {
564580 self . path = vec ! [ ] ;
565581 return self ;
@@ -657,6 +673,17 @@ impl UseTree {
657673 self . has_comment ( ) || self . path . iter ( ) . any ( |path| path. contains_comment ( ) )
658674 }
659675
676+ fn has_attrs ( & self ) -> bool {
677+ self . attrs . is_some ( )
678+ }
679+
680+ fn has_attrs_disallow_outer_style ( & self ) -> bool {
681+ !self . attrs . iter ( ) . flatten ( ) . all ( |attr| match & attr. kind {
682+ ast:: AttrKind :: Normal ( attr) => attr. item . is_valid_for_outer_style ( ) ,
683+ ast:: AttrKind :: DocComment ( ..) => false ,
684+ } )
685+ }
686+
660687 fn same_visibility ( & self , other : & UseTree ) -> bool {
661688 match ( & self . visibility , & other. visibility ) {
662689 (
@@ -682,7 +709,8 @@ impl UseTree {
682709 fn share_prefix ( & self , other : & UseTree , shared_prefix : SharedPrefix ) -> bool {
683710 if self . path . is_empty ( )
684711 || other. path . is_empty ( )
685- || self . attrs . is_some ( )
712+ || self . has_attrs ( )
713+ || other. has_attrs ( )
686714 || self . contains_comment ( )
687715 || !self . same_visibility ( other)
688716 {
@@ -697,7 +725,8 @@ impl UseTree {
697725 }
698726
699727 fn flatten ( self , import_granularity : ImportGranularity ) -> Vec < UseTree > {
700- if self . path . is_empty ( ) || self . contains_comment ( ) {
728+ if self . path . is_empty ( ) || self . contains_comment ( ) || self . has_attrs_disallow_outer_style ( )
729+ {
701730 return vec ! [ self ] ;
702731 }
703732 match & self . path . clone ( ) . last ( ) . unwrap ( ) . kind {
0 commit comments