@@ -57,11 +57,43 @@ impl<'tcx> Clean<'tcx, Item> for DocModule<'tcx> {
57
57
. map ( |( item, renamed) | clean_maybe_renamed_foreign_item ( cx, item, * renamed) ) ,
58
58
) ;
59
59
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
+ } ) ) ;
65
97
66
98
// determine if we should display the inner contents or
67
99
// the outer `mod` item for the source code.
0 commit comments