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: Fix handling of Self type in search index and refactor its representation #128471

Merged
merged 6 commits into from
Aug 5, 2024

Conversation

camelid
Copy link
Member

@camelid camelid commented Aug 1, 2024

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

After

image

r? @notriddle
cc #127589 (comment)

@rustbot rustbot added A-rustdoc-json Area: Rustdoc JSON backend S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Aug 1, 2024
// FIXME: add dedicated variant to json Type?
SelfTy => Type::Generic("Self".to_owned()),
Copy link
Member Author

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?

Copy link
Member

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

Copy link
Member

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

Copy link
Member Author

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.

@camelid
Copy link
Member Author

camelid commented Aug 1, 2024

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 if lets with a match.

@camelid camelid added A-type-based-search Area: Searching rustdoc pages using type signatures A-rustdoc-search Area: Rustdoc's search feature labels Aug 1, 2024
trait_: Some(trait_),
..
}),
bounds,
..
} => !(bounds.is_empty() || *s == kw::SelfUpper && trait_.def_id() == trait_did),
} => !bounds.is_empty() && trait_.def_id() != trait_did,
Copy link
Member Author

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.

@notriddle
Copy link
Contributor

Please add a test case in tests/rustdoc-js?

@camelid
Copy link
Member Author

camelid commented Aug 1, 2024

Done, let me know if it looks correct.

@camelid
Copy link
Member Author

camelid commented Aug 1, 2024

@rfcbot poll rustdoc-frontend

@rfcbot
Copy link

rfcbot commented Aug 1, 2024

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 => {
Copy link
Member

@compiler-errors compiler-errors Aug 1, 2024

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 */ }

Copy link
Member Author

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.

Copy link
Member

@fmease fmease Aug 15, 2024

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.

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).

@GuillaumeGomez
Copy link
Member

Nice improvement, thanks!

@rfcbot reviewed

@camelid
Copy link
Member Author

camelid commented Aug 3, 2024

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.)

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Aug 4, 2024
…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`
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Aug 4, 2024
…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``
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Aug 4, 2024
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``
@bors

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.
@notriddle
Copy link
Contributor

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Aug 4, 2024

📌 Commit dac7f20 has been approved by notriddle

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 4, 2024
ChrisDenton added a commit to ChrisDenton/rust that referenced this pull request Aug 5, 2024
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)
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 5, 2024
…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
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Aug 5, 2024
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)
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 5, 2024
…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
RalfJung pushed a commit to RalfJung/miri that referenced this pull request Aug 5, 2024
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``
@bors bors merged commit 4adefa4 into rust-lang:master Aug 5, 2024
6 checks passed
@rustbot rustbot added this to the 1.82.0 milestone Aug 5, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Aug 5, 2024
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)
@camelid camelid deleted the rustdoc-self branch August 5, 2024 09:41
workingjubilee added a commit to workingjubilee/rustc that referenced this pull request Aug 29, 2024
…=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`
workingjubilee added a commit to workingjubilee/rustc that referenced this pull request Aug 29, 2024
…=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``
workingjubilee added a commit to workingjubilee/rustc that referenced this pull request Aug 30, 2024
…=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```
workingjubilee added a commit to workingjubilee/rustc that referenced this pull request Aug 30, 2024
…=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````
workingjubilee added a commit to workingjubilee/rustc that referenced this pull request Aug 31, 2024
…=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`````
workingjubilee added a commit to workingjubilee/rustc that referenced this pull request Aug 31, 2024
…=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``````
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Aug 31, 2024
…=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```````
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Aug 31, 2024
…=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````````
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Aug 31, 2024
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````````
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-rustdoc-json Area: Rustdoc JSON backend A-rustdoc-search Area: Rustdoc's search feature A-type-based-search Area: Searching rustdoc pages using type signatures S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants