Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustdoc: add support for incoherent impls on structs and traits #103746

Merged
merged 1 commit into from
Oct 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then the issue will remain for the JSON output if we fix it in inline, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only a problem in the HTML output because, if inlining isn’t performed, there’s nowhere to actually show it. JSON directly represents impl blocks as their own item, rather than attaching them to their types, so all it needs to do is not strip them out.

If there’s a problem in JSON output, the solution is going to be totally different and should probably be a separate PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense! So no need for it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably still want to add a test case for JSON output on incoherent impl, but, again, separate PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, totally fine.

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
Expand Down
7 changes: 7 additions & 0 deletions src/test/rustdoc/auxiliary/incoherent-impl-types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#![feature(rustc_attrs)]

#[rustc_has_incoherent_inherent_impls]
pub trait FooTrait {}

#[rustc_has_incoherent_inherent_impls]
pub struct FooStruct;
28 changes: 28 additions & 0 deletions src/test/rustdoc/rustc-incoherent-impls.rs
Original file line number Diff line number Diff line change
@@ -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() {}
}