-
Notifications
You must be signed in to change notification settings - Fork 70
Fix union field access by representing unions as structs #269
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
Conversation
@simensgreen can you check this fix?
3818aae
to
c93f02e
Compare
When a union has multiple fields, represent it as a struct with all fields at offset 0 instead of just using the largest field. This allows pointer casts between union fields to work correctly by enabling the recover_access_chain_from_offset function to find valid access chains. Fixes Rust-GPU#241.
c93f02e
to
c6c8056
Compare
simensgreen
commented
Jun 4, 2025
@LegNeato Ok, in this simple example it works, but in a more complicated scenario, it will not.
Now I can reproduce both cannot cast between pointer types
and cannot memcpy dynamically sized data
, you can check it out in my repo
Full error messages:
error: cannot cast between pointer types
from `*struct DataMatrix { array1d: [f32; 25], array2d: [[f32; 5]; 5], data_array: [struct Data { a: f32, b: [f32; 3], c: f32 }; 5] }`
to `*[[f32; 5]; 5]`
--> shader/src/lib.rs:35:77
|
35 | pub fn array2d_ref(&self) -> &[[f32; 5]; 5] { unsafe { &self.array2d } }
| ^
|
note: used from within `<shader::DataMatrix>::array2d_ref`
--> shader/src/lib.rs:35:77
|
35 | pub fn array2d_ref(&self) -> &[[f32; 5]; 5] { unsafe { &self.array2d } }
| ^
note: called by `shader::main`
--> shader/src/lib.rs:50:18
|
50 | output[id] = input_matrices[id].array2d_ref()[0];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: cannot memcpy dynamically sized data
--> shader/src/lib.rs:34:54
|
34 | pub fn array2d(self) -> [[f32; 5]; 5] { unsafe { self.array2d } }
| ^^^^^^^^^^^^
|
note: used from within `<shader::DataMatrix>::array2d`
--> shader/src/lib.rs:34:54
|
34 | pub fn array2d(self) -> [[f32; 5]; 5] { unsafe { self.array2d } }
| ^^^^^^^^^^^^
note: called by `shader::main`
--> shader/src/lib.rs:52:18
|
52 | output[id] = input_matrices[id].array2d()[0];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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.
blocked by #270 due to adding a test
Ok, this code is a minefield...back to the drawingboard ha.
When a union has multiple fields, represent it as a struct with all fields at offset 0 instead of just using the largest field. This allows pointer casts between union fields to work correctly by enabling the recover_access_chain_from_offset function to find valid access chains.
Fixes #241.