hashmismatch / packed_struct.rs

Bit-level packing and unpacking for Rust
MIT License
164 stars 30 forks source link

Expected an array with a fixed size of 4 elements, found one with 8 elements? #83

Closed VisualEhrmanntraut closed 3 years ago

VisualEhrmanntraut commented 3 years ago
error[E0308]: mismatched types
  --> src/vmcb/vmcb_control/mod.rs:10:10
   |
10 | #[derive(PackedStruct, Debug, PartialEq)]
   |          ^^^^^^^^^^^^ expected an array with a fixed size of 4 elements, found one with 8 elements
   |
   = note: this error originates in the derive macro `PackedStruct` (in Nightly builds, run with -Z macro-backtrace for more info)

Getting the above error on this piece of code: http://hastebin.com/puwogalutu.rust

rudib commented 3 years ago

If I remove the fields for the two fields which don't have their source code in that file (VmcbCleanBits and TlbControl), then it compiles just fine. One issue could be is that VmcbCleanBits is actually 4 bytes wide but you have it referenced here as 8?

VisualEhrmanntraut commented 3 years ago

Oh, oops. That fixed it. But I've got another issue now:

#[derive(PackedStruct, Debug, PartialEq)]
#[packed_struct(bit_numbering = "msb0", endian = "lsb")]
pub struct Vmcb {
    #[packed_field(bits = "0..", size_bytes = "0x3FF")]
    pub control: VmcbControl,
}

gives

error[E0308]: mismatched types
 --> src/vmcb/mod.rs:8:10
  |
8 | #[derive(PackedStruct, Debug, PartialEq)]
  |          ^^^^^^^^^^^^ expected an array with a fixed size of 1018 elements, found one with 1023 elements
  |
  = note: this error originates in the derive macro `PackedStruct` (in Nightly builds, run with -Z macro-backtrace for more info)
rudib commented 3 years ago

I guess it's a similar issue, you assume that the packed size of the structure is exactly 0x3FF, but it actually isn't - maybe some fields are missing or they have incorrect widths. I'd first build the docs for your big structure using cargo doc and check if the generated fields match what you are expecting.

Also, an option is to enforce the width of the structure using the size_bytes struct attribute. So something like:

#[packed_struct(bit_numbering = "msb0", endian = "lsb", size_bytes="0x3FF")]
pub struct VmcbControl {
}

But for both of the issues which you've encountered, I think that we could emit user-friendly compiler exceptions, because of the newly added const generics. Asserting on the expected and actual byte widths could give a helpful error message.

VisualEhrmanntraut commented 3 years ago

Now clippy gives me a bunch of errors like

error: used binding `_reserved` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
rudib commented 3 years ago

That's probably because it uses the exact same names for temporary variables in the generated code, but since your structures have prefixed reserved fields, clippy emits that error. I'd assume that you should add another exception for this structure at the top.

Obviously, this is outside the scope of this bug report, so closing this issue.