X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustdoc%2Fclean%2Fmod.rs;h=9865601da5fc7f5b9aca672a0accebe0549507d2;hb=9e197b75f0e5ad17dc1bb1431853bd4df7cff408;hp=fa2efb0041621204ab9e77852fdb999217e12bc5;hpb=103b8602b7e3cfc8301ab9e0981563bde3789ea7;p=rust.git diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index fa2efb00416..9865601da5f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -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> { // 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)