Skip to content

Commit

Permalink
Rollup merge of #93169 - CraftSpider:rustdoc-clean-inconsistency, r=G…
Browse files Browse the repository at this point in the history
…uillaumeGomez

Fix inconsistency of local blanket impls

When a blanket impl is local, go through HIR instead of middle. This fixes inconsistencies with data detected during JSON generation.

Expected this change to take longer. I also tried doing the whole item through existing clean architecture, but it didn't work out trivially, and felt like it would have added more complexity than it removed.

Properly fixes #83718
  • Loading branch information
matthiaskrgr authored Jan 25, 2022
2 parents 8dddc86 + 9220631 commit 677126c
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 20 deletions.
28 changes: 22 additions & 6 deletions src/librustdoc/clean/blanket_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,27 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {

cx.generated_synthetics.insert((ty, trait_def_id));

let hir_imp = impl_def_id.as_local()
.map(|local| cx.tcx.hir().expect_item(local))
.and_then(|item| if let hir::ItemKind::Impl(i) = &item.kind {
Some(i)
} else {
None
});

let items = match hir_imp {
Some(imp) => imp
.items
.iter()
.map(|ii| cx.tcx.hir().impl_item(ii.id).clean(cx))
.collect::<Vec<_>>(),
None => cx.tcx
.associated_items(impl_def_id)
.in_definition_order()
.map(|x| x.clean(cx))
.collect::<Vec<_>>(),
};

impls.push(Item {
name: None,
attrs: Default::default(),
Expand All @@ -117,12 +138,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
// the post-inference `trait_ref`, as it's more accurate.
trait_: Some(trait_ref.clean(cx)),
for_: ty.clean(cx),
items: cx
.tcx
.associated_items(impl_def_id)
.in_definition_order()
.map(|x| x.clean(cx))
.collect::<Vec<_>>(),
items,
polarity: ty::ImplPolarity::Positive,
kind: ImplKind::Blanket(box trait_ref.self_ty().clean(cx)),
}),
Expand Down
15 changes: 1 addition & 14 deletions src/librustdoc/json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,21 +172,8 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
/// the hashmap because certain items (traits and types) need to have their mappings for trait
/// implementations filled out before they're inserted.
fn item(&mut self, item: clean::Item) -> Result<(), Error> {
let local_blanket_impl = match item.def_id {
clean::ItemId::Blanket { impl_id, .. } => impl_id.is_local(),
clean::ItemId::Auto { .. }
| clean::ItemId::DefId(_)
| clean::ItemId::Primitive(_, _) => false,
};

// Flatten items that recursively store other items
// FIXME(CraftSpider): We skip children of local blanket implementations, as we'll have
// already seen the actual generic impl, and the generated ones don't need documenting.
// This is necessary due to the visibility, return type, and self arg of the generated
// impls not quite matching, and will no longer be necessary when the mismatch is fixed.
if !local_blanket_impl {
item.kind.inner_items().for_each(|i| self.item(i.clone()).unwrap());
}
item.kind.inner_items().for_each(|i| self.item(i.clone()).unwrap());

let id = item.def_id;
if let Some(mut new_item) = self.convert_item(item) {
Expand Down
4 changes: 4 additions & 0 deletions src/test/rustdoc-json/impls/blanket_with_local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@

// @has blanket_with_local.json "$.index[*][?(@.name=='Load')]"
pub trait Load {
// @has - "$.index[*][?(@.name=='load')]"
fn load() {}
// @has - "$.index[*][?(@.name=='write')]"
fn write(self) {}
}

impl<P> Load for P {
fn load() {}
fn write(self) {}
}

// @has - "$.index[*][?(@.name=='Wrapper')]"
Expand Down

0 comments on commit 677126c

Please sign in to comment.