sharksforarms / deku

Declarative binary reading and writing: bit-level, symmetric, serialization/deserialization
Apache License 2.0
1.14k stars 55 forks source link

derive(DekuRead) fails if struct has a field named `rest` #365

Closed ghost closed 1 year ago

ghost commented 1 year ago

Minimal repro:

use deku::prelude::*;

#[derive(DekuRead)]
struct Value {
    rest: (),
}

Results in

Error ``` error[E0599]: no method named `len` found for unit type `()` in the current scope --> src/lib.rs:3:10 | 3 | #[derive(DekuRead)] | ^^^^^^^^ method not found in `()` | = note: this error originates in the derive macro `DekuRead` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types --> src/lib.rs:3:10 | 3 | #[derive(DekuRead)] | ^^^^^^^^ expected `&BitSlice`, found `()` | = note: expected reference `&deku::bitvec::BitSlice` found unit type `()` = note: this error originates in the derive macro `DekuRead` (in Nightly builds, run with -Z macro-backtrace for more info) Some errors have detailed explanations: E0308, E0599. For more information about an error, try `rustc --explain E0308`. error: could not compile `deku-rest-repro` (lib) due to 2 previous errors ```

... and, if macro-expanded, results in

Error ``` error[E0433]: failed to resolve: could not find `alloc` in the list of imported crates --> src/lib.rs:17:33 | 17 | let res = ::alloc::fmt::format(format_args!("Too much data")); | ^^^^^ could not find `alloc` in the list of imported crates error[E0554]: `#![feature]` may not be used on the stable release channel --> src/lib.rs:1:1 | 1 | #![feature(prelude_import)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused import: `std::prelude::rust_2021::*` --> src/lib.rs:3:5 | 3 | use std::prelude::rust_2021::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default warning: unused import: `deku::prelude::*` --> src/lib.rs:6:5 | 6 | use deku::prelude::*; | ^^^^^^^^^^^^^^^^ warning: the item `TryFrom` is imported redundantly --> src/lib.rs:30:13 | 30 | use core::convert::TryFrom; | ^^^^^^^^^^^^^^^^^^^^^^ | ::: /home/inty/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/prelude/mod.rs:129:13 | 129 | pub use core::prelude::rust_2021::*; | ------------------------ the item `TryFrom` is already defined here warning: unused import: `core::convert::TryFrom` --> src/lib.rs:30:13 | 30 | use core::convert::TryFrom; | ^^^^^^^^^^^^^^^^^^^^^^ warning: the item `TryFrom` is imported redundantly --> src/lib.rs:65:13 | 65 | use core::convert::TryFrom; | ^^^^^^^^^^^^^^^^^^^^^^ | ::: /home/inty/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/prelude/mod.rs:129:13 | 129 | pub use core::prelude::rust_2021::*; | ------------------------ the item `TryFrom` is already defined here warning: unused import: `core::convert::TryFrom` --> src/lib.rs:65:13 | 65 | use core::convert::TryFrom; | ^^^^^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `len` found for unit type `()` in the current scope --> src/lib.rs:46:44 | 46 | let __deku_pad = 8 * ((__deku_rest.len() + 7) / 8) - __deku_rest.len(); | ^^^ method not found in `()` error[E0599]: no method named `len` found for unit type `()` in the current scope --> src/lib.rs:46:74 | 46 | let __deku_pad = 8 * ((__deku_rest.len() + 7) / 8) - __deku_rest.len(); | ^^^ method not found in `()` error[E0599]: no method named `len` found for unit type `()` in the current scope --> src/lib.rs:47:70 | 47 | let __deku_read_idx = __deku_input_bits.len() - (__deku_rest.len() + __deku_pad); | ^^^ method not found in `()` error[E0308]: mismatched types --> src/lib.rs:78:13 | 78 | Ok((__deku_rest, __deku_value)) | ^^^^^^^^^^^ expected `&BitSlice`, found `()` | = note: expected reference `&deku::bitvec::BitSlice` found unit type `()` Some errors have detailed explanations: E0308, E0433, E0554, E0599. For more information about an error, try `rustc --explain E0308`. warning: `deku-rest-repro` (lib) generated 6 warnings error: could not compile `deku-rest-repro` (lib) due to 6 previous errors; 6 warnings emitted ```

Seems that struct fields are expanded to __deku_IDENT, which shadows (at least) __deku_rest in expanded DekuRead::read impl.