Rollup merge of #98053 - GuillaumeGomez:fix-generic-impl-json-ice, r=notriddle
Fix generic impl rustdoc json output Fixes #97986. The problem in case of generic trait impl is that the trait's items are the same for all the types afterward. But since they're the same, it's safe for rustdoc-json to just ignore them. A little representation of what's going on: ```rust trait T { fn f(); // <- defid 0 } impl<Y> T for Y { fn f() {} // <- defid 1 } struct S; // <- defid 1 (since it matches `impl<Y> T for Y` ``` cc ```@Urgau``` r? ```@CraftSpider```
This commit is contained in:
commit
4ee78a686f
src
@ -181,15 +181,44 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
||||
let name = item.name;
|
||||
let item_id = item.item_id;
|
||||
if let Some(mut new_item) = self.convert_item(item) {
|
||||
if let types::ItemEnum::Trait(ref mut t) = new_item.inner {
|
||||
t.implementations = self.get_trait_implementors(item_id.expect_def_id())
|
||||
} else if let types::ItemEnum::Struct(ref mut s) = new_item.inner {
|
||||
s.impls = self.get_impls(item_id.expect_def_id())
|
||||
} else if let types::ItemEnum::Enum(ref mut e) = new_item.inner {
|
||||
e.impls = self.get_impls(item_id.expect_def_id())
|
||||
} else if let types::ItemEnum::Union(ref mut u) = new_item.inner {
|
||||
u.impls = self.get_impls(item_id.expect_def_id())
|
||||
}
|
||||
let can_be_ignored = match new_item.inner {
|
||||
types::ItemEnum::Trait(ref mut t) => {
|
||||
t.implementations = self.get_trait_implementors(item_id.expect_def_id());
|
||||
false
|
||||
}
|
||||
types::ItemEnum::Struct(ref mut s) => {
|
||||
s.impls = self.get_impls(item_id.expect_def_id());
|
||||
false
|
||||
}
|
||||
types::ItemEnum::Enum(ref mut e) => {
|
||||
e.impls = self.get_impls(item_id.expect_def_id());
|
||||
false
|
||||
}
|
||||
types::ItemEnum::Union(ref mut u) => {
|
||||
u.impls = self.get_impls(item_id.expect_def_id());
|
||||
false
|
||||
}
|
||||
|
||||
types::ItemEnum::Method(_)
|
||||
| types::ItemEnum::AssocConst { .. }
|
||||
| types::ItemEnum::AssocType { .. } => true,
|
||||
types::ItemEnum::Module(_)
|
||||
| types::ItemEnum::ExternCrate { .. }
|
||||
| types::ItemEnum::Import(_)
|
||||
| types::ItemEnum::StructField(_)
|
||||
| types::ItemEnum::Variant(_)
|
||||
| types::ItemEnum::Function(_)
|
||||
| types::ItemEnum::TraitAlias(_)
|
||||
| types::ItemEnum::Impl(_)
|
||||
| types::ItemEnum::Typedef(_)
|
||||
| types::ItemEnum::OpaqueTy(_)
|
||||
| types::ItemEnum::Constant(_)
|
||||
| types::ItemEnum::Static(_)
|
||||
| types::ItemEnum::ForeignType
|
||||
| types::ItemEnum::Macro(_)
|
||||
| types::ItemEnum::ProcMacro(_)
|
||||
| types::ItemEnum::PrimitiveType(_) => false,
|
||||
};
|
||||
let removed = self
|
||||
.index
|
||||
.borrow_mut()
|
||||
@ -199,7 +228,11 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
||||
// to make sure the items are unique. The main place this happens is when an item, is
|
||||
// reexported in more than one place. See `rustdoc-json/reexport/in_root_and_mod`
|
||||
if let Some(old_item) = removed {
|
||||
assert_eq!(old_item, new_item);
|
||||
// In case of generic implementations (like `impl<T> Trait for T {}`), all the
|
||||
// inner items will be duplicated so we can ignore if they are slightly different.
|
||||
if !can_be_ignored {
|
||||
assert_eq!(old_item, new_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
24
src/test/rustdoc-json/generic_impl.rs
Normal file
24
src/test/rustdoc-json/generic_impl.rs
Normal file
@ -0,0 +1,24 @@
|
||||
// Regression test for <https://github.com/rust-lang/rust/issues/97986>.
|
||||
|
||||
// @has generic_impl.json
|
||||
// @has - "$.index[*][?(@.name=='f')]"
|
||||
// @has - "$.index[*][?(@.name=='AssocTy')]"
|
||||
// @has - "$.index[*][?(@.name=='AssocConst')]"
|
||||
|
||||
pub mod m {
|
||||
pub struct S;
|
||||
}
|
||||
|
||||
pub trait F {
|
||||
type AssocTy;
|
||||
const AssocConst: usize;
|
||||
fn f() -> m::S;
|
||||
}
|
||||
|
||||
impl<T> F for T {
|
||||
type AssocTy = u32;
|
||||
const AssocConst: usize = 0;
|
||||
fn f() -> m::S {
|
||||
m::S
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user