Skip to content

[rustdoc] Fix how Deref items is handled. - #160915

Merged
rust-bors[bot] merged 5 commits into
rust-lang:mainfrom
GuillaumeGomez:deref-items
Oct 6, 2026
Merged

rust-bors[bot] merged 5 commits into
rust-lang:mainfrom
GuillaumeGomez:deref-items

Conversation

@GuillaumeGomez

@GuillaumeGomez GuillaumeGomez commented Aug 11, 2026 •

Copy link
Copy Markdown
Member

View all comments

Fixes #160236.

This PR fixes a few things around how we handle Deref:

  • Since nothing except for methods is callable through a Deref, only methods should be kept
  • If the Deref::Target is a type implementing Copy, then methods taking self work and should be displayed.

During the clean pass, I store the item DefId on which Deref is implemented in a DefIdSet if the Deref::Target implements Copy. Then during rendering, we check if the "parent item" is in in the DefIdSet, and if so, we keep methods with self.

Now you might wonder why the item and not the derefed item. It's because the DefId we get from the computed type doesn't match the DefId of the actual type (that's where I spent most of my time, finding an ID (DefId/ItemId) I can use as key T_T).

It computes in html/render if the Deref::Target item is copy before rendering it.

So to resume:

  • &self is always kept.
  • &mut self is kept if DerefMut is implemented (nothing changed there).
  • self is kept only if Deref::Target is Copy.
  • Everything else disappears as they're not callable through Deref.

r? @camelid

@rustbot rustbot added 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. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output. labels Aug 11, 2026
@rustbot

rustbot commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

camelid is currently at their maximum review capacity.
They may take a while to respond.

@GuillaumeGomez

Copy link
Copy Markdown
Member Author

Oof, that's a big diff. It's mostly because of reindent, not much that we can do about. ^^'

@rust-log-analyzer

This comment has been minimized.

@GuillaumeGomez

Copy link
Copy Markdown
Member Author

Fixed fmt. ^^'

@camelid camelid left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw there's some missing wording in this sentence of the PR description, so I'm not quite sure what it says:

Since since except for methods is callable through a Deref, only methods should be kept

View changes since this review

Comment thread src/librustdoc/clean/inline.rs Outdated
Comment thread src/librustdoc/clean/utils.rs Outdated
Comment thread tests/rustdoc-html/deref/deref-to-primitive.rs
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 11, 2026
@GuillaumeGomez

Copy link
Copy Markdown
Member Author

Btw there's some missing wording in this sentence of the PR description, so I'm not quite sure what it says:

Since since except for methods is callable through a Deref, only methods should be kept

Fixed the typo. Correct sentence is:

Since nothing except for methods is callable through a Deref, only methods should be kept

@GuillaumeGomez GuillaumeGomez removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Aug 11, 2026
@GuillaumeGomez

Copy link
Copy Markdown
Member Author

Thanks to @camelid's suggestion, code is now much simpler. Thanks!

@rustbot ready

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 11, 2026
Comment thread src/librustdoc/clean/mod.rs Outdated
Comment on lines +3046 to +3047
let for_ = clean_ty(impl_.self_ty, cx);

@camelid camelid Aug 12, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Moving this let is now unnecessary. Better to move it back to where it's used.

View changes since the review

Comment thread src/librustdoc/clean/utils.rs Outdated
@@ -295,6 +295,8 @@ pub(crate) fn build_deref_target_impls(
inline::build_impls(cx, did, None, ret);
});
}
} else {
break;

@camelid camelid Aug 12, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this break added?

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it's actually looking for the Deref::Target item and doesn't do anything. So at that point, we can break as soon as we found it. Can remove it though, considering there are only 2 items, doesn't matter much.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also just realized that it shouldn't be in a else condition. Anyway, removing it.

Comment thread src/librustdoc/html/render/mod.rs Outdated
@@ -3150,3 +3174,30 @@ fn repr_attribute<'tcx>(

(!result.is_empty()).then(|| format!("#[repr({})]", result.join(", ")).into())
}

pub(crate) fn compute_if_deref_target_implements_copy(
cx: &Context<'_>,

@camelid camelid Aug 12, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's have this take TyCtxt instead of Context and change the callers as well. It's better to take as little input as possible.

View changes since the review

Comment thread src/librustdoc/html/render/sidebar.rs Outdated
AlsoCollectAssocFns { assoc_fns: &'r mut Vec<Link<'l>> },
}

fn get_methods<'a>(
i: &'a clean::Impl,
mut mode: GetMethodsMode<'_, 'a>,
used_links: &mut FxHashSet<String>,
tcx: TyCtxt<'_>,
cx: &Context<'_>,

@camelid camelid Aug 12, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@camelid camelid added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 12, 2026
@rustbot

This comment has been minimized.

@GuillaumeGomez

Copy link
Copy Markdown
Member Author

Applied suggestions.

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 12, 2026
@GuillaumeGomez

Copy link
Copy Markdown
Member Author

ping @camelid ;)

} else {
false
}
(deref_mut_ || !by_mut_ref) && !by_box && (!by_value || target_is_copy)

@camelid camelid Sep 2, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any idea why Box is special-cased here? Seems weird to special-case at all, and also I would expect needing special cases for things like Rc or Pin as well if Box truly needs it.

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's because Box is a known type implementing Deref for the end type, common enough to make sense as an optimization? And should likely add the other types you mentioned. However in another PR might make more sense.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This causes a behavior difference though, right? It's not just a matter of optimization/performance.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you see what behavior changes if you remove the !by_box part of this expression?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without by_box, when running the rustdoc-html tests:

failures:

---- [rustdoc-html] tests/rustdoc-html/deref-mut-35169-2.rs stdout ----
------python3 stdout------------------------------

------python3 stderr------------------------------
38: !has check failed
	`XPATH PATTERN` unexpectedly matched
	//@ !has - '//*[@id="method.by_explicit_box"]//h4[@class="code-header"]' 'fn by_explicit_box(self: Box<Foo>)'
39: !has check failed
	`XPATH PATTERN` unexpectedly matched
	//@ !has - '//*[@id="method.by_explicit_box"]' 'fn by_explicit_box(self: Box<Foo>)'
40: !has check failed
	`XPATH PATTERN` unexpectedly matched
	//@ !has - '//*[@id="method.by_explicit_self_box"]//h4[@class="code-header"]' 'fn by_explicit_self_box(self: Box<Self>)'
41: !has check failed
	`XPATH PATTERN` unexpectedly matched
	//@ !has - '//*[@id="method.by_explicit_self_box"]' 'fn by_explicit_self_box(self: Box<Self>)'

Encountered 4 errors

------------------------------------------

error: htmldocck failed!
status: exit status: 1
command: "/usr/bin/python3" "/home/imperio/rust/rust/src/etc/htmldocck.py" "/home/imperio/rust/rust/build/x86_64-unknown-linux-gnu/test/rustdoc-html/deref-mut-35169-2" "/home/imperio/rust/rust/tests/rustdoc-html/deref-mut-35169-2.rs"
stdout: none
--- stderr -------------------------------
38: !has check failed
	`XPATH PATTERN` unexpectedly matched
	//@ !has - '//*[@id="method.by_explicit_box"]//h4[@class="code-header"]' 'fn by_explicit_box(self: Box<Foo>)'
39: !has check failed
	`XPATH PATTERN` unexpectedly matched
	//@ !has - '//*[@id="method.by_explicit_box"]' 'fn by_explicit_box(self: Box<Foo>)'
40: !has check failed
	`XPATH PATTERN` unexpectedly matched
	//@ !has - '//*[@id="method.by_explicit_self_box"]//h4[@class="code-header"]' 'fn by_explicit_self_box(self: Box<Self>)'
41: !has check failed
	`XPATH PATTERN` unexpectedly matched
	//@ !has - '//*[@id="method.by_explicit_self_box"]' 'fn by_explicit_self_box(self: Box<Self>)'

Encountered 4 errors
------------------------------------------

---- [rustdoc-html] tests/rustdoc-html/deref-mut-35169-2.rs stdout end ----
---- [rustdoc-html] tests/rustdoc-html/deref-mut-35169.rs stdout ----
------python3 stdout------------------------------

------python3 stderr------------------------------
33: !has check failed
	`XPATH PATTERN` unexpectedly matched
	//@ !has - '//*[@id="method.by_explicit_box"]//h4[@class="code-header"]' 'fn by_explicit_box(self: Box<Foo>)'
34: !has check failed
	`XPATH PATTERN` unexpectedly matched
	//@ !has - '//*[@id="method.by_explicit_box"]' 'fn by_explicit_box(self: Box<Foo>)'
35: !has check failed
	`XPATH PATTERN` unexpectedly matched
	//@ !has - '//*[@id="method.by_explicit_self_box"]//h4[@class="code-header"]' 'fn by_explicit_self_box(self: Box<Self>)'
36: !has check failed
	`XPATH PATTERN` unexpectedly matched
	//@ !has - '//*[@id="method.by_explicit_self_box"]' 'fn by_explicit_self_box(self: Box<Self>)'

Encountered 4 errors

------------------------------------------

error: htmldocck failed!
status: exit status: 1
command: "/usr/bin/python3" "/home/imperio/rust/rust/src/etc/htmldocck.py" "/home/imperio/rust/rust/build/x86_64-unknown-linux-gnu/test/rustdoc-html/deref-mut-35169" "/home/imperio/rust/rust/tests/rustdoc-html/deref-mut-35169.rs"
stdout: none
--- stderr -------------------------------
33: !has check failed
	`XPATH PATTERN` unexpectedly matched
	//@ !has - '//*[@id="method.by_explicit_box"]//h4[@class="code-header"]' 'fn by_explicit_box(self: Box<Foo>)'
34: !has check failed
	`XPATH PATTERN` unexpectedly matched
	//@ !has - '//*[@id="method.by_explicit_box"]' 'fn by_explicit_box(self: Box<Foo>)'
35: !has check failed
	`XPATH PATTERN` unexpectedly matched
	//@ !has - '//*[@id="method.by_explicit_self_box"]//h4[@class="code-header"]' 'fn by_explicit_self_box(self: Box<Self>)'
36: !has check failed
	`XPATH PATTERN` unexpectedly matched
	//@ !has - '//*[@id="method.by_explicit_self_box"]' 'fn by_explicit_self_box(self: Box<Self>)'

Encountered 4 errors
------------------------------------------

---- [rustdoc-html] tests/rustdoc-html/deref-mut-35169.rs stdout end ----

failures:
    [rustdoc-html] tests/rustdoc-html/deref-mut-35169-2.rs
    [rustdoc-html] tests/rustdoc-html/deref-mut-35169.rs

I think we should leave it as is. ;)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I still think this special-casing is a little sketchy but it's pre-existing so we should deal with it in another PR.

Comment thread src/librustdoc/html/render/mod.rs Outdated
Comment thread src/librustdoc/html/render/mod.rs Outdated
@camelid camelid added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 2, 2026
@rustbot

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Oct 5, 2026
…uwer

Rollup of 12 pull requests

Successful merges:

 - #163531 (rustc_ast_lowering: track implicit Self via explicit flag instead of name)
 - #160915 ([rustdoc] Fix how `Deref` items is handled.)
 - #163364 (make semicolon_in_expressions_from_non_local_macros not report-in-deps)
 - #163770 (document the rustc_comptime attribute)
 - #163780 (Skip optional asserts in SsaRangePropagation)
 - #163785 (Bump Windows CI LLVM to 22.1.8)
 - #163796 (continue crashes tests `-Znext-solver` work)
 - #163646 (Get `inputs_hir` directly from `decl`)
 - #163733 (Fix extra spaces in integer format_into docs)
 - #163773 (Update GitHub Actions to v26)
 - #163787 (moves rustc_legacy_const_generics checks into attribute parsing)
 - #163810 (Fix an issue for clippy's `search_is_some` with the next-solver)
@JonathanBrouwer

Copy link
Copy Markdown
Member

💔 I suspect this PR failed tests as part of a rollup
@bors r-

Failed during a local run

error[E0433]: cannot find module or crate `hir` in this scope
    --> src/librustdoc/html/render/mod.rs:3188:16
     |
3188 |         && let hir::ItemKind::Impl(impl_item) = item.kind
     |                ^^^ use of unresolved module or unlinked crate `hir`
     |
     = help: if you wanted to use a crate named `hir`, use `cargo add hir` to add it to your `Cargo.toml`
help: consider importing one of these enums
     |
  42 + use crate::ast::ItemKind;
     |
  42 + use crate::clean::ItemKind;
     |
  42 + use rustc_ast::ItemKind;
     |
  42 + use rustc_hir::ItemKind;
     |
     = and 1 other candidate
help: if you import `ItemKind`, refer to it directly
     |
3188 -         && let hir::ItemKind::Impl(impl_item) = item.kind
3188 +         && let ItemKind::Impl(impl_item) = item.kind
     |

I think you need to rebase

@rust-bors rust-bors Bot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Oct 5, 2026
@rust-bors

rust-bors Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

This pull request was unapproved.

This PR was contained in a rollup (#163827), which was unapproved.

View changes since this unapproval

@rustbot

rustbot commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@GuillaumeGomez

Copy link
Copy Markdown
Member Author

@JonathanBrouwer Yeah it needed a rebase.

@bors r=camelid

@rust-bors

rust-bors Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 32561a0 has been tentatively approved by camelid

It will be put into the queue for this repository once PR CI succeeds.

@rust-bors rust-bors Bot 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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Oct 5, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Oct 5, 2026
[rustdoc] Fix how `Deref` items is handled.

Fixes rust-lang#160236.

This PR fixes a few things around how we handle `Deref`:
 * Since nothing except for methods is callable through a `Deref`, only methods should be kept
 * If the `Deref::Target` is a type implementing `Copy`, then methods taking `self` work and should be displayed.

<del>During the `clean` pass, I store the item `DefId` on which `Deref` is implemented in a `DefIdSet` if the `Deref::Target` implements `Copy`. Then during rendering, we check if the "parent item" is in in the `DefIdSet`, and if so, we keep methods with `self`.</del>

<del>Now you might wonder why the item and not the derefed item. It's because the `DefId` we get from the computed type doesn't match the `DefId` of the actual type (that's where I spent most of my time, finding an ID (`DefId`/`ItemId`) I can use as key T_T).</del>

It computes in `html/render` if the `Deref::Target` item is copy before rendering it.

So to resume:

* `&self` is always kept.
* `&mut self` is kept if `DerefMut` is implemented (nothing changed there).
* `self` is kept only if `Deref::Target` is `Copy`.
* Everything else disappears as they're not callable through `Deref`.

r? @camelid
rust-bors Bot pushed a commit that referenced this pull request Oct 5, 2026
…uwer

Rollup of 4 pull requests

Successful merges:

 - #160915 ([rustdoc] Fix how `Deref` items is handled.)
 - #163267 (fix `VisibleForLeakCheck` in `RegionOutlives` fast path)
 - #163673 (Move #[doc(inline)] and #[doc(no_inline)] validation into rustc_attr_parsing)
 - #163814 (Add some comments and docs related to `AllocatorNightly`)
rust-bors Bot pushed a commit that referenced this pull request Oct 5, 2026
…uwer

Rollup of 5 pull requests

Successful merges:

 - #160915 ([rustdoc] Fix how `Deref` items is handled.)
 - #163267 (fix `VisibleForLeakCheck` in `RegionOutlives` fast path)
 - #163673 (Move #[doc(inline)] and #[doc(no_inline)] validation into rustc_attr_parsing)
 - #163795 (When documenting without a specified `--edition`, emit a message)
 - #163814 (Add some comments and docs related to `AllocatorNightly`)
rust-bors Bot pushed a commit that referenced this pull request Oct 5, 2026
…uwer

Rollup of 5 pull requests

Successful merges:

 - #160915 ([rustdoc] Fix how `Deref` items is handled.)
 - #163267 (fix `VisibleForLeakCheck` in `RegionOutlives` fast path)
 - #163673 (Move #[doc(inline)] and #[doc(no_inline)] validation into rustc_attr_parsing)
 - #163795 (When documenting without a specified `--edition`, emit a message)
 - #163814 (Add some comments and docs related to `AllocatorNightly`)
rust-bors Bot pushed a commit that referenced this pull request Oct 5, 2026
…uwer

Rollup of 5 pull requests

Successful merges:

 - #160915 ([rustdoc] Fix how `Deref` items is handled.)
 - #163267 (fix `VisibleForLeakCheck` in `RegionOutlives` fast path)
 - #163673 (Move #[doc(inline)] and #[doc(no_inline)] validation into rustc_attr_parsing)
 - #163795 (When documenting without a specified `--edition`, emit a message)
 - #163814 (Add some comments and docs related to `AllocatorNightly`)
@rust-bors
rust-bors Bot merged commit 3c67d2d into rust-lang:main Oct 6, 2026
14 checks passed
rust-bors Bot pushed a commit that referenced this pull request Oct 6, 2026
Rollup merge of #160915 - GuillaumeGomez:deref-items, r=camelid

[rustdoc] Fix how `Deref` items is handled.

Fixes #160236.

This PR fixes a few things around how we handle `Deref`:
 * Since nothing except for methods is callable through a `Deref`, only methods should be kept
 * If the `Deref::Target` is a type implementing `Copy`, then methods taking `self` work and should be displayed.

<del>During the `clean` pass, I store the item `DefId` on which `Deref` is implemented in a `DefIdSet` if the `Deref::Target` implements `Copy`. Then during rendering, we check if the "parent item" is in in the `DefIdSet`, and if so, we keep methods with `self`.</del>

<del>Now you might wonder why the item and not the derefed item. It's because the `DefId` we get from the computed type doesn't match the `DefId` of the actual type (that's where I spent most of my time, finding an ID (`DefId`/`ItemId`) I can use as key T_T).</del>

It computes in `html/render` if the `Deref::Target` item is copy before rendering it.

So to resume:

* `&self` is always kept.
* `&mut self` is kept if `DerefMut` is implemented (nothing changed there).
* `self` is kept only if `Deref::Target` is `Copy`.
* Everything else disappears as they're not callable through `Deref`.

r? @camelid
@rustbot rustbot added this to the 1.101.0 milestone Oct 6, 2026
@rust-timer

Copy link
Copy Markdown
Collaborator

Note

This PR was benchmarked as part of triage of its containing rollup: triage URL.

Finished benchmarking commit (9d02933): comparison URL.

Overall result: ❌ regressions - please read:

Our benchmarks found a performance regression caused by this PR.
This might be an actual regression, but it can also be just noise.

Next Steps:

  • If the regression was expected or you think it can be justified,
    please write a comment with sufficient written justification, and add
    @rustbot label: +perf-regression-triaged to it, to mark the regression as triaged.
  • If you think that you know of a way to resolve the regression, try to create
    a new PR with a fix for the regression.
  • If you do not understand the regression or you think that it is just noise,
    you can ask the @rust-lang/wg-compiler-performance working group for help (members of this group
    were already notified of this PR).

@rustbot label: +perf-regression
cc @rust-lang/wg-compiler-performance

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
0.3% [0.3%, 0.3%] 1
Regressions ❌
(secondary)
1.2% [1.2%, 1.2%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 0.3% [0.3%, 0.3%] 1

Max RSS (memory usage)

This perf run didn't have relevant results for this metric.

Cycles

Results (secondary 6.5%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
6.5% [6.5%, 6.5%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Binary size

This perf run didn't have relevant results for this metric.

Artifact size: 408.58 MiB -> 408.75 MiB (0.04%)

@rustbot rustbot added the perf-regression Performance regression. label Oct 6, 2026
@GuillaumeGomez
GuillaumeGomez deleted the deref-items branch October 6, 2026 09:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

perf-regression Performance regression. 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. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rustdoc: Methods from deref is missing methods

7 participants