bytemuck
bytemuck copied to clipboard
Potential rustc bug related to deriving ByteEq
Right off the bat, here's the minimum reproducible example: Cargo.toml:
[package]
name = "bug_rep"
version = "0.1.0"
edition = "2021"
[dependencies]
bytemuck = { version = "1.14.0", features = ["derive"] }
#[derive(bytemuck::ByteEq)]
pub struct Magnitude<const BYTES: usize>([u8; 0]);
The bug still occurs identically if swapping out bytemuck::ByteEq
for bytemuck::ByteHash
.
The error from cargo check
is:
error[E0107]: missing generics for struct `Magnitude`
--> src/lib.rs:2:12
|
2 | pub struct Magnitude<const BYTES: usize>([u8; 0]);
| ^^^^^^^^^ expected 1 generic argument
|
note: struct defined here, with 1 generic parameter: `BYTES`
--> src/lib.rs:2:12
|
2 | pub struct Magnitude<const BYTES: usize>([u8; 0]);
| ^^^^^^^^^ ------------------
help: add missing generic argument
|
2 | pub struct Magnitude<BYTES><const BYTES: usize>([u8; 0]);
| +++++++
For more information about this error, try `rustc --explain E0107`.
error: could not compile `bug_rep` (lib) due to 2 previous errors
Following it's inane suggestion, unsurprisingly, does not fix the issue.
I got this from the rather more reasonable code:
[package]
name = "magnitude"
version = "0.1.0"
edition = "2021"
[dependencies]
bytemuck = { version = "1.14.0", features = ["derive", "min_const_generics"] }
#[derive(Clone, Copy, bytemuck::Zeroable, bytemuck::Pod, bytemuck::ByteEq, bytemuck::ByteHash)]
#[repr(transparent)]
pub struct Magnitude<const BYTES: usize>([u8; BYTES]);
Which gives an identical error message other than that it shows the longer source code.
Checking magnitude v0.1.0 (/home/lily/dev/magnitude)
error[E0107]: missing generics for struct `Magnitude`
--> src/static_precision/mod.rs:3:12
|
3 | pub struct Magnitude<const BYTES: usize>([u8; BYTES]);
| ^^^^^^^^^ expected 1 generic argument
|
note: struct defined here, with 1 generic parameter: `BYTES`
--> src/static_precision/mod.rs:3:12
|
3 | pub struct Magnitude<const BYTES: usize>([u8; BYTES]);
| ^^^^^^^^^ ------------------
help: add missing generic argument
|
3 | pub struct Magnitude<BYTES><const BYTES: usize>([u8; BYTES]);
| +++++++
For more information about this error, try `rustc --explain E0107`.
error: could not compile `magnitude` (lib) due to 3 previous errors
Considering how inane the suggestion from rustc is, I suspect this may actually be a compiler bug, but I want to get a second opinion before I go opening an issue claiming a compiler error, especially for code involving macros I didn't write.
(cargo expand
output on the example given above)
#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
pub struct Magnitude<const BYTES : usize>([u8; 0]);
impl ::core::cmp::PartialEq for Magnitude {
#[inline]
#[must_use]
fn eq(&self, other: &Self) -> bool {
::bytemuck::bytes_of(self) == ::bytemuck::bytes_of(other)
}
}
impl ::core::cmp::Eq for Magnitude {}
This isn't a compiler bug, the ByteEq
derive macro doesn't currently emit generics on the PartialEq and Eq impls (which it probably should, or should emit an error that it doesn't support generics).
Opened a PR to allow deriving ByteEq
and ByteHash
for types with generics.
Note that ByteEq
and ByteHash
require the type implement NoUninit
, which cannot currently be derived for generic structs, and must be manually verified to be correct and implemented.