Skip to content

Stabilize feature(trait_upcasting) - #134367

Merged
bors merged 8 commits into
rust-lang:masterfrom
WaffleLapkin:trait_upcasting_as_a_treat
Feb 7, 2025
Merged

Stabilize feature(trait_upcasting)#134367
bors merged 8 commits into
rust-lang:masterfrom
WaffleLapkin:trait_upcasting_as_a_treat

Conversation

@WaffleLapkin

@WaffleLapkinWaffleLapkin commented Dec 16, 2024

Copy link
Copy Markdown
Member

This feature was "done" for a while now, I think it's finally time to stabilize it! Stabilization report: #134367 (comment).
cc reference PR: rust-lang/reference#1622.

Closes#65991 (tracking issue), closes#89460 (the lint is no longer future incompat).

r? compiler-errors

@WaffleLapkinWaffleLapkin added T-lang Relevant to the language team F-trait_upcasting `#![feature(trait_upcasting)]` labels Dec 16, 2024
@rustbotrustbot added PG-exploit-mitigations Project group: Exploit mitigations S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Dec 16, 2024
@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in tests/ui/sanitizer

cc @rust-lang/project-exploit-mitigations, @rcvalle

@WaffleLapkinWaffleLapkin added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed PG-exploit-mitigations Project group: Exploit mitigations WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Dec 16, 2024
@compiler-errors

Copy link
Copy Markdown
Contributor

Could you please provide some links that specify what has been done since the last stabilization? Ideally both the issues and the resulting fix PRs.

Ty for doing this tho :)

Gna nominate for T-lang but this should be an easy decision.

@compiler-errorscompiler-errors added I-lang-easy-decision Issue: The decision needed by the team is conjectured to be easy; this does not imply nomination and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 16, 2024
@compiler-errors

Copy link
Copy Markdown
Contributor

And maybe link to the last stabilization too

@rust-log-analyzer

This comment has been minimized.

@rustbotrustbot added PG-exploit-mitigations Project group: Exploit mitigations WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Dec 16, 2024
@rustbot

Copy link
Copy Markdown
Collaborator

The Miri subtree was changed

cc @rust-lang/miri

@WaffleLapkinWaffleLapkin added S-waiting-on-team and removed PG-exploit-mitigations Project group: Exploit mitigations WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Dec 16, 2024
@RalfJungRalfJung added the I-lang-nominated Nominated for discussion during a lang team meeting. label Dec 16, 2024
@WaffleLapkin

WaffleLapkin commented Dec 16, 2024

Copy link
Copy Markdown
MemberAuthor

Stabilization report

The core of the feature hasn't changed since the last attempt to stabilize it.

But as a reminder this feature allows "upcasting" dyn Sub to dyn Super, such as in this example:

traitSub:Super{}traitSuper{}fnupcast(x:&dynSub) -> &dynSuper{
x // implicit coercion}

This is a long wanted feature that people used workarounds for for a long while now.

One possible downside is that this forces us into including more data in the vtables. However, our measurements show that the overhead is mostly negligible. Also note that we ate already including this overhead on stable for countless versions and no one ever complained.

Another possible downside is that this feature this allows upcasting of raw trait pointers in safe code. That puts constraints on their library invariant (safety invariant) -- specifically, even *const dyn Trait must always come with a vtable that is valid for Trait. This was also discussed during previous stabilization attempts, but still, something to keep in mind.

I believe that the feature is well tested and is ready for stabilization.

Previous stabilization attempt problems

After the last attempt to stabilize this feature @steffahn found two unsound interactions between trait upcasting and pointer casting (one of which also required feature(arbitrary_self_types)): #120222 and #120217. This caused a revert of the stabilization PR.

Both issues were since fixed in #120248 by adding additional checks for casting pointers, to uphold the library invariant of pointers to trait objects which is needed for this feature.

No new issues were found since.

After this comment @steffahn found another soundness issue: #135315, which was then promptly fixed by @compiler-errors in #135318.

No new issues were found since.

@WaffleLapkinWaffleLapkin removed the I-lang-nominated Nominated for discussion during a lang team meeting. label Dec 16, 2024
@WaffleLapkin

Copy link
Copy Markdown
MemberAuthor

(@RalfJung I'm pretty sure I-lang-easy-decisionIssue: The decision needed by the team is conjectured to be easy; this does not imply nomination implies nomination and you don't need I-lang-nominatedNominated for discussion during a lang team meeting. )

@RalfJung

RalfJung commented Dec 16, 2024

Copy link
Copy Markdown
Member

@traviscross told me the opposite -- it still needs to be nominated with the regular label.

The label description should probably clarify or else people will inevitably keep getting this wrong.

@RalfJung

RalfJung commented Dec 16, 2024

Copy link
Copy Markdown
Member

The only possible downside

That's a very strong statement.^^

I'd say there is at least one other downside, or point worth mentioning: this allows upcasting of raw trait pointers in safe code. That puts constraints on their library invariant (safety invariant) -- specifically, even *const dyn Trait must always come with a vtable that is valid for Trait.

I'm fine with that, and AFAIK @rust-lang/types agrees, but it is a choice we are making here that should be called out explicitly. @rust-lang/opsem is still discussing what to do with the language invariant for raw trait pointers; having that be different from the library invariant is likely surprising but OTOH we still might want a weaker invariant here.

@WaffleLapkinWaffleLapkin added the I-lang-nominated Nominated for discussion during a lang team meeting. label Dec 16, 2024
@WaffleLapkin

Copy link
Copy Markdown
MemberAuthor

@RalfJung I did call this out, but maybe not explicitly enough ("the only" slipped from an earlier draft). I've updated the wording to more clearly highlight this.

@rust-log-analyzer

This comment was marked as outdated.

(so that it doesn't talk about trait upcasting stabilization in the
future tense)
We can't remove `TraitUpcasting` variant, since we need to use the index
in winnowing.
this commit makes `deref_into_dyn_supertrait` lint allow-by-default,
removes future incompatibility (we finally live in a broken world), and
changes the wording in the documentation.
previously documentation erroneously said that it lints against *usage*
of the deref impl, while it actually (since 104742) lints on the impl
itself (oooops, my oversight, should have updated it 2+ years ago...)
@WaffleLapkin
WaffleLapkinforce-pushed the trait_upcasting_as_a_treat branch from 1aac2f1 to 4915995CompareFebruary 6, 2025 23:38
@rustbotrustbot added PG-exploit-mitigations Project group: Exploit mitigations WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Feb 6, 2025
@WaffleLapkinWaffleLapkin removed PG-exploit-mitigations Project group: Exploit mitigations WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Feb 6, 2025
@WaffleLapkin

Copy link
Copy Markdown
MemberAuthor

With that, I think we can finally

bors r plus

@bors

bors commented Feb 6, 2025

Copy link
Copy Markdown
Collaborator

📌 Commit 4915995 has been approved by compiler-errors

It is now in the queue for this repository.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Feb 7, 2025
…treat, r=compiler-errors
Stabilize `feature(trait_upcasting)`
This feature was "done" for a while now, I think it's finally time to stabilize it! Stabilization report: rust-lang#134367 (comment).
cc reference PR: rust-lang/reference#1622.
Closesrust-lang#65991 (tracking issue), closesrust-lang#89460 (the lint is no longer future incompat).
r? compiler-errors
This was referenced Feb 7, 2025
@gabrielecastellano

Copy link
Copy Markdown

Hello! As this feature was initially stabilized and merged more than 1 year ago #118133, I am a bit confused about the workflow of rust toolchains. I was wondering if someone could explain how it works, i mean why this ended up to be tracked for milestone 1.86 instead, of e.g., 1.76 one year ago. Thanks!

@Kobzol

Copy link
Copy Markdown
Member

Because the initial stabilization was later reverted: #120233

@gabrielecastellano

Copy link
Copy Markdown

Because the initial stabilization was later reverted: #120233

Completely missed that. Now it is very clear :)

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

Labels

disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.F-trait_upcasting`#![feature(trait_upcasting)]`finished-final-comment-periodThe final comment period is finished for this PR / Issue.relnotesMarks issues that should be documented in the release notes of the next release.S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-langRelevant to the language team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tracking issue for future-incompatibility lint deref_into_dyn_supertrait Tracking issue for dyn upcasting coercion

19 participants

@WaffleLapkin@rustbot@compiler-errors@rust-log-analyzer@RalfJung@nikomatsakis@rfcbot@traviscross@scottmcm@tmandry@Veykril@bors@theemathas@steffahn@kellerkindt@gabrielecastellano@Kobzol@lukas-code@jackh726