Prevent duplicated imports

This commit is contained in:
Guillaume Gomez 2023-02-22 17:47:00 +01:00
parent a9dba83f63
commit 4aa142ee2d
2 changed files with 16 additions and 8 deletions

View file

@ -77,7 +77,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
// 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.
items.extend(doc.items.iter().flat_map(|(item, renamed, import_id)| {
items.extend(doc.items.values().flat_map(|(item, renamed, import_id)| {
// First, lower everything other than imports.
if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
return Vec::new();
@ -90,7 +90,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
}
v
}));
items.extend(doc.items.iter().flat_map(|(item, renamed, _)| {
items.extend(doc.items.values().flat_map(|(item, renamed, _)| {
// Now we actually lower the imports, skipping everything else.
if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind {
let name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id()));

View file

@ -1,7 +1,7 @@
//! The Rust AST Visitor. Extracts useful information and massages it into a form
//! usable for `clean`.
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LocalDefIdSet};
@ -26,8 +26,12 @@ pub(crate) struct Module<'hir> {
pub(crate) where_inner: Span,
pub(crate) mods: Vec<Module<'hir>>,
pub(crate) def_id: LocalDefId,
// (item, renamed, import_id)
pub(crate) items: Vec<(&'hir hir::Item<'hir>, Option<Symbol>, Option<LocalDefId>)>,
/// The key is the item `ItemId` and the value is: (item, renamed, import_id).
/// We use `FxIndexMap` to keep the insert order.
pub(crate) items: FxIndexMap<
(LocalDefId, Option<Symbol>),
(&'hir hir::Item<'hir>, Option<Symbol>, Option<LocalDefId>),
>,
pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option<Symbol>)>,
}
@ -38,7 +42,7 @@ impl Module<'_> {
def_id,
where_inner,
mods: Vec::new(),
items: Vec::new(),
items: FxIndexMap::default(),
foreigns: Vec::new(),
}
}
@ -136,7 +140,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
inserted.insert(def_id)
{
let item = self.cx.tcx.hir().expect_item(local_def_id);
top_level_module.items.push((item, None, None));
top_level_module.items.insert((local_def_id, Some(item.ident.name)), (item, None, None));
}
}
@ -294,7 +298,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
renamed: Option<Symbol>,
parent_id: Option<LocalDefId>,
) {
self.modules.last_mut().unwrap().items.push((item, renamed, parent_id))
self.modules
.last_mut()
.unwrap()
.items
.insert((item.owner_id.def_id, renamed), (item, renamed, parent_id));
}
fn visit_item_inner(