Skip to content
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

const-ify casting functions #280

Open
kovaxis opened this issue Oct 19, 2024 · 2 comments
Open

const-ify casting functions #280

kovaxis opened this issue Oct 19, 2024 · 2 comments

Comments

@kovaxis
Copy link

kovaxis commented Oct 19, 2024

I don't know if it's possible, but it would be great if the bytemuck::cast* functions where const fn so that we could include_bytes! into a struct or a list of structs.

@zachs18
Copy link
Contributor

zachs18 commented Oct 19, 2024

The by-value bytemuck::cast could probably be made const (under a feature gate), like bytemuck::must_cast, though this would AFAICT require changing how the panic message is made for cast1.

The by-immutable-ref cast_ref and cast_slice would have the issue that converting pointers to integers (to check alignment) is not necessarily possible in const eval.2 (Though the size checks are dependant on pointer addresses, so could be implemented in consteval just fine (except for 1).)

Note that the by-immutable-ref must_cast_ref and must_cast_slice functions are const, and they can be because they are intentionally more conservative in that they only accept casts that cannot fail (e.g. &[u16] -> &[u8] is fine, but not &[u8] -> &[u16] since the input pointer could be unaligned, which we can't check in const eval, and &[u8] -> &[[u8; 2]] is not fine, since the length could be odd, though this could be checked in const-eval, just not in the type system).

Because of this, must_cast_slice is probably not useful for include_bytes!ing struct data. However, include_bytes! gives an array, so theoretically you could use by-value must_cast if you know the length of the data.

Footnotes

  1. since you can't do panic!("{}", non_string_literal) in const fn, which is currently used, so without something like const_eval_select on stable the runtime impl would have to be the same as the const impl. 2

  2. cast_mut and cast_slice_mut have the same issue, and also they are also blocked on feature(const_mut_refs) which IIUC is planned to become stable in Rust 1.83.0.

@Lokathor
Copy link
Owner

What I've done for byte including before is
https://docs.rs/gba/latest/gba/struct.Align4.html
and also
https://docs.rs/gba/latest/gba/macro.include_aligned_bytes.html

the included bytes are actually an array to start, so the Align4 can take the array by value, align it to 4 (which adds padding if it's not a multiple of 4 in length!), and then your data could be transmuted to u32 or whatever.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants