Skip to content

Commit

Permalink
Rollup merge of rust-lang#93169 - CraftSpider:rustdoc-clean-inconsist…
Browse files Browse the repository at this point in the history
…ency, r=GuillaumeGomez

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 rust-lang#83718
  • Loading branch information
matthiaskrgr authored Jan 25, 2022
2 parents 8346977 + 9220631 commit fa16356
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 fa16356

Please sign in to comment.