@@ -57,11 +57,43 @@ impl<'tcx> Clean<'tcx, Item> for DocModule<'tcx> {
5757 . map ( |( item, renamed) | clean_maybe_renamed_foreign_item ( cx, item, * renamed) ) ,
5858 ) ;
5959 items. extend ( self . mods . iter ( ) . map ( |x| x. clean ( cx) ) ) ;
60- items. extend (
61- self . items
62- . iter ( )
63- . flat_map ( |( item, renamed) | clean_maybe_renamed_item ( cx, item, * renamed) ) ,
64- ) ;
60+
61+ // Split up imports from all other items.
62+ //
63+ // This covers the case where somebody does an import which should pull in an item,
64+ // but there's already an item with the same namespace and same name. Rust gives
65+ // priority to the not-imported one, so we should, too.
66+ let mut inserted = FxHashSet :: default ( ) ;
67+ items. extend ( self . items . iter ( ) . flat_map ( |( item, renamed) | {
68+ // First, lower everything other than imports.
69+ if matches ! ( item. kind, hir:: ItemKind :: Use ( ..) ) {
70+ return Vec :: new ( ) ;
71+ }
72+ let v = clean_maybe_renamed_item ( cx, item, * renamed) ;
73+ for item in & v {
74+ if let Some ( name) = item. name {
75+ inserted. insert ( ( item. type_ ( ) , name) ) ;
76+ }
77+ }
78+ v
79+ } ) ) ;
80+ items. extend ( self . items . iter ( ) . flat_map ( |( item, renamed) | {
81+ // Now we actually lower the imports, skipping everything else.
82+ if !matches ! ( item. kind, hir:: ItemKind :: Use ( ..) ) {
83+ return Vec :: new ( ) ;
84+ }
85+ let mut v = clean_maybe_renamed_item ( cx, item, * renamed) ;
86+ v. drain_filter ( |item| {
87+ if let Some ( name) = item. name {
88+ // If an item with the same type and name already exists,
89+ // it takes priority over the inlined stuff.
90+ !inserted. insert ( ( item. type_ ( ) , name) )
91+ } else {
92+ false
93+ }
94+ } ) ;
95+ v
96+ } ) ) ;
6597
6698 // determine if we should display the inner contents or
6799 // the outer `mod` item for the source code.
0 commit comments