-
Notifications
You must be signed in to change notification settings - Fork 13k
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
What should we do about #[derive(...)]
on #[repr(packed)]
structs?
#39696
Comments
Option 1 would probably be ideal. Option 3 would require a crater run and I think a lot of stuff would fail that. Option 2 would be kinda inefficient for all non-packed structs. I don't know what option 4 even is. |
Can you give an example of the code that would be generated for a |
The way to do (1) or (2) is to move every field into an aligned local and pass a reference to that local instead of a reference to the field. Unfortunately, this is only safe if all the fields are It's maybe possible that it could work for non- |
Those copies are potentially pretty bad implicit behavior if there is a really large field in the packed struct (say, a long array), which is an argument in favor of (3). Another option is (3) plus a crates.io crate using custom derive for |
Every packed struct in winapi manually implements Copy/Clone, so this won't break winapi 0.2.8 nor 0.3, so I'm okay with option 3. Just be sure to do crater runs and have a long warning period. |
Due the limitation that #[derive(...)] on #[repr(packed)] structs does not guarantee proper alignment of the compiler-generated impls is not guaranteed (rust-lang#39696), the change in rust-lang#44646 to compress Spans results in the compiler generating code with unaligned access. Until rust-lang#39696 has been fixed, the issue can be worked around by not using the packed attribute on sparc64 and sparcv9 on the Span struct. Fixes: rust-lang#45509
I think we should make it very easy to do derives on packed, copy structs. There is a bit of a performance footgun to copying into a local variable, but that won't apply to 99% of the structs -- it's a shame to make people write out the impls by hand just because of that. I could imagine having some "flag" that we pass to derive (e.g., (Also, one great thing about the copy solution is that I suspect it greatly mitigates the backwards compat risk here.) |
Option 1a: detect #[repr(packed)] and error out on #[derive(...)] from them not implementing manual Copy/Clone? |
I'm going to close this in favor of #46043. There is already now some handling of this problem in rustc. |
The derived trait instances for packed structs tend to take references to the packed struct fields, which can cause undefined behavior (unaligned loads) and will be detected as unsafe once #27060 is fixed. So, code using these derives on packed structs will stop compiling.
See also #39682 where I fixed impls in a Rust test and #39683 where I fixed an impl in rustc.
Should we:
#[repr(packed)]
(can it?) and change the generated code.cc @Aatch @bluss @retep998 @rust-lang/compiler
The text was updated successfully, but these errors were encountered: