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
@@ -123,7 +123,7 @@ pub(crate) struct UseTree {
123123
124124impl PartialEq for UseTree {
125125 fn eq ( & self , other : & UseTree ) -> bool {
126- self . path == other. path
126+ self . path == other. path && ! self . has_attrs ( ) && !other . has_attrs ( )
127127 }
128128}
129129impl Eq for UseTree { }
@@ -226,13 +226,19 @@ pub(crate) fn normalize_use_trees_with_granularity(
226226
227227 let mut result = Vec :: with_capacity ( use_trees. len ( ) ) ;
228228 for use_tree in use_trees {
229- if use_tree. contains_comment ( ) || use_tree. attrs . is_some ( ) {
229+ if use_tree. contains_comment ( ) || use_tree. has_attrs_disallow_outer_style ( ) {
230230 result. push ( use_tree) ;
231231 continue ;
232232 }
233+ let attrs = use_tree. attrs . clone ( ) ;
234+ let result_buf = if attrs. is_some ( ) {
235+ & mut vec ! [ ]
236+ } else {
237+ & mut result
238+ } ;
233239
234240 for mut flattened in use_tree. flatten ( import_granularity) {
235- if let Some ( tree) = result
241+ if let Some ( tree) = result_buf
236242 . iter_mut ( )
237243 . find ( |tree| tree. share_prefix ( & flattened, merge_by) )
238244 {
@@ -242,9 +248,19 @@ pub(crate) fn normalize_use_trees_with_granularity(
242248 if merge_by == SharedPrefix :: Module {
243249 flattened = flattened. nest_trailing_self ( ) ;
244250 }
245- result . push ( flattened) ;
251+ result_buf . push ( flattened) ;
246252 }
247253 }
254+ if let Some ( attrs) = attrs {
255+ let result_buf: Vec < _ > = result_buf
256+ . drain ( ..)
257+ . map ( |mut use_tree| {
258+ use_tree. attrs = Some ( attrs. clone ( ) ) ;
259+ use_tree
260+ } )
261+ . collect ( ) ;
262+ result. extend ( result_buf) ;
263+ }
248264 }
249265 result
250266}
@@ -552,7 +568,7 @@ impl UseTree {
552568
553569 // Remove foo::{} or self without attributes.
554570 match last. kind {
555- _ if self . attrs . is_some ( ) => ( ) ,
571+ _ if self . has_attrs ( ) => ( ) ,
556572 UseSegmentKind :: List ( ref list) if list. is_empty ( ) => {
557573 self . path = vec ! [ ] ;
558574 return self ;
@@ -650,6 +666,17 @@ impl UseTree {
650666 self . has_comment ( ) || self . path . iter ( ) . any ( |path| path. contains_comment ( ) )
651667 }
652668
669+ fn has_attrs ( & self ) -> bool {
670+ self . attrs . is_some ( )
671+ }
672+
673+ fn has_attrs_disallow_outer_style ( & self ) -> bool {
674+ !self . attrs . iter ( ) . flatten ( ) . all ( |attr| match & attr. kind {
675+ ast:: AttrKind :: Normal ( attr) => attr. item . is_valid_for_outer_style ( ) ,
676+ ast:: AttrKind :: DocComment ( ..) => false ,
677+ } )
678+ }
679+
653680 fn same_visibility ( & self , other : & UseTree ) -> bool {
654681 match ( & self . visibility , & other. visibility ) {
655682 (
@@ -675,7 +702,8 @@ impl UseTree {
675702 fn share_prefix ( & self , other : & UseTree , shared_prefix : SharedPrefix ) -> bool {
676703 if self . path . is_empty ( )
677704 || other. path . is_empty ( )
678- || self . attrs . is_some ( )
705+ || self . has_attrs ( )
706+ || other. has_attrs ( )
679707 || self . contains_comment ( )
680708 || !self . same_visibility ( other)
681709 {
@@ -692,7 +720,8 @@ impl UseTree {
692720 }
693721
694722 fn flatten ( self , import_granularity : ImportGranularity ) -> Vec < UseTree > {
695- if self . path . is_empty ( ) || self . contains_comment ( ) {
723+ if self . path . is_empty ( ) || self . contains_comment ( ) || self . has_attrs_disallow_outer_style ( )
724+ {
696725 return vec ! [ self ] ;
697726 }
698727 match & self . path . clone ( ) . last ( ) . unwrap ( ) . kind {
0 commit comments