-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #113956 - fmease:rustdoc-fix-x-crate-rpitits, r=Guillau…
…meGomez,compiler-errors rustdoc: handle cross-crate RPITITs correctly Filter out the internal associated types synthesized during the desugaring of RPITITs, they really shouldn't show up in the docs. This also fixes #113929 since we're no longer invoking `is_impossible_associated_item` (renamed from `is_impossible_method`) which cannot handle them (leading to an ICE). I don't think it makes sense to try to make `is_impossible_associated_item` handle this exotic kind of associated type (CC original author `@compiler-errors).` @ T-rustdoc reviewers, currently I'm throwing out ITIT assoc tys before cleaning assoc tys at each usage-site. I'm thinking about making `clean_middle_assoc_item` return an `Option<_>` instead and doing the check inside of it to prevent any call sites from forgetting the check for ITITs. Since I wasn't sure if you would like that approach, I didn't go through with it. Let me know what you think. <details><summary>Explanation on why <code>is_impossible_associated_item(itit_assoc_ty)</code> leads to an ICE</summary> Given the following code: ```rs pub trait Trait { fn def<T>() -> impl Default {} } impl Trait for () {} ``` The generated associated type looks something like (simplified): ```rs type {opaque#0}<T>: Default = impl Default; // the name is actually `kw::Empty` but this is the `def_path_str` repr ``` The query `is_impossible_associated_item` goes through all predicates of the associated item – in this case `<T as Sized>` – to check if they contain any generic parameters from the (generic) associated type itself. For predicates that don't contain any *own* generics, it does further processing, part of which is instantiating the predicate with the generic arguments of the impl block (which is only correct if they truly don't contain any own generics since they wouldn't get instantiated this way leading to an ICE). It checks if `parent_def_id(T) == assoc_ty_def_id` to get to know if `T` is owned by the assoc ty. Unfortunately this doesn't work for ITIT assoc tys. In this case, the parent of `T` is `Trait::def` (!) which is the associated function (I'm pretty sure this is very intentional) which is of course not equal to the assoc ty `Trait::{opaque#0}`. </details> `@rustbot` label A-cross-crate-reexports
- Loading branch information
Showing
7 changed files
with
84 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
tests/rustdoc/inline_cross/auxiliary/ret-pos-impl-trait-in-trait.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#![feature(return_position_impl_trait_in_trait)] | ||
|
||
pub trait Trait { | ||
fn create() -> impl Iterator<Item = u64> { | ||
std::iter::empty() | ||
} | ||
} | ||
|
||
pub struct Basic; | ||
pub struct Intermediate; | ||
pub struct Advanced; | ||
|
||
impl Trait for Basic { | ||
// method provided by the trait | ||
} | ||
|
||
impl Trait for Intermediate { | ||
fn create() -> std::ops::Range<u64> { // concrete return type | ||
0..1 | ||
} | ||
} | ||
|
||
impl Trait for Advanced { | ||
fn create() -> impl Iterator<Item = u64> { // opaque return type | ||
std::iter::repeat(0) | ||
} | ||
} | ||
|
||
// Regression test for issue #113929: | ||
|
||
pub trait Def { | ||
fn def<T>() -> impl Default {} | ||
} | ||
|
||
impl Def for () {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#![crate_name = "user"] | ||
// aux-crate:rpitit=ret-pos-impl-trait-in-trait.rs | ||
// edition:2021 | ||
|
||
// Test that we can correctly render cross-crate RPITITs. | ||
// In particular, check that we don't render the internal associated type generated by | ||
// their desugaring. We count the number of associated items and ensure that it is exactly one. | ||
// This is more robust than checking for the absence of the associated type. | ||
|
||
// @has user/trait.Trait.html | ||
// @has - '//*[@id="method.create"]' 'fn create() -> impl Iterator<Item = u64>' | ||
// The class "method" is used for all three kinds of associated items at the time of writing. | ||
// @count - '//*[@id="main-content"]//section[@class="method"]' 1 | ||
pub use rpitit::Trait; | ||
|
||
// @has user/struct.Basic.html | ||
// @has - '//*[@id="method.create"]' 'fn create() -> impl Iterator<Item = u64>' | ||
// @count - '//*[@id="trait-implementations-list"]//*[@class="impl-items"]' 1 | ||
pub use rpitit::Basic; | ||
|
||
// @has user/struct.Intermediate.html | ||
// @has - '//*[@id="method.create"]' 'fn create() -> Range<u64>' | ||
// @count - '//*[@id="trait-implementations-list"]//*[@class="impl-items"]' 1 | ||
pub use rpitit::Intermediate; | ||
|
||
// @has user/struct.Advanced.html | ||
// @has - '//*[@id="method.create"]' 'fn create() -> impl Iterator<Item = u64>' | ||
// @count - '//*[@id="trait-implementations-list"]//*[@class="impl-items"]' 1 | ||
pub use rpitit::Advanced; | ||
|
||
// Regression test for issue #113929: | ||
|
||
// @has user/trait.Def.html | ||
// @has - '//*[@id="method.def"]' 'fn def<T>() -> impl Default' | ||
pub use rpitit::Def; |