-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Add transmute_slice_to_larger_element_type
lint
#10312
Add transmute_slice_to_larger_element_type
lint
#10312
Conversation
r? @Jarcho (rustbot has picked a reviewer for you, use r? to override) |
3a6b425
to
9288d7f
Compare
(force pushed to revert local change that was try about |
/// Use instead: | ||
/// | ||
/// ```rust | ||
/// let i32_slice: &[i32] = i8_slice.iter().map(|item| unsafe { std::mem::transmute(item) }).collect::<Vec<_>>().to_slice(); |
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.
Have you tried this suggestion? I don't think this will do what you want: this attempts to transmute &i8
to i32
.
Also, isn't the vector you create dropped at the end of the statement? (and don't you mean .as_slice()
?)
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.
Yes, this code does not compile because of the temporary Vec
being dropped, and the transmute
on each element is wrong as well. A "proper" suggestion might be to go through core::slice::from_raw_parts
, but also because of alignment requirements, I don't think it can be an automated suggestion. Perhaps "consider core::slice::from_raw_parts(_mut)
instead" would suffice?
clippy_lints/src/transmute/mod.rs
Outdated
/// or, alternatively: | ||
/// | ||
/// ```rust | ||
/// let i32_slice: &[i32] = std::slice::align_to::<i32>(i8_slice).1; |
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.
Don't you mean unsafe { i8_slice.align_to::<i32>().1 }
?
clippy_lints/src/transmute/transmute_slice_to_larger_element_type.rs
Outdated
Show resolved
Hide resolved
false | ||
} | ||
} else { | ||
false |
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.
You can use if_chain!
to avoid this cascade fo else { false }
(or if let … && let … && …
since feature let_chains
is enabled).
This would be fine without a suggestion. It's more likely that the size needs to change than anything. This would be better as a lint to check if the size changes, not just becomes larger. Both almost certainly do not have the intended result. |
Yes, that will not be what is wanted. However, if slice gets truncated by transmute, it does not cause UB immediately (still may cause: |
It's not instant UB to grow the size either, it depends on the underlying allocation. e.g. let x: [u32; 2] = [0, 1];
let y: &[u64] = transmute(&x[0..1]); // This is 'fine' |
Note that
is not fine, as per Miri. The input slice is only allowed to access the 4 bytes that make up the element from Transmuting a slice to any larger element type is always an error because of this, since the length in elements stays the same, but it tries to access more bytes. This is basically the same as cast_slice_different_sizes, but is immediate UB because it's references. (additionally there's alignment issues and such, but those can be checked/fixed more easily) re: shrinking instead of growing, it's probably useful as a different lint, since it could be intended, but still definitely suspicious, i would be in favor of either warn or deny on such a lint. But this lint is always correct to be |
Looks like this is much more defined than when I last checked (years ago). Both tree and stack borrows definitely set this as ub with references. As a tangential note, it is valid for raw pointers:
I'm still not convinced this is worth a lint separate from just any size changes. Converting to a smaller type without changing the length is incredibly close to certainly wrong. I've never seen a valid use case for it. I can't even imagine what that use case would be. |
☔ The latest upstream changes (presumably #11750) made this pull request unmergeable. Please resolve the merge conflicts. |
Hey @KisaragiEffective this is a ping from triage. Are you planning to continue working on this PR? |
I will, i am not able to decide whether the lint will fire not only larger, but smaller one. The current impl has a bug that suggests take ref on temp, but other parts still can be used. |
Interesting, I would lint that as well. Having If there is a valid use case to transmute |
Hey this is triage, I'm closing this due to inactivity. If you want to continue this implementation, you're welcome to create a new PR. Thank you for the time, you already put into this! Interested parties are welcome to pick this implementation up as well :) @rustbot label +S-inactive-closed -S-waiting-on-author -S-waiting-on-review |
.stderr
file)cargo test
passes locallyfmt
checkcargo dev update_lints
cargo dev fmt
cargo dev fmt
somehow impliedcargo dev fmt --check
close #10285
changelog: New lint: [
transmute_slice_to_larger_element_type
]#10312