-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Lint against &T
to &mut T
and &T
to &UnsafeCell<T>
transmutes
#128351
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
Lint against &T
to &mut T
and &T
to &UnsafeCell<T>
transmutes
#128351
Conversation
The Miri subtree was changed cc @rust-lang/miri |
This comment was marked as resolved.
This comment was marked as resolved.
f27dba0
to
d20e89c
Compare
@bors try |
d20e89c
to
5c1d66e
Compare
…e-cell, r= [crater] Lint against &T to &mut T and &T to &UnsafeCell<T> transmutes Needs a (check-only) crater run as per https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Lint.20against.20.60.26.60-.3E.60.26UnsafeCell.60.20transmutes/near/454868964. r? ghost
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
💔 Test failed - checks-actions |
5c1d66e
to
b62dc4c
Compare
This comment has been minimized.
This comment has been minimized.
b62dc4c
to
59c22c3
Compare
@bors try |
…e-cell, r=<try> [crater] Lint against &T to &mut T and &T to &UnsafeCell<T> transmutes Needs a (check-only) crater run as per https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Lint.20against.20.60.26.60-.3E.60.26UnsafeCell.60.20transmutes/near/454868964. r? ghost
This comment has been minimized.
This comment has been minimized.
59c22c3
to
cc72a92
Compare
This comment was marked as resolved.
This comment was marked as resolved.
@bors try |
…e-cell, r=<try> [crater] Lint against &T to &mut T and &T to &UnsafeCell<T> transmutes Needs a (check-only) crater run as per https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Lint.20against.20.60.26.60-.3E.60.26UnsafeCell.60.20transmutes/near/454868964. r? ghost
☀️ Try build successful - checks-actions |
@craterbot check |
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
🚧 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
I'd take a somewhat more broad view of transmuting. Probably I think of that as essentially synonymous with reinterpreting some sequence of bytes as some other type without the presence of any automatic mechanism to reject invalid reinterpretations or to adjust the bytes as needed. So whether we do that with |
I find it bizarre to say that transmuting covers anything other than But even if we accept your definition, this PR lacks internal consistency in its terminology. Sometimes it talks about casts, sometimes about transmuting, sometimes it mentions both. @ChayimFriedman2, can you talk about your understanding of these words and how you have used them? |
Agreed definitely that this PR should be more consistent on this point -- I should have mentioned that. So +1 for catching that in review.
I don't know. I reviewed the Reference text, and I think my definition aligns with it. E.g., it says:
That's directly in line with my remark that:
Elsewhere, it says:
If we were to narrowly define Similarly, in the Nomicon, at the bottom of the page about transmutes, it says:
If we were to say that it's only a "transmute" if you call |
This adds the lint against `&T`->`&UnsafeCell<T>` transmutes, and also check in struct fields, and reference casts (`&*(&a as *const u8 as *const UnsafeCell<u8>)`). The code is quite complex; I've tried my best to simplify and comment it. This is missing one parts: array transmutes. When transmuting an array, this only consider the first element. The reason for that is that the code is already quite complex, and I didn't want to complicate it more. This catches the most common pattern of transmuting an array into an array of the same length with type of the same size; more complex cases are likely not properly handled. We could take a bigger sample, for example the first and last elements to increase the chance that the lint will catch mistakes, but then the runtime complexity becomes exponential with the nesting of the arrays (`[[[[[T; 2]; 2]; 2]; 2]; 2]` has complexity of O(2**5), for instance).
2ea0578
to
ff6a3db
Compare
To me "transmute" is any conversion that changes structures but leaves the bits as-is, and "cast" is specific to |
The job Click to see the possible cause of the failure (guessed by this bot)
|
@rustbot labels +I-lang-nominated The lang FCPed included approval of the name of the lint, so that can't be changed without lang assent. Nominating to discuss. Also, overall, I feel like we've made this PR worse by switching everything to use the word "conversion" when that word is so much more broad. |
Personally I have never seen the word "transmute" used to mean "specifically the function
the
and then uses the word "transmuting" to mean the general concept of a bitwise equivalent value with a different type in future documentation (of which there is a lot) additionally the very start of the docs says
(where this So I would find it odd that you have to use a different phrase to include all semantically equivalent options, even though the namesake of "transmuting" says its equivalent. |
In @rust-lang/opsem we also often use "transmute" to refer to any form of type punning / byte-level reinterpretation of the underlying representation, be it via the |
"It's only a transmute if it's from the transmute region of std; otherwise it's just sparkling unsafety." In all seriousness: I think we should defer to the framing of @rust-lang/opsem here and let "transmute" refer to anything equivalent to a transmute. |
I agree; if it's equivalent to a transmute it's fine to call it a transmute. Especially now that https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/syntax/enum.CastKind.html#variant.Transmute exists in MIR as well, so post-optimization it's possible for things to end up as "literally transmute" even if nobody wrote |
@rustbot labels -I-lang-nominated We discussed this in the lang call today. We agreed that a "transmute" represents the language-level concept, however expressed. We see the library function, For this PR to move forward, the name of the lint should be changed back to that which was FCPed, |
@ChayimFriedman2 I am looking at the diff. Is there a way to refactor this work to make it easier to review? Can this patch be split into smaller, easier to review bits? See our review guidelines. Thanks. |
Much of the discussion can boil down the the following two examples.
The first one is clearly a transmute. AIUI, everyone is saying the second one is also a transmute, albeit one that involves casts (of a pointer, and subsequent dereferencing of that pointer). I guess it makes sense, but I still would find an error message that describes the second one as transmuting a bit surprising. I still think the At this point I will bow out of review duties because I'm about to go on vacation for five weeks. I'm definitely not a T-opsem person, as this whole discussion indicates. My earlier attempt to find an alternative reviewer was met with a crying emoji so I'll let somebody else decide who should review this. Apologies for all the confusion. |
☔ The latest upstream changes (presumably #136024) made this pull request unmergeable. Please resolve the merge conflicts. |
} | ||
|
||
/// The parameters to `report_error` are: breadcrumbs to src's UnsafeCell, breadcrumbs to dst's UnsafeCell. | ||
fn check_unsafe_cells<'tcx>( |
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.
I wonder why the is_freeze
query doesn't work for this?
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.
It can work for finding &
to &UnsafeCell
casts, but not for finding &
to &mut
or &
to &UnsafeCell
inside fields. So we need to have this anyway, given that it's just natural to use it for unsafe cell too.
@ChayimFriedman2 any updates on this? thanks |
I've lost interest in this. If someone wants to take my work, feel free. |
Conversion from
&
to&mut
are and always were immediate UB, and we already lint against them, but until now the lint did not catch the case were the reference was in a field.Conversion from
&
to&UnsafeCell
is more nuanced: Stacked Borrows makes it immediate UB, but in Tree Borrows it is sound.However, even in Tree Borrows it is UB to write into that reference (if the original value was
Freeze
). In all cases crater found where the lint triggered, the reference was written into.Lints (
mutable_transmutes
existed before):Crater summary is below.
cc #111229
r? compiler