-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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: Fix handling of Self
type in search index and refactor its representation
#128471
Conversation
// FIXME: add dedicated variant to json Type? | ||
SelfTy => Type::Generic("Self".to_owned()), |
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.
cc @aDotInTheVoid -- what would you like to do here?
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.
This is fine for now as it preserves the existing behavior, but yeah this should almost certainly be changed in a future PR
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.
after some discussion with @compiler-errors, i’m not sure the current json behaviour is wrong. but either way, this is fine for this PR
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.
Yes, technically speaking Self
is either an alias (in the case of concrete impls) or a type parameter (in the case of traits). So what we're doing here in Rustdoc is more of a convenience for how users perceive Self
, rather than how the compiler does.
I highly recommend reviewing commit-by-commit. The diff for the whole PR looks larger than it really is since in one commit I replaced a long sequence of |
trait_: Some(trait_), | ||
.. | ||
}), | ||
bounds, | ||
.. | ||
} => !(bounds.is_empty() || *s == kw::SelfUpper && trait_.def_id() == trait_did), | ||
} => !bounds.is_empty() && trait_.def_id() != trait_did, |
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.
Just an application of De Morgan rules combined with knowing that clean::Generic(kw::SelfUpper)
is gone now.
Please add a test case in |
Done, let me know if it looks correct. |
@rfcbot poll rustdoc-frontend |
Team member @camelid has asked teams: T-rustdoc-frontend, for consensus on: |
@@ -468,7 +468,7 @@ pub(crate) fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type { | |||
match path.res { | |||
Res::PrimTy(p) => Primitive(PrimitiveType::from(p)), | |||
Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } if path.segments.len() == 1 => { |
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 don't believe that the handling of SelfTyAlias
is correct here 🤔 Or at least I do want to point out that SelfTyParam
and SelfTyAlias
act differently and should probably not continue to be conflated.
SelfTyAlias
is used for the self type of an impl; this is not some abstract Self
(which is literally just parameter -- unrelated, but I'm not sure why this PR moves away from representing self as a parameter when it is one in trait
, but I digress) -- SelfTyAlias
instead refers to a specific, sometimes concrete type. For example, in:
impl MyCustomType<i32> { /* Self is a SelfTypeAlias here */ }
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.
Yes, thanks for raising this. I believe that some other part of rustdoc is "unwrapping" the Self
alias; see for example Vec::new()
's return type. It may make sense to centralize that behavior in one place—namely here—though.
Regarding your comment about the change in representation: I understand that Self
in trait is logically a parameter (à la Haskell type classes) in the compiler's view. However, from the perspective of users and many of Rustdoc's transformations, we treat it specially and don't think of it as such. For example, we don't normally render it as a parameter on a trait's page (though we do currently have some bugs, like the : PartialEq<Self>
here but not here). So I feel like from Rustdoc's perspective, it makes sense to treat it specially unless and until we replace clean::Type
with rustc_middle::ty::Ty
. Thoughts?
I do intend to add information about the meaning of the type (alias, with value, or parameter, with DefId
) to Type::SelfTy
, but rustdoc currently doesn't use that information.
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.
Yes, thanks for raising this. I believe that some other part of rustdoc is "unwrapping" the
Self
alias; see for exampleVec::new()
's return type.
No, that's not the reason. You've linked to std
's Vec::new
which is an inlined cross-crate re-export. If you take a look at the local docs in alloc
: https://doc.rust-lang.org/nightly/alloc/vec/struct.Vec.html#method.new, you can see that rustdoc retains the literal Self
.
This is due to the fact that in the local case rustdoc cleans the HIR which contains the still-unresolved Self
path. In the IXCRE case, rustdoc cleans rustc_middle::ty types were the SelfTyAlias has been resolved to a 'concrete' type (here: Vec<T>
). In rustc_middle::ty only SelfTyParam is retained (as tcx.types.self_param
/ "TyKind::Param(0, kw::SelfUpper)
").
This bug (or discrepancy at least) is tracked in #44306. See my latest comment from almost a year ago: #44306 (comment) describing how we might go about fixing it and why I haven't taken it on (yet). Note that that comment assumes we want to render Self
over the resolved aliased type which might lead to a better UX (unknown).
Nice improvement, thanks! @rfcbot reviewed |
Ok, according to our new procedure for rustdoc-frontend changes, this change is now approved ✔️ . (Though the PR itself is not done with review quite yet.) |
…riddle rustdoc: Cleanup `CacheBuilder` code for building search index This code was very convoluted and hard to reason about. It is now (I hope) much clearer and more suitable for both future enhancements and future cleanups. I'm doing this as a precursor, with no UI changes, to changing rustdoc to [ignore blanket impls][1] in type-based search. [1]: rust-lang#128471 (comment) r? `@notriddle`
…riddle rustdoc: Cleanup `CacheBuilder` code for building search index This code was very convoluted and hard to reason about. It is now (I hope) much clearer and more suitable for both future enhancements and future cleanups. I'm doing this as a precursor, with no UI changes, to changing rustdoc to [ignore blanket impls][1] in type-based search. [1]: rust-lang#128471 (comment) r? ``@notriddle``
Rollup merge of rust-lang#128578 - camelid:cache-index-cleanup, r=notriddle rustdoc: Cleanup `CacheBuilder` code for building search index This code was very convoluted and hard to reason about. It is now (I hope) much clearer and more suitable for both future enhancements and future cleanups. I'm doing this as a precursor, with no UI changes, to changing rustdoc to [ignore blanket impls][1] in type-based search. [1]: rust-lang#128471 (comment) r? ``@notriddle``
This comment was marked as resolved.
This comment was marked as resolved.
`SelfTy` makes it sound like it is literally the `Self` type, whereas in fact it may be `&Self` or other types. Plus, I want to use the name `SelfTy` for a new variant of `clean::Type`. Having both causes resolution conflicts or at least confusion.
Rustdoc often has to special-case `Self` because it is, well, a special type of generic parameter (although it also behaves as an alias in concrete impls). Instead of spreading this special-casing throughout the code base, create a new variant of the `clean::Type` enum that is for `Self` types. This is a refactoring that has almost no impact on rustdoc's behavior, except that `&Self`, `(Self,)`, `&[Self]`, and other similar occurrences of `Self` no longer link to the wrapping type (reference primitive, tuple primitive, etc.) as regular generics do. I felt this made more sense since users would expect `Self` to link to the containing trait or aliased type (though those are usually expanded), not the primitive that is wrapping it. For an example of the change, see the docs for `std::alloc::Allocator::by_ref`.
We already have special-cased code to handle inlining `Self` as the type or trait it refers to, and this was just causing glitches like the search `A -> B` yielding blanket `Into` impls.
This is much more readable and idiomatic, and also may help performance since `match`es usually use switches while `if`s may not. I also fixed an incorrect comment.
It was barely used, and the places that used it are actually clearer without it since they were often undoing some of its work. This also avoids an unnecessary clone of the receiver type and removes a layer of logical indirection in the code.
@bors r+ rollup |
rustdoc: Fix handling of `Self` type in search index and refactor its representation ### Summary - Add enum variant `clean::Type::SelfTy` and use it instead of `clean::Type::Generic(kw::SelfUpper)`. - Stop treating `Self` as a generic in the search index. - Remove struct formerly known as `clean::SelfTy` (constructed as representation of function receiver type). We're better off without it. ### Before ![image](https://github.com/user-attachments/assets/d257bdd8-3a62-4c71-84a5-9c950f2e4f00) ### After ![image](https://github.com/user-attachments/assets/8f6d3f22-92c1-41e3-9ab8-a881b66816c0) r? `@notriddle` cc rust-lang#127589 (comment)
…enton Rollup of 11 pull requests Successful merges: - rust-lang#128026 (std::thread: available_parallelism implementation for vxWorks proposal.) - rust-lang#128471 (rustdoc: Fix handling of `Self` type in search index and refactor its representation) - rust-lang#128607 (Use `object` in `run-make/symbols-visibility`) - rust-lang#128609 (Remove unnecessary constants from flt2dec dragon) - rust-lang#128611 (run-make: Remove cygpath) - rust-lang#128630 (docs(resolve): more explain about `target`) - rust-lang#128638 (run-make: enable msvc for `link-dedup`) - rust-lang#128647 (Enable msvc for link-args-order) - rust-lang#128649 (run-make: Enable msvc for `no-duplicate-libs` and `zero-extend-abi-param-passing`) - rust-lang#128656 (Enable msvc for run-make/rust-lld) - rust-lang#128660 (tests: more crashes) r? `@ghost` `@rustbot` modify labels: rollup
rustdoc: Fix handling of `Self` type in search index and refactor its representation ### Summary - Add enum variant `clean::Type::SelfTy` and use it instead of `clean::Type::Generic(kw::SelfUpper)`. - Stop treating `Self` as a generic in the search index. - Remove struct formerly known as `clean::SelfTy` (constructed as representation of function receiver type). We're better off without it. ### Before ![image](https://github.com/user-attachments/assets/d257bdd8-3a62-4c71-84a5-9c950f2e4f00) ### After ![image](https://github.com/user-attachments/assets/8f6d3f22-92c1-41e3-9ab8-a881b66816c0) r? ``@notriddle`` cc rust-lang#127589 (comment)
…iaskrgr Rollup of 8 pull requests Successful merges: - rust-lang#128026 (std::thread: available_parallelism implementation for vxWorks proposal.) - rust-lang#128471 (rustdoc: Fix handling of `Self` type in search index and refactor its representation) - rust-lang#128607 (Use `object` in `run-make/symbols-visibility`) - rust-lang#128609 (Remove unnecessary constants from flt2dec dragon) - rust-lang#128611 (run-make: Remove cygpath) - rust-lang#128619 (Correct the const stabilization of `<[T]>::last_chunk`) - rust-lang#128630 (docs(resolve): more explain about `target`) - rust-lang#128660 (tests: more crashes) r? `@ghost` `@rustbot` modify labels: rollup
rustdoc: Cleanup `CacheBuilder` code for building search index This code was very convoluted and hard to reason about. It is now (I hope) much clearer and more suitable for both future enhancements and future cleanups. I'm doing this as a precursor, with no UI changes, to changing rustdoc to [ignore blanket impls][1] in type-based search. [1]: rust-lang/rust#128471 (comment) r? ``@notriddle``
Rollup merge of rust-lang#128471 - camelid:rustdoc-self, r=notriddle rustdoc: Fix handling of `Self` type in search index and refactor its representation ### Summary - Add enum variant `clean::Type::SelfTy` and use it instead of `clean::Type::Generic(kw::SelfUpper)`. - Stop treating `Self` as a generic in the search index. - Remove struct formerly known as `clean::SelfTy` (constructed as representation of function receiver type). We're better off without it. ### Before ![image](https://github.com/user-attachments/assets/d257bdd8-3a62-4c71-84a5-9c950f2e4f00) ### After ![image](https://github.com/user-attachments/assets/8f6d3f22-92c1-41e3-9ab8-a881b66816c0) r? ```@notriddle``` cc rust-lang#127589 (comment)
…=fmease rustdoc-json: Add test for `Self` type Inspired by rust-lang#128471, the rustdoc-json suite had no tests in place for the `Self` type. This PR adds one. I've also manually checked locally that this test passes on 29e9248, confirming that adding `clean::Type::SelfTy` didn't change the JSON output. (potentially adding a self type to json (insead of (ab)using generic) is tracked in rust-lang#128522) Updates rust-lang#81359 r? `@fmease`
…=fmease rustdoc-json: Add test for `Self` type Inspired by rust-lang#128471, the rustdoc-json suite had no tests in place for the `Self` type. This PR adds one. I've also manually checked locally that this test passes on 29e9248, confirming that adding `clean::Type::SelfTy` didn't change the JSON output. (potentially adding a self type to json (insead of (ab)using generic) is tracked in rust-lang#128522) Updates rust-lang#81359 r? ``@fmease``
…=fmease rustdoc-json: Add test for `Self` type Inspired by rust-lang#128471, the rustdoc-json suite had no tests in place for the `Self` type. This PR adds one. I've also manually checked locally that this test passes on 29e9248, confirming that adding `clean::Type::SelfTy` didn't change the JSON output. (potentially adding a self type to json (insead of (ab)using generic) is tracked in rust-lang#128522) Updates rust-lang#81359 r? ```@fmease```
…=fmease rustdoc-json: Add test for `Self` type Inspired by rust-lang#128471, the rustdoc-json suite had no tests in place for the `Self` type. This PR adds one. I've also manually checked locally that this test passes on 29e9248, confirming that adding `clean::Type::SelfTy` didn't change the JSON output. (potentially adding a self type to json (insead of (ab)using generic) is tracked in rust-lang#128522) Updates rust-lang#81359 r? ````@fmease````
…=fmease rustdoc-json: Add test for `Self` type Inspired by rust-lang#128471, the rustdoc-json suite had no tests in place for the `Self` type. This PR adds one. I've also manually checked locally that this test passes on 29e9248, confirming that adding `clean::Type::SelfTy` didn't change the JSON output. (potentially adding a self type to json (insead of (ab)using generic) is tracked in rust-lang#128522) Updates rust-lang#81359 r? `````@fmease`````
…=fmease rustdoc-json: Add test for `Self` type Inspired by rust-lang#128471, the rustdoc-json suite had no tests in place for the `Self` type. This PR adds one. I've also manually checked locally that this test passes on 29e9248, confirming that adding `clean::Type::SelfTy` didn't change the JSON output. (potentially adding a self type to json (insead of (ab)using generic) is tracked in rust-lang#128522) Updates rust-lang#81359 r? ``````@fmease``````
…=fmease rustdoc-json: Add test for `Self` type Inspired by rust-lang#128471, the rustdoc-json suite had no tests in place for the `Self` type. This PR adds one. I've also manually checked locally that this test passes on 29e9248, confirming that adding `clean::Type::SelfTy` didn't change the JSON output. (potentially adding a self type to json (insead of (ab)using generic) is tracked in rust-lang#128522) Updates rust-lang#81359 r? ```````@fmease```````
…=fmease rustdoc-json: Add test for `Self` type Inspired by rust-lang#128471, the rustdoc-json suite had no tests in place for the `Self` type. This PR adds one. I've also manually checked locally that this test passes on 29e9248, confirming that adding `clean::Type::SelfTy` didn't change the JSON output. (potentially adding a self type to json (insead of (ab)using generic) is tracked in rust-lang#128522) Updates rust-lang#81359 r? ````````@fmease````````
Rollup merge of rust-lang#129123 - aDotInTheVoid:rustdoc-json-self, r=fmease rustdoc-json: Add test for `Self` type Inspired by rust-lang#128471, the rustdoc-json suite had no tests in place for the `Self` type. This PR adds one. I've also manually checked locally that this test passes on 29e9248, confirming that adding `clean::Type::SelfTy` didn't change the JSON output. (potentially adding a self type to json (insead of (ab)using generic) is tracked in rust-lang#128522) Updates rust-lang#81359 r? ````````@fmease````````
Summary
clean::Type::SelfTy
and use it instead ofclean::Type::Generic(kw::SelfUpper)
.Self
as a generic in the search index.clean::SelfTy
(constructed as representation of function receiver type). We're better off without it.Before
After
r? @notriddle
cc #127589 (comment)