From 547e55a84e668a287486f9ab6b47d352fe9675a1 Mon Sep 17 00:00:00 2001 From: hecatia-elegua <108802164+hecatia-elegua@users.noreply.github.com> Date: Sun, 23 Jul 2023 16:40:19 +0200 Subject: [PATCH] Show a better error on wrong struct size --- bilge-impl/src/bitsize.rs | 10 ++-------- src/lib.rs | 8 ++++++++ tests/ui/attr-value-does-not-match-size.rs | 9 +++++++++ tests/ui/attr-value-does-not-match-size.stderr | 15 +++++++++++++++ 4 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 tests/ui/attr-value-does-not-match-size.rs create mode 100644 tests/ui/attr-value-does-not-match-size.stderr diff --git a/bilge-impl/src/bitsize.rs b/bilge-impl/src/bitsize.rs index 752f5d7..a8f70a9 100644 --- a/bilge-impl/src/bitsize.rs +++ b/bilge-impl/src/bitsize.rs @@ -145,14 +145,8 @@ fn generate_struct(item: &ItemStruct, declared_bitsize: u8) -> TokenStream { quote! { #vis struct #ident #fields_def - // constness: when we get const blocks evaluated at compile time, add a const computed_bitsize - const _: () = assert!( - (#computed_bitsize) == (#declared_bitsize), - concat!("struct size and declared bit size differ: ", - // stringify!(#computed_bitsize), - " != ", - stringify!(#declared_bitsize)) - ); + // constness: assert_eq!, format! are not const + const _: () = ::bilge::AssertEquals::<{#computed_bitsize}, {#declared_bitsize}>::EQUAL; } } diff --git a/src/lib.rs b/src/lib.rs index 41ddd70..739b482 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,6 +47,14 @@ pub fn give_me_error() -> BitsError { BitsError } +/// This is used in `bitsize.rs` gen, for showing a compile error. +/// Only needed because const contexts can't use `format!` and `COMPUTED_SIZE` is not a plain number. +/// `evaluation of `bilge::AssertEquals::<19, 18>::EQUAL` failed` will tell you what's wrong. +pub struct AssertEquals; +impl AssertEquals { + pub const EQUAL: () = assert!(COMPUTED_SIZE == DECLARED_SIZE, "computed bitsize and declared bitsize differ"); +} + /// Only basing this on Number did not work, as bool and others are not Number. /// We could remove the whole macro_rules thing if it worked, though. /// Maybe there is some way to do this, I'm not deep into types. diff --git a/tests/ui/attr-value-does-not-match-size.rs b/tests/ui/attr-value-does-not-match-size.rs new file mode 100644 index 0000000..807673a --- /dev/null +++ b/tests/ui/attr-value-does-not-match-size.rs @@ -0,0 +1,9 @@ +use bilge::prelude::*; + +#[bitsize(18)] +struct Wrong { + field1: u6, + field2: u13, +} + +fn main() {} diff --git a/tests/ui/attr-value-does-not-match-size.stderr b/tests/ui/attr-value-does-not-match-size.stderr new file mode 100644 index 0000000..f2f5f89 --- /dev/null +++ b/tests/ui/attr-value-does-not-match-size.stderr @@ -0,0 +1,15 @@ +error[E0080]: evaluation of `bilge::AssertEquals::<19, 18>::EQUAL` failed + --> src/lib.rs + | + | pub const EQUAL: () = assert!(COMPUTED_SIZE == DECLARED_SIZE, "computed bitsize and declared bitsize differ"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'computed bitsize and declared bitsize differ', $DIR/src/lib.rs:55:27 + | + = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0080]: evaluation of constant value failed + --> tests/ui/attr-value-does-not-match-size.rs:3:1 + | +3 | #[bitsize(18)] + | ^^^^^^^^^^^^^^ referenced constant has errors + | + = note: this error originates in the attribute macro `bitsize` (in Nightly builds, run with -Z macro-backtrace for more info)