-
Notifications
You must be signed in to change notification settings - Fork 13.3k
rustdoc: handle cross-crate RPITITs correctly #113956
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
Conversation
(rustbot has picked a reviewer for you, use r? to override) |
/// | ||
/// This only considers predicates that reference the impl's generics, and not | ||
/// those that reference the method's generics. | ||
fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefId, DefId)) -> bool { | ||
fn is_impossible_associated_item( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've renamed this since the previous name confused me quite a bit at first, I wasn't sure if the ICE happened due to the RPITIT-method or due to the synthetic RPITIT assoc type. It can handle every kind of associated item just fine (even generic consts I assume) and rustdoc does use the query for every kind already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it used to be used during codegen to skip monomorphizing methods that have impossible to solve predicates, but now it's used for other things.
edit: nvm I was confusing it with another "is impossible" method. Yeah, idk why it was named like that.
fn is_impossible_associated_item( | ||
tcx: TyCtxt<'_>, | ||
(impl_def_id, trait_item_def_id): (DefId, DefId), | ||
) -> bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ofc, we could just defensively check at the start if the assoc item is_impl_trait_in_trait
and if so return false
. Wouldn't be reachable at this point in time but it might be in the future if this query gained more users.
Not really, ideally the GAT that we synthesize for an RPITIT should own all of its non-impl generics. That's a different story though, and is difficult to fix for its own reasons. |
Looks good to me. I'll let @compiler-errors have the final word though. ;) |
@bors r=GuillaumeGomez,compiler-errors |
☀️ Test successful - checks-actions |
Finished benchmarking commit (cb6ab95): comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesThis benchmark run did not return any relevant results for this metric. Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 653.19s -> 653.106s (-0.01%) |
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 fromis_impossible_method
) which cannot handle them (leading to an ICE). I don't think it makes sense to try to makeis_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 anOption<_>
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.Explanation on why
is_impossible_associated_item(itit_assoc_ty)
leads to an ICEGiven the following code:
The generated associated type looks something like (simplified):
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 ifT
is owned by the assoc ty. Unfortunately this doesn't work for ITIT assoc tys. In this case, the parent ofT
isTrait::def
(!) which is the associated function (I'm pretty sure this is very intentional) which is of course not equal to the assoc tyTrait::{opaque#0}
.@rustbot label A-cross-crate-reexports