-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
UnsafeCell
blocks niches inside its nested type from being available outside
#99011
Conversation
Some changes occurred to the CTFE / Miri engine cc @rust-lang/miri Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
Some changes occurred in src/tools/clippy cc @rust-lang/clippy |
r? @davidtwco (rust-highfive has picked a reviewer for you, use r? to override) |
UnsafeCell
now has no niches, ever.UnsafeCell
now has no niches, not even transitively
UnsafeCell
now has no niches, not even transitivelyUnsafeCell
blocks niches inside its nested type from being available outside
Please make sure this is covered by tests. #87341 has a nice test set at the top. |
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.
LGTM (modulo the comment I left about handling all Abi
s, and tests ofc).
IMO limiting this to UnsafeCell
is more reasonable than #[repr(no_niche)]
.
The question I ask myself is: why would anyone want #[repr(no_niche)]
without the semantics of UnsafeCell
and/or MaybeUninit
?
I can only think of layout/ABI misuses (that would be defeated by layout randomization), I can't imagine that there's a way to have unsafe code that would only need #[repr(no_niche)]
(and nothing else) to both have no UB, and work under layout randomization.
|
||
// Update `largest_niche` if we have introduced a larger niche. | ||
let niche = if def.repr().hide_niche() { | ||
None | ||
if def.is_unsafe_cell() { | ||
match scalar { | ||
Scalar::Initialized { value, valid_range } => { | ||
*valid_range = WrappingRange::full(value.size(dl)) | ||
} | ||
// Already doesn't have any niches | ||
Scalar::Union { .. } => {} | ||
} | ||
st.largest_niche = None; |
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 like the original code got misplaced into the #[rustc_layout_scalar_valid_range]
handling, instead of being separate.
I think it should be moved out and made to exhaustively handle all Abi
s.
More specifically, Abi::{Scalar,ScalarPair,Vector}
) all have Scalar
s in them - and even if ScalarPair
appears to be handled, note that you're only operating its first Scalar
.
So when testing, make sure to also check UnsafeCell
around pairs with niches in both sides of the pair and custom #[repr(simd)]
structs with niche'd element types.
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.
custom #[repr(simd)] structs with niche'd element types.
I tried, we have checks preventing such datastructures from existing at all. So this can't happen.
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.
The checks are not perfect: https://godbolt.org/z/W8o3Gxhdo.
r? @eddyb |
I didn't add those as we already had equivalent tests in rust/src/test/ui/layout/unsafe-cell-hides-niche.rs Lines 20 to 28 in 2a899dc
I'll add the libstd type tests for completeness now |
…n the layout_scalar_valid_range logic
@rustbot review |
That test already passed before this PR. So it cannot be testing the right thing. |
@bors r=eddyb |
`UnsafeCell` blocks niches inside its nested type from being available outside fixes rust-lang#87341 This implements the plan by `@eddyb` in rust-lang#87341 (comment) Somewhat related PR (not strictly necessary, but that cleanup made this PR simpler): rust-lang#94527
`UnsafeCell` blocks niches inside its nested type from being available outside fixes rust-lang#87341 This implements the plan by ``@eddyb`` in rust-lang#87341 (comment) Somewhat related PR (not strictly necessary, but that cleanup made this PR simpler): rust-lang#94527
@bors r=eddyb |
Rollup of 5 pull requests Successful merges: - rust-lang#98574 (Lower let-else in MIR) - rust-lang#99011 (`UnsafeCell` blocks niches inside its nested type from being available outside) - rust-lang#99030 (diagnostics: error messages when struct literals fail to parse) - rust-lang#99155 (Keep unstable target features for asm feature checking) - rust-lang#99199 (Refactor: remove an unnecessary `span_to_snippet`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
`UnsafeCell` blocks niches inside its nested type from being available outside fixes rust-lang#87341 This implements the plan by `@eddyb` in rust-lang#87341 (comment) Somewhat related PR (not strictly necessary, but that cleanup made this PR simpler): rust-lang#94527
Rollup of 5 pull requests Successful merges: - rust-lang#98574 (Lower let-else in MIR) - rust-lang#99011 (`UnsafeCell` blocks niches inside its nested type from being available outside) - rust-lang#99030 (diagnostics: error messages when struct literals fail to parse) - rust-lang#99155 (Keep unstable target features for asm feature checking) - rust-lang#99199 (Refactor: remove an unnecessary `span_to_snippet`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Rollup of 5 pull requests Successful merges: - rust-lang#98574 (Lower let-else in MIR) - rust-lang#99011 (`UnsafeCell` blocks niches inside its nested type from being available outside) - rust-lang#99030 (diagnostics: error messages when struct literals fail to parse) - rust-lang#99155 (Keep unstable target features for asm feature checking) - rust-lang#99199 (Refactor: remove an unnecessary `span_to_snippet`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
fixes #87341
This implements the plan by @eddyb in #87341 (comment)
Somewhat related PR (not strictly necessary, but that cleanup made this PR simpler): #94527