diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index c823ed0f16efb..d93f0bd4e5657 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -323,6 +323,21 @@ pub(crate) fn build_impls( for &did in tcx.inherent_impls(did).iter() { build_impl(cx, parent_module, did, attrs, ret); } + + // This pretty much exists expressly for `dyn Error` traits that exist in the `alloc` crate. + // See also: + // + // * https://github.com/rust-lang/rust/issues/103170 — where it didn't used to get documented + // * https://github.com/rust-lang/rust/pull/99917 — where the feature got used + // * https://github.com/rust-lang/rust/issues/53487 — overall tracking issue for Error + if tcx.has_attr(did, sym::rustc_has_incoherent_inherent_impls) { + use rustc_middle::ty::fast_reject::SimplifiedTypeGen::*; + let type_ = + if tcx.is_trait(did) { TraitSimplifiedType(did) } else { AdtSimplifiedType(did) }; + for &did in tcx.incoherent_impls(type_) { + build_impl(cx, parent_module, did, attrs, ret); + } + } } /// `parent_module` refers to the parent of the re-export, not the original item diff --git a/src/test/rustdoc/auxiliary/incoherent-impl-types.rs b/src/test/rustdoc/auxiliary/incoherent-impl-types.rs new file mode 100644 index 0000000000000..fc51e42e5004d --- /dev/null +++ b/src/test/rustdoc/auxiliary/incoherent-impl-types.rs @@ -0,0 +1,7 @@ +#![feature(rustc_attrs)] + +#[rustc_has_incoherent_inherent_impls] +pub trait FooTrait {} + +#[rustc_has_incoherent_inherent_impls] +pub struct FooStruct; diff --git a/src/test/rustdoc/rustc-incoherent-impls.rs b/src/test/rustdoc/rustc-incoherent-impls.rs new file mode 100644 index 0000000000000..3fdefbecc5461 --- /dev/null +++ b/src/test/rustdoc/rustc-incoherent-impls.rs @@ -0,0 +1,28 @@ +// aux-build:incoherent-impl-types.rs +// build-aux-docs + +#![crate_name = "foo"] +#![feature(rustc_attrs)] + +extern crate incoherent_impl_types; + +// The only way this actually shows up is if the type gets inlined. +#[doc(inline)] +pub use incoherent_impl_types::FooTrait; + +// @has foo/trait.FooTrait.html +// @count - '//section[@id="method.do_something"]' 1 +impl dyn FooTrait { + #[rustc_allow_incoherent_impl] + pub fn do_something() {} +} + +#[doc(inline)] +pub use incoherent_impl_types::FooStruct; + +// @has foo/struct.FooStruct.html +// @count - '//section[@id="method.do_something"]' 1 +impl FooStruct { + #[rustc_allow_incoherent_impl] + pub fn do_something() {} +}