Skip to content

Prefer inherent methods in trait object method resolution#158320

Open
Jules-Bertholet wants to merge 3 commits into
rust-lang:mainfrom
Jules-Bertholet:dyn-inherent
Open

Prefer inherent methods in trait object method resolution#158320
Jules-Bertholet wants to merge 3 commits into
rust-lang:mainfrom
Jules-Bertholet:dyn-inherent

Conversation

@Jules-Bertholet

Copy link
Copy Markdown
Contributor

Fixes #51402. Inherent methods on trait objects now take precedence over methods from the trait object's trait, but these last continue to take precedence over other trait impls as before.

I don't know whether this should be feature gated or insta-stable FCP, will let T-types decide that.

r? types

@rustbot label T-types A-dyn-trait

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 23, 2026
@rustbot rustbot added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-dyn-trait Area: trait objects, vtable layout T-types Relevant to the types team, which will review and decide on the PR/issue. labels Jun 23, 2026
Comment on lines +54 to +55
let x: &(dyn T + Send) = &0i32;
assert_eq!(x.foo(), 0);

@Jules-Bertholet Jules-Bertholet Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This part is not so nice… ideally this would use the inherent impl too.

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I looked into making this work, but it seems non-trivial. The inherent_impls query is based on DefIds, so information about auto traits is lost

@oli-obk

oli-obk commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

@bors try @rust-timer queue

and cratering it when the try job finishes, impl lgtm

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jun 24, 2026
@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Jun 24, 2026
Prefer inherent methods in trait object method resolution
@oli-obk oli-obk added needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 24, 2026
@rust-bors

rust-bors Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 8a2f6fe (8a2f6fe57adadb246778b8d41925d3dc46d468cb)
Base parent: f28ac76 (f28ac764c36004fa6a6e098d15b4016a838c13c6)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (8a2f6fe): comparison URL.

Overall result: no relevant changes - no action needed

Benchmarking means the PR may be perf-sensitive. Consider adding rollup=never if this change is not fit for rolling up.

@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

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

Max RSS (memory usage)

Results (primary -5.9%, 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)
- - 0
Improvements ✅
(primary)
-5.9% [-5.9%, -5.9%] 1
Improvements ✅
(secondary)
-6.5% [-10.5%, -2.6%] 2
All ❌✅ (primary) -5.9% [-5.9%, -5.9%] 1

Cycles

Results (secondary 3.9%)

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)
3.9% [3.9%, 3.9%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Binary size

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

Bootstrap: 510.446s -> 505.256s (-1.02%)
Artifact size: 353.05 MiB -> 353.51 MiB (0.13%)

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jun 24, 2026
@oli-obk

oli-obk commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

@craterbot check

@craterbot

Copy link
Copy Markdown
Collaborator

👌 Experiment pr-158320 created and queued.
🤖 Automatically detected try build 8a2f6fe
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added the S-waiting-on-crater Status: Waiting on a crater run to be completed. label Jun 24, 2026
@craterbot

Copy link
Copy Markdown
Collaborator

🚧 Experiment pr-158320 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot

Copy link
Copy Markdown
Collaborator

🎉 Experiment pr-158320 is completed!
📊 0 regressed and 0 fixed (995573 total)
📊 4655 spurious results on the retry-regressed-list.txt, consider a retry1 if this is a significant amount.
📰 Open the summary report.

⚠️ If you notice any spurious failure please add them to the denylist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

Footnotes

  1. re-run the experiment with crates=https://crater-reports.s3.amazonaws.com/pr-158320/retry-regressed-list.txt

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Jun 28, 2026
@theemathas

Copy link
Copy Markdown
Contributor

The reference has a warning about this that needs to be corrected if this PR were to go through.

@oli-obk oli-obk 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 Jul 6, 2026
@Jules-Bertholet

Jules-Bertholet commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

Stabilization report

This PR allows calling an inherent method on a trait object that shares a name with the method's primary trait. Up to now, this has always failed with an ambiguity error; after this PR, the inherent method shadows the trait method.

Reference PR: rust-lang/reference#2308

What is stabilized

trait Trait {
    fn foo(&self) -> i32 {
        1
    }
}

impl Trait for i32 {}

impl<'a> dyn Trait + 'a {
    fn foo(&self) -> i32 {
        2
    }
}

fn main() {
    let a: &i32 = &3;
    assert_eq!(a.foo(), 1);

    let obj: &(dyn Trait) = a;
    assert_eq!(obj.foo(), 2); // would previously give ambiguity error
    assert_eq!(Trait::foo(obj), 1);
}

What isn't stabilized

Inherent method lookup continues to not peel off auto traits on trait objects.

Continuing our previous example:

let obj2: &(dyn Trait + Send) = a;
assert_eq!(obj2.foo(), 1); // uses trait method

There is a risk that merging this PR now could make this more difficult to fix in the future, because doing so would change the behavior of code like the example above.

@oli-obk

oli-obk commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

@rfcbot fcp merge types

@rust-rfcbot

rust-rfcbot commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

@oli-obk has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rust-rfcbot rust-rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. and removed needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. labels Jul 7, 2026
@lcnr

lcnr commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Was there any specific reason you've working on this. I agree this feels vaguely desirable, but don't have a concrete use case in mind right now.

There are a few interesting cases here 🤔

Which method to use already depends on the self type

trait Trait<T> {
    fn func(&mut self) {
        println!("trait");
    }
}
impl<T> Trait<T> for i32 {}

impl dyn Trait<u32> {
    fn func(&self) {
        println!("inherent");
    }
}

fn foo(mut x: Box<dyn Trait<u32>>) {
    x.func(); // inherent
    (&mut *x).func(); // trait
}

fn main() {
    foo(Box::new(1));
}

This candidate preference guides inference

trait Trait<T> {
    fn func(&self) {
        println!("trait");
    }
}

impl<T> Trait<T> for i32 {}
impl dyn Trait<u32> {
    fn func(&self) {
        println!("inherent");
    }
}

fn foo() {
    let x: Box<dyn Trait<_>> = Box::new(1);
    x.func(); // ambiguity error -> now constrains the infer var to `u32`
}

fn main() {
    foo();
}

Both of these feel acceptable to me and aren't really new issues

@rfcbot reviewed

Also, while I consider this (and want it to be) a bit more Types than Lang, this has definitely a stronger Lang overlap @rust-lang/lang

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-dyn-trait Area: trait objects, vtable layout disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-types Relevant to the types team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Method resolution for trait object types does not prefer inherent methods

8 participants