Skip to content

Conversation

@dingxiangfei2009
Copy link
Contributor

@dingxiangfei2009 dingxiangfei2009 commented Sep 1, 2025

Receiver chain has been an extension of Deref chain, but the consequence has been questioned as this would admit method signatures that are deemed dubious.

It is also debatable that Receiver trait which determines applicable Self type should have anything to do with dereference operation in general.

This patch separate the two traits and isolate their use in the language. This means that in method probing, we will chase down a Deref chain for an applicable type for the variable self, from which we additionally chase down a Receiver chain for an applicable Self type from a list of methods that accepts one of these possible types of self.

To facilitate discussion, we can use the Zulip thread #t-lang > Consequences of making Deref a subtrait of Receiver.

Pending items

  • First, gather feedback on the proposed change and assess the impact on the overall feature.
  • Stomp out UI test changes due to lost diagnostics, by enabling search through Receiver side-chains, so that we can suggest enabling arbitrary_self_types gate again.

@rustbot
Copy link
Collaborator

rustbot commented Sep 1, 2025

r? @jackh726

rustbot has assigned @jackh726.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Sep 1, 2025
@rustbot
Copy link
Collaborator

rustbot commented Sep 1, 2025

This PR changes a file inside tests/crashes. If a crash was fixed, please move into the corresponding ui subdir and add 'Fixes #' to the PR description to autoclose the issue upon merge.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rustbot

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@dingxiangfei2009
Copy link
Contributor Author

@rustbot label +F-arbitrary_self_types

@rustbot rustbot added the F-arbitrary_self_types `#![feature(arbitrary_self_types)]` label Sep 2, 2025
@rustbot
Copy link
Collaborator

rustbot commented Sep 2, 2025

The Miri subtree was changed

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo, @GuillaumeGomez

@rustbot

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@jackh726
Copy link
Member

jackh726 commented Sep 3, 2025

Is this waiting on discussion and a decision from the lang team?

@dingxiangfei2009
Copy link
Contributor Author

@jackh726 Sorry I was not very clear. Indeed it would need a lang team discussion.

To support the discussion, I am writing a report to describe what changes this would bring to the feature.

cc @traviscross @tmandry

@traviscross traviscross added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. S-waiting-on-team I-lang-radar Items that are on lang's radar and will need eventual work or consideration. T-lang Relevant to the language team and removed T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Sep 4, 2025
@bors
Copy link
Collaborator

bors commented Sep 18, 2025

☔ The latest upstream changes (presumably #145993) made this pull request unmergeable. Please resolve the merge conflicts.

@dingxiangfei2009
Copy link
Contributor Author

dingxiangfei2009 commented Sep 24, 2025

The report is a bit overdue. I would like to just publish a partial text while I need more time to restore some diagnostics.

Acceptable receivers

Landing #146095 means that types implementing Deref are not automatically acceptable receiver types anymore.

Before #146095 After #146095
struct A;
struct B;
impl Deref for A {
    type Target = B;
    fn deref(&self) -> &B {
        &B
    }
}
impl B {
    fn recv(self: &A);
}

A.recv(); // resolves to B::recv
struct A;
struct B;
impl Deref for A {
    type Target = B;
    fn deref(&self) -> &B {
        &B
    }
}
// This is needed ...
impl Receiver for A {
    type Target = B;
}
impl B {
    fn recv(self: &A);
}

A.recv();
// ^ ... in order to resolve this to B::recv
// The following passes checking in our surprises
impl Trait for str {
    fn recv(self: &String) {}
}
"hello".to_string().recv();
impl Trait for MyType {
    fn recv(self: MutexGuard<'_, Self>) {}
}
let my_mutex = Mutex::new(MyType);
my_mutex.lock().recv();
// The following stops to compile for good reasons
impl Trait for str {
    fn recv(self: &String) {}
    // `String: Deref<Target = str>` but without `Receiver<Target = str>`
}
"hello".to_string().recv(); //~ ERROR
impl Trait for MyType {
    fn recv(self: MutexGuard<'_, Self>) {}
    // `MutexGuard<'_, MyType>: Deref<Target = MyType>` but without `Receiver<Target = MyType>`
}
let my_mutex = Mutex::new(MyType);
my_mutex.lock().recv(); //~ ERROR

Library changes

This patch demonstrates that we now explicitly mark types like Rc, Arc, Box, Pin as valid receivers regardless of whether a Deref is applicable.

This is particularly important for Pin as we want to conditionally make it Derefable but unconditionally a valid method receiver just like the stable Rust.

Shadowing

After careful consideration and testing, I believe that splitting the two traits do not change the fundamental reasoning behind method shadowing diagnostics. Before this change, concerns about shadowing items through Deref, and by extension Receiver, are reported by the compiler by picking up inherent methods with the same name on some self receiver down the Receiver chain. Those shadowed items will continue to be reported as they will appear in the same Receiver sub-chain after this PR lands.

@traviscross traviscross added I-lang-nominated Nominated for discussion during a lang team meeting. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang labels Sep 24, 2025
@rustbot

This comment has been minimized.

@bors
Copy link
Collaborator

bors commented Oct 31, 2025

☔ The latest upstream changes (presumably #144420) made this pull request unmergeable. Please resolve the merge conflicts.

@rustbot

This comment has been minimized.

@rustbot

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@dingxiangfei2009
Copy link
Contributor Author

dingxiangfei2009 commented Dec 31, 2025

Quick update:

  • I have benchmarked the method resolution, as reworked in the commit Nr. 3, which shows some compiler performance improvements on my metal. Shall we get a rust-timer run? With this change, we will presumably address the concern on extra overhead from potentially allowing Deref::Target != Receiver::Target. Deref::Target == Receiver::Target is a common case and the new method resolution should still be comparatively performant under this scenario.
  • I would propose to require explicit enablement of arbitrary method receiver designation with impl Receiver. It is not a lot of code for library authors to write impl Receiver when they really want their type to receive methods for other types. The vibe check shows that keeping Deref and Receiver decoupled in trait design is better.
  • The next step is to tweak the impl Receiver wfcheck a bit. Deref::Target == Receiver::Target will be set as the #[feature(arbitrary_self_types)] and Deref::Target != Receiver::Target will be allowed behind a new feature gate so that people can continue to experiment.

@traviscross
Copy link
Contributor

@bors2 try
@rust-timer queue

@rust-timer

This comment has been minimized.

@rust-bors

This comment has been minimized.

rust-bors bot added a commit that referenced this pull request Jan 1, 2026
arbitrary_self_types: Split the Autoderef chain
@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jan 1, 2026
@rust-bors
Copy link

rust-bors bot commented Jan 1, 2026

☀️ Try build successful (CI)
Build commit: 7757954 (7757954de1446aa7950e3bf5df62e7df2c06fac5, parent: 4c62aa446803c8f31eafdc0c0119209ff129b3e0)

@rust-timer

This comment has been minimized.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (7757954): comparison URL.

Overall result: ❌✅ regressions and improvements - please read the text below

Benchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf.

Next Steps: If you can justify the regressions found in this try perf run, please do so in sufficient writing along with @rustbot label: +perf-regression-triaged. If not, please fix the regressions and do another perf run. If its results are neutral or positive, the label will be automatically removed.

@bors rollup=never
@rustbot label: -S-waiting-on-perf +perf-regression

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.2% [0.1%, 0.3%] 18
Regressions ❌
(secondary)
0.4% [0.1%, 0.7%] 10
Improvements ✅
(primary)
-0.5% [-1.2%, -0.1%] 16
Improvements ✅
(secondary)
-0.1% [-0.3%, -0.1%] 10
All ❌✅ (primary) -0.1% [-1.2%, 0.3%] 34

Max RSS (memory usage)

Results (primary 0.0%)

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

mean range count
Regressions ❌
(primary)
1.6% [1.5%, 1.8%] 2
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-1.6% [-2.2%, -0.9%] 2
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 0.0% [-2.2%, 1.8%] 4

Cycles

Results (secondary -2.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)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-2.5% [-3.2%, -2.0%] 5
All ❌✅ (primary) - - 0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 476.46s -> 476.713s (0.05%)
Artifact size: 390.83 MiB -> 390.87 MiB (0.01%)

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels Jan 1, 2026
@dingxiangfei2009
Copy link
Contributor Author

The results seem neutral to me. Do we need deeper look into the performance?

@Kobzol
Copy link
Member

Kobzol commented Jan 2, 2026

Perf. seems like a wash, so I don't think so.

Receiver chain has been an extension of Deref chain,
but the consequence has been questioned as this would admit method
signatures that are deemed dubious.

It is also debatable that Receiver trait which determines applicable
`Self` type should have anything to do with dereference operation
in general.

This patch separate the two traits and isolate their use in the language.
This means that in method probing, we will chase down a Deref chain for
an applicable type for the variable `self`, from which we additionally
chase down a Receiver chain for an applicable `Self` type from a list of
methods that accepts one of these possible types of `self`.

This patch includes rewording of diagnostics.
To allow use of Receiver with Target diverging from Deref::Target,
one must now enable an unstable feature flag arbitrary-self-types-split-chains.

Signed-off-by: Xiangfei Ding <[email protected]>
@rustbot
Copy link
Collaborator

rustbot commented Jan 2, 2026

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.

Previously we have been picking methods for receiver types even though
we are inspecting other receiver types that are several levels of
dereferences, which is wasted effort because there will never be matches
with these methods.

Signed-off-by: Xiangfei Ding <[email protected]>
@dingxiangfei2009
Copy link
Contributor Author

@rustbot label: +perf-regression-triaged

@rustbot rustbot added the perf-regression-triaged The performance regression has been triaged. label Jan 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

F-arbitrary_self_types `#![feature(arbitrary_self_types)]` I-lang-radar Items that are on lang's radar and will need eventual work or consideration. perf-regression Performance regression. perf-regression-triaged The performance regression has been triaged. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants