Comments (16)
Such a derive would have to live in its own crate because of how proc-macros work.
If someone makes the proc-macro for it I'll link to their work, but I basically don't want to do it myself.
from bytemuck.
I am going to implement a derive macro for Zeroable
.
It will be a separate set of crates (a proc-macro crate,and a library crate that re-exports it) for now.
from bytemuck.
I'm happy to advertise it in the readme/lib here.
Zeroable seems easier, Pod seems trickier.
from bytemuck.
I created the zeroable crate that exposes a Zeroable
derive macro for the bytemuck::Zeroable
trait.
The macro has some limitations which are described in the docs.
from bytemuck.
I've been hacking on this, as I'd need it to use bytemuck reasonably at work.
I took a look at @rodrimati1992 Zeroable derive and I think some of the cases it allows could be unsound, especially if you include things like the attributes, especially #[zero(not_zeroable())]
which AFAICT really should have unsafe
in its name (as it's possible for users to use it in an unsound way).
A lot of effort was spent on it clearly, but I think too much work was spent on trying to make the derive usable for all cases. IMO for cases which aren't obviously correct, the solution has to be to force the user to manually implement unsafe trait Zeroable
. Ditto Pod (and Contiguous
in #12 if it is accepted)
from bytemuck.
@thomcc Aside from using the Zeroable derive macro with unions,is there anything unsound about it?
If you feel strongly enough about the soundness of union attributes,you should create an issue in here.
I didn't feel like the union attributes needed an unsafe prefix,since accessing union fields is already unsafe(you have to ensure that the field has a valid value for its type).
One thing you could say is that the Zeroable derive should not allow non-Zeroable fields on unions,the same way that it doesn't allow them with structs,and require users to manually implement the trait otherwise.This would make it easier to tell whether it's safe to access a zeroed union field,since it would always be safe with the derive that way,rather than just being the default.
from bytemuck.
I would say that if I have a type Foo
that I can derive Zeroable
on, and it doesn't need an unsafe
somewhere to do it, then if I can do let x: Foo = mem::zero();
and get an invalid Foo
the Zeroable
derive is not sound.
from bytemuck.
It's not possible to get UB in code using the Zeroable derive macro,with struct
s or enum
s.
With union
s you can get UB in unsafe
code,if you marked a field as being not-zeroable,and yet access it anyway afterwards.
from bytemuck.
like union { a: usize, b: NonZeroUsize }
?
from bytemuck.
Like:
#[derive(Zeroable)]
union Dummy{
a:usize,
#[zero(nonzero)]
b:NonZeroUsize,
}
let um=Dummy::zeroed();
unsafe{
println!("{}",um.b); // whoops,this field is not zeroable
}
This is what I think thomcc was describing when talking about allowing unsound code.
from bytemuck.
I merged #30, which added this to the repo.
I've since published the bytemuck_derive crate as an alpha release (technically 1.0.0-alpha.2
), and I want to give people a little time to make sure things are fully working before declaring it a real 1.0 release.
Currently you can should be able to use the crate on its own without bytemuck
having a derive
feature by doing the following in Cargo.toml
:
[dependencies]
bytemuck_derive = "1.0.0-alpha.2"
And then in your code:
use bytemuck_derive::{Zeroable, Pod, TransparentWrapper};
@LPGhatguy in the PR you expressed interest in using this with your stuff, could you try things out and report back?
from bytemuck.
Will do! I should have some time tomorrow.
from bytemuck.
The derives seem pretty good and functional. They caught a couple oversights in my codebase, actually!
However, the error messages aren't great. If there's padding in the struct, you'll get an error message like this:
Is this something that's fixable? If now not, can it be something we can fix later?
from bytemuck.
hmm.
what's the struct definition?
and what sort of error message would you expect?
from bytemuck.
I lost the original struct, but here's one that gives an error message with different numbers:
#[repr(C)]
#[derive(Clone, Copy, Zeroable, Pod)]
struct Oopsie {
pub first: u16,
pub second: f32,
}
I would want the macro to tells me I have padding, and ideally where it is!
from bytemuck.
Ah, okay, so that's checked for here
https://github.com/Lokathor/bytemuck/blob/main/derive/src/traits.rs#L209-L225
and I can kinda tell how that's turning into the error message you see, but i'm not a proc-macro pro so I'm not sure how to make the error message better than it currently is.
from bytemuck.
Related Issues (20)
- Raw pointer cast functions HOT 4
- Cannot use derive macros when reexporting bytemuck from library HOT 2
- Crate makes assumptions about bool values HOT 5
- Safe `offset_of` for packed structs using `addr_of`? HOT 9
- `ASSERT_SIZE_MULTIPLE_OF` when casting `&[u8]` to `&[[u8; 16]]` HOT 1
- Crate documentation is misleading, implies `Pod` required for all functions. HOT 3
- the `FooBits` type generated by `#[derive(CheckedBitPattern)]` should implement `NoUninit` if `Self` is `NoUninit` HOT 3
- False positive derive error for `TransparentWrapper` around types like `Box` HOT 1
- Potential rustc bug related to deriving ByteEq HOT 2
- no-uninit trait with interior mutability HOT 6
- Deriving Pod for arbitrary generic types HOT 1
- Why use from_bytes when you can use pod_read_unaligned? HOT 5
- Build error on nightly-2024-02-05 HOT 1
- Bytemuck 1.14.2 does not build on stable HOT 1
- Feature request: Casting owned slices or vec, I.e. Box<[u64]> to Box<[u8]> or Vec<u64> to Vec<u8> HOT 4
- conversion from `&[u8]` to `&[T]`? HOT 4
- Allow deriving `Zeroable` for enums which are `#[repr(u32, i8, etc..)]` HOT 2
- Address safety invariants in documentation HOT 1
- No documentation for the FooBits public type generated by derive(CheckedBitPattern) HOT 1
- Casts and conversions for owned, boxed slices HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bytemuck.