-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Add lint on reference-to-pointer transmutes #124865
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
Comments
I recommend not offering such a suggestion in this case. People are often too quick to accept suggestions that successfully remove warnings, and it would be bad to transform simple wrong code into complex wrong code. |
Why are none of the options "use a coercion"? In code review I would generally prefer this over |
@digama0 I was assuming that if they wrote a transmute specifically then it's not a place where a coercion work, as presumably they would have tried that first. Even if it would, I think I'd rather suggest a function here that doesn't need changing the flow of things (or adding a Maybe if we had stable type ascription I'd lean that way, but since we don't, I like recommending the methods here for the same reason that Ralf added them in #104977. After all, even coercions can be footguns, as seen with the |
Yes, we should almost certainly lint on the last case precisely because the coercion is also wrong. |
@scottmcm The original bugfix which started this is exactly a case where the right solution was to use a coercion, but mind you a coercion from
I'm not suggesting type ascriptions or anything like that, I mean when using the coercion alone with no additional annotation does the right thing according to our analysis of the situation in the given context (no changed types, no |
I tried, sometime ago, to add a lint that would do that, but ran into a issue,
because recommending fn main() {
let _: *mut i32 = &mut 1 as *mut _; // this line is fine
let _: *mut i32 = std::ptr::from_mut(&mut 1); // but this one isn't, the
// pointer is dangling
} the solution to that would be to have temporary like this: fn main() {
let tmp0 = &mut 1;
let _: *mut i32 = std::ptr::from_mut(tmp0);
} but this begs the question of usability. |
That's not a transmute. |
Inspired by #124861, specifically glium/glium@ebdc18e
There's no reason to use an unsafe transmute to get a pointer from a reference, and as that code example shows it can easily hide bugs. We should (at least) warn about it.
&T
to*const T
, recommend https://doc.rust-lang.org/std/ptr/fn.from_ref.html (machine-applicable, because it's always right)&mut T
to*mut T
, recommend https://doc.rust-lang.org/std/ptr/fn.from_mut.html (machine-applicable, because it's always right)&T
to*mut T
, recommendfrom_ref
+cast_mut
, but not auto-applicable because we should comment that it's probably wrong, and they probably wantfrom_mut
instead, but that will require larger reworking of the code.&mut T
to*const T
, recommend https://doc.rust-lang.org/std/ptr/fn.from_mut.html with a note that in a generic context it might also need.cast_const()
.The text was updated successfully, but these errors were encountered: