[rustdoc] Improve "in parameters" search and search more generally#59004
[rustdoc] Improve "in parameters" search and search more generally#59004bors merged 7 commits intorust-lang:masterfrom
Conversation
|
Some changes occurred in HTML/CSS. |
|
(rust_highfive has picked a reviewer for you, use r? to override) |
37bcbce to
6efbcaa
Compare
|
ping from triage @QuietMisdreavus waiting for your review on this |
QuietMisdreavus
left a comment
There was a problem hiding this comment.
Looks good, just a couple small comments. This may clash with #59170 whenever that lands.
src/librustdoc/clean/mod.rs
Outdated
There was a problem hiding this comment.
Can you write doc comments for the functions you added? For example, this could be something like "Extract the types from a function's parameters and generics" with maybe a note about trait bounds since you've already added the comment for it.
src/librustdoc/clean/mod.rs
Outdated
There was a problem hiding this comment.
If you use a BTreeSet instead, it comes pre-sorted - otherwise it comes out in an arbitrary order. I'm not sure if you wanted it to be properly sorted or just deduplicated, though.
There was a problem hiding this comment.
Dedup, the order doesn't matter. ;)
src/librustdoc/clean/mod.rs
Outdated
There was a problem hiding this comment.
You can replace this loop with res.extend(adds), since the sets implement the Extend trait.
|
☔ The latest upstream changes (presumably #58927) made this pull request unmergeable. Please resolve the merge conflicts. |
6efbcaa to
befe9ca
Compare
|
@QuietMisdreavus I applied your comments. |
QuietMisdreavus
left a comment
There was a problem hiding this comment.
Excellent, thanks for doing this! This will make the in-doc search much more powerful.
|
@bors r+ |
|
📌 Commit befe9ca has been approved by |
…=QuietMisdreavus [rustdoc] Improve "in parameters" search and search more generally Fixes rust-lang#58230. r? @QuietMisdreavus
Rollup of 7 pull requests Successful merges: - #59004 ([rustdoc] Improve "in parameters" search and search more generally) - #59026 (Fix moving text in search tabs headers) - #59197 (Exclude old book redirect stubs from search engines) - #59330 (Improve the documentation for std::convert (From, Into, AsRef and AsMut)) - #59424 (Fix code block display in portability element in dark theme) - #59427 (Link to PhantomData in NonNull documentation) - #59432 (Improve some compiletest documentation) Failed merges: r? @ghost
Rollup of 7 pull requests Successful merges: - #59004 ([rustdoc] Improve "in parameters" search and search more generally) - #59026 (Fix moving text in search tabs headers) - #59197 (Exclude old book redirect stubs from search engines) - #59330 (Improve the documentation for std::convert (From, Into, AsRef and AsMut)) - #59424 (Fix code block display in portability element in dark theme) - #59427 (Link to PhantomData in NonNull documentation) - #59432 (Improve some compiletest documentation) Failed merges: r? @ghost
|
@GuillaumeGomez @QuietMisdreavus Please do not merge PRs that change the compiler (in this case, typeck) without a review from @rust-lang/compiler. |
| pub fn get_type(&self, cx: &DocContext<'_>) -> Option<Type> { | ||
| match *self { | ||
| GenericParamDefKind::Type { did, .. } => { | ||
| rustc_typeck::checked_type_of(cx.tcx, did, false).map(|t| t.clean(cx)) |
There was a problem hiding this comment.
You didn't have to do any of the typeck changes, the default is already there:
GenericParamDefKind::Type { ref default, .. } => default.clone(),|
|
||
| /// The point of this function is to replace bounds with types. | ||
| /// | ||
| /// i.e. `[T, U]` when you have the following bounds: `T: Display, U: Option<T>` will return |
There was a problem hiding this comment.
Option<T> is not a bound... how does this make sense?
There was a problem hiding this comment.
The point is to replace T by the type/trait if any. For example:
fn<T>(x: T)
where T: Display
In there, T should be replaced with Display. In here, it's all about the rustdoc search, not about finding exact types. If we have two types with the same name, we don't care, we just remove one name from the list and that's it.
There was a problem hiding this comment.
Sure, but you can get the desired effect without using confusing terminology.
So what you want is "types of arguments" and "bounds on parameters in those arguments"?
Why bother with that complication tho? Why not just record all paths in a signature, be it args/return, or bounds/where clauses? Getting all that is less work and much easier to reason about.
|
|
||
| pub fn is_full_generic(&self) -> bool { | ||
| match *self { | ||
| Type::Generic(_) => true, |
There was a problem hiding this comment.
This should be called Param or GenericParam.
| } | ||
| } | ||
|
|
||
| pub fn is_full_generic(&self) -> bool { |
There was a problem hiding this comment.
This should be called is_param or is_generic_param.
| /// wrapped types in here). | ||
| fn get_real_types( | ||
| generics: &Generics, | ||
| arg: &Type, |
There was a problem hiding this comment.
This should probably be called ty?
| continue | ||
| } | ||
| if let Some(ty) = x.get_type(cx) { | ||
| let adds = get_real_types(generics, &ty, cx); |
There was a problem hiding this comment.
This is unguarded recursion, can easily become infinite, probably the cause of #59502.
| }) { | ||
| for bound in bound.get_bounds().unwrap_or_else(|| &[]) { | ||
| if let Some(ty) = bound.get_trait_type() { | ||
| let adds = get_real_types(generics, &ty, cx); |
| if let Some(gens) = arg.generics() { | ||
| for gen in gens.iter() { | ||
| if gen.is_full_generic() { | ||
| let adds = get_real_types(generics, gen, cx); |
| /// Return the full list of types when bounds have been resolved. | ||
| /// | ||
| /// i.e. `fn foo<A: Display, B: Option<A>>(x: u32, y: B)` will return | ||
| /// `[u32, Display, Option]`. |
There was a problem hiding this comment.
Same here, Option<A> is not a bound.
| } | ||
| } | ||
| } | ||
| if let Some(bound) = generics.params.iter().find(|g| { |
There was a problem hiding this comment.
bound here seems to be a misnomer, this is a param.
There was a problem hiding this comment.
IMO this should be above the where handling above, doing it this way is far more confusing.
| } | ||
| } | ||
| if let Some(bound) = generics.params.iter().find(|g| { | ||
| g.is_type() && g.name == arg_s |
There was a problem hiding this comment.
Why is this by name instead of by DefId?
There was a problem hiding this comment.
I don't care about DefId in here, I only care about names. Don't forget it's to generate rustdoc search array. I'm not looking for a given type but for a given type name.
There was a problem hiding this comment.
You're searching for a type parameter though, not a struct/enum.
And you implemented the other search for type parameters by DefId, so it's inconsistent.
| let adds = get_real_types(generics, &ty, cx); | ||
| if !adds.is_empty() { | ||
| res.extend(adds); | ||
| } else if !ty.is_full_generic() { |
There was a problem hiding this comment.
ty is a trait, not a type, so is_full_generic() should never be the case.
| /// i.e. `[T, U]` when you have the following bounds: `T: Display, U: Option<T>` will return | ||
| /// `[Display, Option]` (we just returns the list of the types, we don't care about the | ||
| /// wrapped types in here). | ||
| fn get_real_types( |
There was a problem hiding this comment.
This name should be find_concrete_types, or, even better, find_type_paths.
| res.insert(arg.clone()); | ||
| if let Some(gens) = arg.generics() { | ||
| for gen in gens.iter() { | ||
| if gen.is_full_generic() { |
There was a problem hiding this comment.
So this means that get_real_types(Option<T>) will look at T's bounds... why?
| if !adds.is_empty() { | ||
| res.extend(adds); | ||
| } else if !ty.is_full_generic() { | ||
| res.insert(ty.clone()); |
There was a problem hiding this comment.
ty is a trait, so your returned set contains both types and traits?
| @@ -1084,9 +1084,10 @@ impl GenericBound { | |||
|
|
|||
| fn get_trait_type(&self) -> Option<Type> { | |||
There was a problem hiding this comment.
The existence of a trait path as a value of Type was a mistake, IMO.
If you move DefId into Path, you can replace trait_: Type with path: Path in:
rust/src/librustdoc/clean/mod.rs
Lines 2428 to 2431 in 237bf32
and this (and other places) with
PolyTrait { path, generic_params: late_bounds }:rust/src/librustdoc/clean/mod.rs
Lines 1196 to 1201 in 237bf32
Wait, Path has a Def which contains a DefId:
rust/src/librustdoc/clean/mod.rs
Lines 3421 to 3425 in 237bf32
So Type::ResolvedPath's DefId is just redundant?!
There was a problem hiding this comment.
Oh, you'd need this to take a Def, too (which can replace trait_did):
rust/src/librustdoc/clean/mod.rs
Lines 1153 to 1154 in 237bf32
|
Opened #59789. |
Revert two unapproved changes to rustc_typeck. There was a breakdown in process (#59004 (comment), #58894 (comment)) and two changes were made to `rustc_typeck`'s "collect" queries, for rustdoc, that were neither needed *nor* correct. I'm reverting them here, and will fix up rustdoc *somehow*, if necessary. cc @rust-lang/compiler How do we ensure this doesn't happen again? r? @nikomatsakis or @oli-obk
Revert two unapproved changes to rustc_typeck. There was a breakdown in process (rust-lang#59004 (comment), rust-lang#58894 (comment)) and two changes were made to `rustc_typeck`'s "collect" queries, for rustdoc, that were neither needed *nor* correct. I'm reverting them here, and will fix up rustdoc *somehow*, if necessary. cc @rust-lang/compiler How do we ensure this doesn't happen again? r? @nikomatsakis or @oli-obk
Fixes #58230.
r? @QuietMisdreavus