]> git.lizzy.rs Git - rust.git/blobdiff - src/librustdoc/clean/mod.rs
Rollup merge of #99480 - miam-miam100:arg-format, r=oli-obk
[rust.git] / src / librustdoc / clean / mod.rs
index fa2efb0041621204ab9e77852fdb999217e12bc5..9865601da5fc7f5b9aca672a0accebe0549507d2 100644 (file)
@@ -57,11 +57,43 @@ fn clean(&self, cx: &mut DocContext<'tcx>) -> Item {
                 .map(|(item, renamed)| clean_maybe_renamed_foreign_item(cx, item, *renamed)),
         );
         items.extend(self.mods.iter().map(|x| x.clean(cx)));
-        items.extend(
-            self.items
-                .iter()
-                .flat_map(|(item, renamed)| clean_maybe_renamed_item(cx, item, *renamed)),
-        );
+
+        // Split up imports from all other items.
+        //
+        // This covers the case where somebody does an import which should pull in an item,
+        // but there's already an item with the same namespace and same name. Rust gives
+        // priority to the not-imported one, so we should, too.
+        let mut inserted = FxHashSet::default();
+        items.extend(self.items.iter().flat_map(|(item, renamed)| {
+            // First, lower everything other than imports.
+            if matches!(item.kind, hir::ItemKind::Use(..)) {
+                return Vec::new();
+            }
+            let v = clean_maybe_renamed_item(cx, item, *renamed);
+            for item in &v {
+                if let Some(name) = item.name {
+                    inserted.insert((item.type_(), name));
+                }
+            }
+            v
+        }));
+        items.extend(self.items.iter().flat_map(|(item, renamed)| {
+            // Now we actually lower the imports, skipping everything else.
+            if !matches!(item.kind, hir::ItemKind::Use(..)) {
+                return Vec::new();
+            }
+            let mut v = clean_maybe_renamed_item(cx, item, *renamed);
+            v.drain_filter(|item| {
+                if let Some(name) = item.name {
+                    // If an item with the same type and name already exists,
+                    // it takes priority over the inlined stuff.
+                    !inserted.insert((item.type_(), name))
+                } else {
+                    false
+                }
+            });
+            v
+        }));
 
         // determine if we should display the inner contents or
         // the outer `mod` item for the source code.
@@ -1502,7 +1534,7 @@ fn clean(&self, cx: &mut DocContext<'tcx>) -> Type {
 /// Returns `None` if the type could not be normalized
 fn normalize<'tcx>(cx: &mut DocContext<'tcx>, ty: Ty<'_>) -> Option<Ty<'tcx>> {
     // HACK: low-churn fix for #79459 while we wait for a trait normalization fix
-    if !cx.tcx.sess.opts.debugging_opts.normalize_docs {
+    if !cx.tcx.sess.opts.unstable_opts.normalize_docs {
         return None;
     }
 
@@ -2005,8 +2037,8 @@ fn clean_impl<'tcx>(
             for_,
             items,
             polarity: tcx.impl_polarity(def_id),
-            kind: if utils::has_doc_flag(tcx, def_id.to_def_id(), sym::tuple_variadic) {
-                ImplKind::TupleVaradic
+            kind: if utils::has_doc_flag(tcx, def_id.to_def_id(), sym::fake_variadic) {
+                ImplKind::FakeVaradic
             } else {
                 ImplKind::Normal
             },
@@ -2120,8 +2152,9 @@ fn clean_use_statement<'tcx>(
     // forcefully don't inline if this is not public or if the
     // #[doc(no_inline)] attribute is present.
     // Don't inline doc(hidden) imports so they can be stripped at a later stage.
-    let mut denied = !(visibility.is_public()
-        || (cx.render_options.document_private && is_visible_from_parent_mod))
+    let mut denied = cx.output_format.is_json()
+        || !(visibility.is_public()
+            || (cx.render_options.document_private && is_visible_from_parent_mod))
         || pub_underscore
         || attrs.iter().any(|a| {
             a.has_name(sym::doc)