-
Notifications
You must be signed in to change notification settings - Fork 563
Reference updates for forbidding object lifetime changing pointer casts #1951
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
Open
Darksonn
wants to merge
2
commits into
rust-lang:master
Choose a base branch
from
Darksonn:ref-for-136776
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This was referenced Jul 29, 2025
Contributor
Author
traviscross
approved these changes
Aug 5, 2025
Contributor
traviscross
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great. Thanks for the PR.
bors
added a commit
to rust-lang/rust
that referenced
this pull request
Dec 10, 2025
Forbid freely casting lifetime bounds of dyn-types Fixes #136702 Reference PR: - rust-lang/reference#1951 Background reading about VTable calls/dyn compatibility: https://hackmd.io/zUp-sgZ0RFuFgsNfD4JqYw This PR causes us to start enforcing that lifetimes of dyn types are constrained through pointer casts. Currently on stable casting `*mut dyn Trait + 'a` to `*mut dyn Trait + 'b` passes with no requirements on `'a` or `'b`. Under this PR we now require `'a` to outlive `'b`. Even though the pointee of `*mut` pointers is considered to be invariant, we still use subtyping rather than equality. This mirrors how we support coercing `&mut dyn Trait + 'a` to `&mut dyn Trait + 'b` while requiring only `'a: 'b`. I believe this coercion is sound as there is no way for safe code to `mem::swap` two `dyn Trait`'s, and the same is definitely true of raw pointers. See the changes to this test: https://github.com/rust-lang/rust/pull/136776/files#diff-5523f20a800287a89c9f3e92646c887f3f7599be006b29dd9315f734a2137764 We also do not enforce any constraints on the lifetime of the dyn types if there are multiple pointer indirections. For example `*mut *mut dyn Trait + 'a` is allowed to be casted to `*mut *mut dyn Trait + 'b` with no requirements on `'a` or 'b`. This case is just a normal thin pointer cast where we do not care about the pointee type as there is no VTable in play. Test: https://github.com/rust-lang/rust/pull/136776/files#diff-3b6c8da342bb6530524158d686455a545bb8fd6f59cf5ff50d1d991ce74c9649 Finally, this is about *any* cast where the pointee is *unsized* with dyn-type metadata, not just *literally* the pointee type being a dyn-type. E.g. casting `*mut Wrapper<dyn Trait + 'a>` to `*mut Wrapper<dyn Trait + 'b>` requires `'a: 'b` under this PR. Test: https://github.com/rust-lang/rust/pull/136776/files#diff-ca0c44df62ae1ad1be70f892f01a59714336c7baf78602a5887ac1cf81145c96 ### Breakage This is a breaking change. Crater Report Comment: #136776 (comment) Generated Report: https://crater-reports.s3.amazonaws.com/pr-136776-2/index.html The majority of the breakage is caused by the `metrics` crate with 142 of the regressions, and the `may` crate with 14 of the regressions. The `metrics` crate has been fixed and has backported the fix to previous versions of the crate that were also affected. The`may` crate has also been fixed. PRs against affected crates have been opened and can be seen here: - belalang-project/belalang#6 - tyilo/multi-vec#1 - luksan/lox#1 - pfzetto/bring-your-own-memory-demo#1 - vitorhnn/bfr#1 - gipsyh/PPSMC#1 - orengine/orengine#33 - maroider/async_scoped_task#1 - WorldSEnder/scoped_worker_thread#1 - Wind-Corporation/trapiron#5 - Thombrom/snek#1 - Xudong-Huang/may#113 - metrics-rs/metrics#564 - DouglasDwyer/micropool#1 - Magicolo/phylactery#8 - HellButcher/pulz#29 - UxuginPython/rrtk#1 - wvwwvwwv/scalable-delayed-dealloc#4 - ultimaweapon/tsuki#32 There were six regressions I've not filed PRs against: - https://github.com/weiznich/diesel_benches depends on a ~6year old version of diesel (where the regression is) - https://crates.io/crates/cogo/0.1.36 is an old version of cogo, since that release cogo has already been updated to not depend on pattern this PR breaks - https://github.com/cruise-automation/webviz-rust-framework is an archived read only repo so 🤷♀️ - makepad_render, doesn't seem to have source available and is 6 years old 🤷♀️ - outsource-heap - not on github - zaplib - I couldn't get it to compile locally as it failed to compile a dependency r? `@ghost`
github-actions bot
pushed a commit
to rust-lang/miri
that referenced
this pull request
Dec 11, 2025
Forbid freely casting lifetime bounds of dyn-types Fixes rust-lang/rust#136702 Reference PR: - rust-lang/reference#1951 Background reading about VTable calls/dyn compatibility: https://hackmd.io/zUp-sgZ0RFuFgsNfD4JqYw This PR causes us to start enforcing that lifetimes of dyn types are constrained through pointer casts. Currently on stable casting `*mut dyn Trait + 'a` to `*mut dyn Trait + 'b` passes with no requirements on `'a` or `'b`. Under this PR we now require `'a` to outlive `'b`. Even though the pointee of `*mut` pointers is considered to be invariant, we still use subtyping rather than equality. This mirrors how we support coercing `&mut dyn Trait + 'a` to `&mut dyn Trait + 'b` while requiring only `'a: 'b`. I believe this coercion is sound as there is no way for safe code to `mem::swap` two `dyn Trait`'s, and the same is definitely true of raw pointers. See the changes to this test: https://github.com/rust-lang/rust/pull/136776/files#diff-5523f20a800287a89c9f3e92646c887f3f7599be006b29dd9315f734a2137764 We also do not enforce any constraints on the lifetime of the dyn types if there are multiple pointer indirections. For example `*mut *mut dyn Trait + 'a` is allowed to be casted to `*mut *mut dyn Trait + 'b` with no requirements on `'a` or 'b`. This case is just a normal thin pointer cast where we do not care about the pointee type as there is no VTable in play. Test: https://github.com/rust-lang/rust/pull/136776/files#diff-3b6c8da342bb6530524158d686455a545bb8fd6f59cf5ff50d1d991ce74c9649 Finally, this is about *any* cast where the pointee is *unsized* with dyn-type metadata, not just *literally* the pointee type being a dyn-type. E.g. casting `*mut Wrapper<dyn Trait + 'a>` to `*mut Wrapper<dyn Trait + 'b>` requires `'a: 'b` under this PR. Test: https://github.com/rust-lang/rust/pull/136776/files#diff-ca0c44df62ae1ad1be70f892f01a59714336c7baf78602a5887ac1cf81145c96 ### Breakage This is a breaking change. Crater Report Comment: rust-lang/rust#136776 (comment) Generated Report: https://crater-reports.s3.amazonaws.com/pr-136776-2/index.html The majority of the breakage is caused by the `metrics` crate with 142 of the regressions, and the `may` crate with 14 of the regressions. The `metrics` crate has been fixed and has backported the fix to previous versions of the crate that were also affected. The`may` crate has also been fixed. PRs against affected crates have been opened and can be seen here: - belalang-project/belalang#6 - tyilo/multi-vec#1 - luksan/lox#1 - pfzetto/bring-your-own-memory-demo#1 - vitorhnn/bfr#1 - gipsyh/PPSMC#1 - orengine/orengine#33 - maroider/async_scoped_task#1 - WorldSEnder/scoped_worker_thread#1 - Wind-Corporation/trapiron#5 - Thombrom/snek#1 - Xudong-Huang/may#113 - metrics-rs/metrics#564 - DouglasDwyer/micropool#1 - Magicolo/phylactery#8 - HellButcher/pulz#29 - UxuginPython/rrtk#1 - wvwwvwwv/scalable-delayed-dealloc#4 - ultimaweapon/tsuki#32 There were six regressions I've not filed PRs against: - https://github.com/weiznich/diesel_benches depends on a ~6year old version of diesel (where the regression is) - https://crates.io/crates/cogo/0.1.36 is an old version of cogo, since that release cogo has already been updated to not depend on pattern this PR breaks - https://github.com/cruise-automation/webviz-rust-framework is an archived read only repo so 🤷♀️ - makepad_render, doesn't seem to have source available and is 6 years old 🤷♀️ - outsource-heap - not on github - zaplib - I couldn't get it to compile locally as it failed to compile a dependency r? `@ghost`
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
S-waiting-on-stabilization
Waiting for a stabilization PR to be merged in the main Rust repository
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.

This is the reference PR for rust-lang/rust#136776.
I've split this into two commits. The first commit moves the relevant rules from a footnote to the
[expr.as.pointer]section for ease of reading, and the second commit actually makes the rule modification.