diff --git a/deku-derive/src/lib.rs b/deku-derive/src/lib.rs index 13abbe7b..3442a6f1 100644 --- a/deku-derive/src/lib.rs +++ b/deku-derive/src/lib.rs @@ -1,11 +1,13 @@ /*! Procedural macros that implement `DekuRead` and `DekuWrite` traits */ - #![warn(missing_docs)] -use std::borrow::Cow; +extern crate alloc; + +use alloc::borrow::Cow; use std::convert::TryFrom; +use std::fmt::Display; use darling::{ast, FromDeriveInput, FromField, FromMeta, FromVariant, ToTokens}; use proc_macro2::TokenStream; @@ -25,9 +27,9 @@ enum Id { Int(syn::LitInt), } -impl ToString for Id { - fn to_string(&self) -> String { - self.to_token_stream().to_string() +impl Display for Id { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.to_token_stream().to_string()) } } @@ -73,9 +75,9 @@ impl Num { } } -impl ToString for Num { - fn to_string(&self) -> String { - self.0.to_token_stream().to_string() +impl Display for Num { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.0.to_token_stream().to_string()) } } @@ -267,14 +269,12 @@ impl DekuData { /// Emit a reader. On error, a compiler error is emitted fn emit_reader(&self) -> TokenStream { - self.emit_reader_checked() - .map_or_else(|e| e.to_compile_error(), |tks| tks) + self.emit_reader_checked().unwrap_or_else(|e| e.to_compile_error()) } /// Emit a writer. On error, a compiler error is emitted fn emit_writer(&self) -> TokenStream { - self.emit_writer_checked() - .map_or_else(|e| e.to_compile_error(), |tks| tks) + self.emit_writer_checked().unwrap_or_else(|e| e.to_compile_error()) } /// Same as `emit_reader`, but won't auto convert error to compile error diff --git a/deku-derive/src/macros/deku_read.rs b/deku-derive/src/macros/deku_read.rs index 37199b86..a7527027 100644 --- a/deku-derive/src/macros/deku_read.rs +++ b/deku-derive/src/macros/deku_read.rs @@ -275,12 +275,14 @@ fn emit_enum(input: &DekuData) -> Result { if !has_default_match && default_reader.is_none() { variant_matches.push(quote! { _ => { + extern crate alloc; + use alloc::borrow::Cow; return Err(::#crate_::DekuError::Parse( - format!( + Cow::from(format!( "Could not match enum variant id = {:?} on enum `{}`", __deku_variant_id, #ident_as_string - ) + )) )); } }); @@ -440,7 +442,9 @@ fn emit_magic_read(input: &DekuData) -> TokenStream { for __deku_byte in __deku_magic { let __deku_read_byte = u8::from_reader_with_ctx(__deku_reader, ())?; if *__deku_byte != __deku_read_byte { - return Err(::#crate_::DekuError::Parse(format!("Missing magic value {:?}", #magic))); + extern crate alloc; + use alloc::borrow::Cow; + return Err(::#crate_::DekuError::Parse(Cow::from(format!("Missing magic value {:?}", #magic)))); } } } @@ -514,11 +518,13 @@ fn emit_padding(bit_size: &TokenStream) -> TokenStream { { use core::convert::TryFrom; // TODO: I hope this consts in most cases? + extern crate alloc; + use alloc::borrow::Cow; let __deku_pad = usize::try_from(#bit_size).map_err(|e| - ::#crate_::DekuError::InvalidParam(format!( + ::#crate_::DekuError::InvalidParam(Cow::from(format!( "Invalid padding param \"({})\": cannot convert to usize", stringify!(#bit_size) - )) + ))) )?; @@ -820,7 +826,9 @@ pub fn emit_try_from( let mut cursor = ::#crate_::no_std_io::Cursor::new(input); let (amt_read, res) = ::from_reader((&mut cursor, 0))?; if (amt_read / 8) != total_len { - return Err(::#crate_::DekuError::Parse(format!("Too much data"))); + extern crate alloc; + use alloc::borrow::Cow; + return Err(::#crate_::DekuError::Parse(Cow::from("Too much data"))); } Ok(res) } diff --git a/deku-derive/src/macros/deku_write.rs b/deku-derive/src/macros/deku_write.rs index 12ae7063..3f3b90fe 100644 --- a/deku-derive/src/macros/deku_write.rs +++ b/deku-derive/src/macros/deku_write.rs @@ -414,11 +414,13 @@ fn emit_padding(bit_size: &TokenStream) -> TokenStream { quote! { { use core::convert::TryFrom; + extern crate alloc; + use alloc::borrow::Cow; let __deku_pad = usize::try_from(#bit_size).map_err(|e| - ::#crate_::DekuError::InvalidParam(format!( + ::#crate_::DekuError::InvalidParam(Cow::from(format!( "Invalid padding param \"({})\": cannot convert to usize", stringify!(#bit_size) - )) + ))) )?; __deku_writer.write_bits(::#crate_::bitvec::bitvec![u8, ::#crate_::bitvec::Msb0; 0; __deku_pad].as_bitslice())?; } diff --git a/deku-derive/src/macros/mod.rs b/deku-derive/src/macros/mod.rs index f5fbf401..8853dc45 100644 --- a/deku-derive/src/macros/mod.rs +++ b/deku-derive/src/macros/mod.rs @@ -372,12 +372,14 @@ fn assertion_failed( #[cfg(not(feature = "no-assert-string"))] { quote! { - return Err(::#crate_::DekuError::Assertion(format!( + extern crate alloc; + use alloc::borrow::Cow; + return Err(::#crate_::DekuError::Assertion(Cow::from(format!( "{}.{} field failed assertion: {}", #ident, #field_ident_str, #stringify, - ))); + )))); } } } diff --git a/src/error.rs b/src/error.rs index 4ba1286a..5c2151c8 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,9 +1,11 @@ //! Error module #![cfg(feature = "alloc")] +use alloc::borrow::Cow; + +use no_std_io::io::ErrorKind; use alloc::format; -use alloc::string::String; /// Number of bits needed to retry parsing #[derive(Debug, Clone, PartialEq, Eq)] @@ -38,30 +40,28 @@ pub enum DekuError { /// Parsing error when reading Incomplete(NeedSize), /// Parsing error when reading - Parse(String), + Parse(Cow<'static, str>), /// Invalid parameter - InvalidParam(String), - /// Unexpected error - Unexpected(String), + InvalidParam(Cow<'static, str>), /// Assertion error from `assert` or `assert_eq` attributes - Assertion(String), + Assertion(Cow<'static, str>), /// Assertion error from `assert` or `assert_eq` attributes, without string AssertionNoStr, /// Could not resolve `id` for variant IdVariantNotFound, - /// IO error while writing - Write, + /// IO error while reading or writing + Io(ErrorKind), } impl From for DekuError { fn from(e: core::num::TryFromIntError) -> DekuError { - DekuError::Parse(format!("error parsing int: {e}")) + DekuError::Parse(Cow::from(format!("error parsing int: {e}"))) } } impl From for DekuError { fn from(e: core::array::TryFromSliceError) -> DekuError { - DekuError::Parse(format!("error parsing from slice: {e}")) + DekuError::Parse(Cow::from(format!("error parsing from slice: {e}"))) } } @@ -82,11 +82,10 @@ impl core::fmt::Display for DekuError { ), DekuError::Parse(ref err) => write!(f, "Parse error: {err}"), DekuError::InvalidParam(ref err) => write!(f, "Invalid param error: {err}"), - DekuError::Unexpected(ref err) => write!(f, "Unexpected error: {err}"), DekuError::Assertion(ref err) => write!(f, "Assertion error: {err}"), DekuError::AssertionNoStr => write!(f, "Assertion error"), DekuError::IdVariantNotFound => write!(f, "Could not resolve `id` for variant"), - DekuError::Write => write!(f, "write error"), + DekuError::Io(ref e) => write!(f, "io errorr: {e:?}"), } } } @@ -106,11 +105,10 @@ impl From for std::io::Error { DekuError::Incomplete(_) => io::Error::new(io::ErrorKind::UnexpectedEof, error), DekuError::Parse(_) => io::Error::new(io::ErrorKind::InvalidData, error), DekuError::InvalidParam(_) => io::Error::new(io::ErrorKind::InvalidInput, error), - DekuError::Unexpected(_) => io::Error::new(io::ErrorKind::Other, error), DekuError::Assertion(_) => io::Error::new(io::ErrorKind::InvalidData, error), DekuError::AssertionNoStr => io::Error::from(io::ErrorKind::InvalidData), DekuError::IdVariantNotFound => io::Error::new(io::ErrorKind::NotFound, error), - DekuError::Write => io::Error::new(io::ErrorKind::BrokenPipe, error), + DekuError::Io(e) => io::Error::new(e, error), } } } diff --git a/src/impls/bool.rs b/src/impls/bool.rs index 34fdaba5..1b1ee960 100644 --- a/src/impls/bool.rs +++ b/src/impls/bool.rs @@ -1,5 +1,7 @@ use no_std_io::io::{Read, Write}; +#[cfg(feature = "alloc")] +use alloc::borrow::Cow; #[cfg(feature = "alloc")] use alloc::format; @@ -21,7 +23,9 @@ where let ret = match val { 0x01 => Ok(true), 0x00 => Ok(false), - _ => Err(DekuError::Parse(format!("cannot parse bool value: {val}",))), + _ => Err(DekuError::Parse(Cow::from(format!( + "cannot parse bool value: {val}", + )))), }?; Ok(ret) diff --git a/src/impls/cstring.rs b/src/impls/cstring.rs index cf636b55..02ba1c8f 100644 --- a/src/impls/cstring.rs +++ b/src/impls/cstring.rs @@ -1,3 +1,4 @@ +use alloc::borrow::Cow; use no_std_io::io::{Read, Write}; use std::ffi::CString; @@ -27,8 +28,9 @@ where let bytes = Vec::from_reader_with_ctx(reader, (Limit::from(|b: &u8| *b == 0x00), inner_ctx))?; - let value = CString::from_vec_with_nul(bytes) - .map_err(|e| DekuError::Parse(format!("Failed to convert Vec to CString: {e}")))?; + let value = CString::from_vec_with_nul(bytes).map_err(|e| { + DekuError::Parse(Cow::from(format!("Failed to convert Vec to CString: {e}"))) + })?; Ok(value) } diff --git a/src/impls/nonzero.rs b/src/impls/nonzero.rs index e51c1cda..62e65397 100644 --- a/src/impls/nonzero.rs +++ b/src/impls/nonzero.rs @@ -1,4 +1,6 @@ #[cfg(feature = "alloc")] +use alloc::borrow::Cow; +#[cfg(feature = "alloc")] use alloc::format; use core::num::*; use no_std_io::io::{Read, Write}; @@ -19,7 +21,7 @@ macro_rules! ImplDekuTraitsCtx { let value = <$typ>::new(value); match value { - None => Err(DekuError::Parse(format!("NonZero assertion"))), + None => Err(DekuError::Parse(Cow::from(format!("NonZero assertion")))), Some(v) => Ok(v), } } diff --git a/src/impls/primitive.rs b/src/impls/primitive.rs index 4f0df03a..eb7f6185 100644 --- a/src/impls/primitive.rs +++ b/src/impls/primitive.rs @@ -1,7 +1,6 @@ +use alloc::borrow::Cow; #[cfg(feature = "alloc")] use alloc::format; -#[cfg(feature = "alloc")] -use alloc::string::ToString; use core::convert::TryInto; use bitvec::prelude::*; @@ -79,13 +78,14 @@ impl DekuReader<'_, (Endian, ByteSize)> for u8 { reader: &mut Reader, (endian, size): (Endian, ByteSize), ) -> Result { - let mut buf = [0; core::mem::size_of::()]; - let ret = reader.read_bytes(size.0, &mut buf)?; + const MAX_TYPE_BYTES: usize = core::mem::size_of::(); + let mut buf = [0; MAX_TYPE_BYTES]; + let ret = reader.read_bytes_const::(&mut buf)?; let a = match ret { ReaderRet::Bytes => ::from_be_bytes(buf), ReaderRet::Bits(bits) => { let Some(bits) = bits else { - return Err(DekuError::Parse("no bits read from reader".to_string())); + return Err(DekuError::Parse(Cow::from("no bits read from reader"))); }; let a = ::read(&bits, (endian, size))?; a.1 @@ -181,14 +181,14 @@ macro_rules! ImplDekuReadBits { ) -> Result<$typ, DekuError> { const MAX_TYPE_BITS: usize = BitSize::of::<$typ>().0; if size.0 > MAX_TYPE_BITS { - return Err(DekuError::Parse(format!( + return Err(DekuError::Parse(Cow::from(format!( "too much data: container of {MAX_TYPE_BITS} bits cannot hold {} bits", size.0 - ))); + )))); } let bits = reader.read_bits(size.0)?; let Some(bits) = bits else { - return Err(DekuError::Parse(format!("no bits read from reader",))); + return Err(DekuError::Parse(Cow::from("no bits read from reader"))); }; let a = <$typ>::read(&bits, (endian, size))?; Ok(a.1) @@ -230,10 +230,10 @@ macro_rules! ImplDekuReadBytes { ) -> Result<$typ, DekuError> { const MAX_TYPE_BYTES: usize = core::mem::size_of::<$typ>(); if size.0 > MAX_TYPE_BYTES { - return Err(DekuError::Parse(format!( + return Err(DekuError::Parse(Cow::from(format!( "too much data: container of {MAX_TYPE_BYTES} bytes cannot hold {} bytes", size.0 - ))); + )))); } let mut buf = [0; MAX_TYPE_BYTES]; let ret = reader.read_bytes(size.0, &mut buf)?; @@ -255,7 +255,7 @@ macro_rules! ImplDekuReadBytes { a.1 } ReaderRet::Bits(None) => { - return Err(DekuError::Parse(format!("no bits read from reader"))); + return Err(DekuError::Parse(Cow::from("no bits read from reader"))); } }; Ok(a) @@ -301,7 +301,7 @@ macro_rules! ImplDekuReadSignExtend { } ReaderRet::Bits(bits) => { let Some(bits) = bits else { - return Err(DekuError::Parse("no bits read from reader".to_string())); + return Err(DekuError::Parse(Cow::from("no bits read from reader"))); }; let a = <$typ>::read(&bits, (endian, size))?; a.1 @@ -341,14 +341,14 @@ macro_rules! ImplDekuReadSignExtend { ) -> Result<$typ, DekuError> { const MAX_TYPE_BITS: usize = BitSize::of::<$typ>().0; if size.0 > MAX_TYPE_BITS { - return Err(DekuError::Parse(format!( + return Err(DekuError::Parse(Cow::from(format!( "too much data: container of {MAX_TYPE_BITS} bits cannot hold {} bits", size.0 - ))); + )))); } let bits = reader.read_bits(size.0)?; let Some(bits) = bits else { - return Err(DekuError::Parse(format!("no bits read from reader",))); + return Err(DekuError::Parse(Cow::from("no bits read from reader"))); }; let a = <$typ>::read(&bits, (endian, size))?; Ok(a.1) @@ -357,20 +357,35 @@ macro_rules! ImplDekuReadSignExtend { }; } -// TODO: these forward types should forward on a ContainerCanHoldSize or something if ByteSize or -// BitSize wasn't defined macro_rules! ForwardDekuRead { ($typ:ty) => { - // Only have `endian`, set `bit_size` to `Size::of::()` + // Only have `endian`, specialize and use read_bytes_const impl DekuReader<'_, Endian> for $typ { #[inline(always)] fn from_reader_with_ctx( reader: &mut Reader, endian: Endian, ) -> Result<$typ, DekuError> { - const BYTE_SIZE: usize = core::mem::size_of::<$typ>(); - - <$typ>::from_reader_with_ctx(reader, (endian, ByteSize(BYTE_SIZE))) + const MAX_TYPE_BYTES: usize = core::mem::size_of::<$typ>(); + let mut buf = [0; MAX_TYPE_BYTES]; + let ret = reader.read_bytes_const::(&mut buf)?; + let a = match ret { + ReaderRet::Bytes => { + if endian.is_le() { + <$typ>::from_le_bytes(buf) + } else { + <$typ>::from_be_bytes(buf) + } + } + ReaderRet::Bits(Some(bits)) => { + let a = <$typ>::read(&bits, (endian, ByteSize(MAX_TYPE_BYTES)))?; + a.1 + } + ReaderRet::Bits(None) => { + return Err(DekuError::Parse(Cow::from("no bits read from reader"))); + } + }; + Ok(a) } } @@ -436,11 +451,11 @@ macro_rules! ImplDekuWrite { let input_bits = input.view_bits::(); if bit_size > input_bits.len() { - return Err(DekuError::InvalidParam(format!( + return Err(DekuError::InvalidParam(Cow::from(format!( "bit size {} is larger than input {}", bit_size, input_bits.len() - ))); + )))); } if matches!(endian, Endian::Little) { @@ -479,10 +494,10 @@ macro_rules! ImplDekuWrite { const TYPE_SIZE: usize = core::mem::size_of::<$typ>(); if size.0 > TYPE_SIZE { - return Err(DekuError::InvalidParam(format!( + return Err(DekuError::InvalidParam(Cow::from(format!( "byte size {} is larger then input {}", size.0, TYPE_SIZE - ))); + )))); } let input = if matches!(endian, Endian::Big) { @@ -906,11 +921,11 @@ mod tests { let res_read = <$typ>::from_reader_with_ctx(&mut reader, (Endian::Little, BitSize($size + 1))); assert_eq!( - DekuError::Parse(format!( + DekuError::Parse(Cow::from(format!( "too much data: container of {} bits cannot hold {} bits", $size, $size + 1 - )), + ))), res_read.err().unwrap() ); } diff --git a/src/lib.rs b/src/lib.rs index 7e14233f..5c8ea8f5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -227,7 +227,7 @@ assert_eq!(value.a, 0x01); assert_eq!(value.sub.b, 0x01 + 0x02) ``` -# `Read` enabled +# `Read` supported Parsers can be created that directly read from a source implementing [Read](crate::no_std_io::Read). The crate [no_std_io] is re-exported for use in `no_std` environments. @@ -250,7 +250,7 @@ let mut file = File::options().read(true).open("file").unwrap(); let ec = EcHdr::from_reader((&mut file, 0)).unwrap(); ``` -# `Write` enabled +# `Write` supported Parsers can be created that directly write to a source implementing [Write](crate::no_std_io::Write). ```rust, no_run @@ -332,6 +332,12 @@ Then you'd call `env_logger::init()` or `env_logger::try_init()` prior to doing Deku uses the `trace` logging level, so if you run your application with `RUST_LOG=trace` in your environment, you will see logging messages as Deku does its deserialising. +# Reducing parser code size + +- With the use of the `no-assert-string` feature, you can remove the strings Deku adds to assertion errors. +- `DekuError` whenever possible will use a `'static str`, to make the errors compile away when following a + guide such as [min-sized-rust](https://github.com/johnthagen/min-sized-rust). + */ #![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] diff --git a/src/reader.rs b/src/reader.rs index 08468021..19283e8a 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -169,8 +169,7 @@ impl<'a, R: Read> Reader<'a, R> { if e.kind() == ErrorKind::UnexpectedEof { return Err(DekuError::Incomplete(NeedSize::new(amt))); } - - // TODO: other errors? + return Err(DekuError::Io(e.kind())); } let read_buf = &buf[..bytes_len]; @@ -206,6 +205,7 @@ impl<'a, R: Read> Reader<'a, R> { /// /// # Params /// `amt` - Amount of bytes that will be read + /// `buf` - result bytes #[inline(always)] pub fn read_bytes(&mut self, amt: usize, buf: &mut [u8]) -> Result { #[cfg(feature = "logging")] @@ -218,8 +218,7 @@ impl<'a, R: Read> Reader<'a, R> { if e.kind() == ErrorKind::UnexpectedEof { return Err(DekuError::Incomplete(NeedSize::new(amt * 8))); } - - // TODO: other errors? + return Err(DekuError::Io(e.kind())); } self.bits_read += amt * 8; @@ -232,6 +231,38 @@ impl<'a, R: Read> Reader<'a, R> { Ok(ReaderRet::Bits(self.read_bits(amt * 8)?)) } } + + /// Attempt to read bytes from `Reader`. This will return `ReaderRet::Bytes` with a valid + /// `buf` of bytes if we have no "leftover" bytes and thus are byte aligned. If we are not byte + /// aligned, this will call `read_bits` and return `ReaderRet::Bits(_)` of size `N` * 8. + /// + /// # Params + /// `buf` - result bytes + #[inline(always)] + pub fn read_bytes_const( + &mut self, + buf: &mut [u8; N], + ) -> Result { + #[cfg(feature = "logging")] + log::trace!("read_bytes: requesting {N} bytes"); + if self.leftover.is_empty() { + if let Err(e) = self.inner.read_exact(buf) { + if e.kind() == ErrorKind::UnexpectedEof { + return Err(DekuError::Incomplete(NeedSize::new(N * 8))); + } + return Err(DekuError::Io(e.kind())); + } + + self.bits_read += N * 8; + + #[cfg(feature = "logging")] + log::trace!("read_bytes: returning {:02x?}", &buf); + + Ok(ReaderRet::Bytes) + } else { + Ok(ReaderRet::Bits(self.read_bits(N * 8)?)) + } + } } #[cfg(test)] @@ -242,12 +273,12 @@ mod tests { #[test] fn test_end() { - let input = hex!("aa"); + let input = hex!("aabb"); let mut cursor = Cursor::new(input); let mut reader = Reader::new(&mut cursor); assert!(!reader.end()); - let mut buf = [0; 1]; - let _ = reader.read_bytes(1, &mut buf); + let mut buf = [0; 2]; + let _ = reader.read_bytes_const::<2>(&mut buf).unwrap(); assert!(reader.end()); let input = hex!("aa"); diff --git a/src/writer.rs b/src/writer.rs index 7e02d690..bf4ed92e 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -88,8 +88,8 @@ impl Writer { bits = unsafe { bits.get_unchecked(count * bits_of::()..) }; self.leftover = bits.to_bitvec(); - if self.inner.write_all(buf).is_err() { - return Err(DekuError::Write); + if let Err(e) = self.inner.write_all(buf) { + return Err(DekuError::Io(e.kind())); } self.bits_written += buf.len() * 8; @@ -117,8 +117,8 @@ impl Writer { // instead of sending the entire thing. The rest would be through self.inner.write. self.write_bits(&BitVec::from_slice(buf))?; } else { - if self.inner.write_all(buf).is_err() { - return Err(DekuError::Write); + if let Err(e) = self.inner.write_all(buf) { + return Err(DekuError::Io(e.kind())); } self.bits_written += buf.len() * 8; } @@ -148,8 +148,8 @@ impl Writer { *slot = byte.load_be(); }); - if self.inner.write_all(&buf).is_err() { - return Err(DekuError::Write); + if let Err(e) = self.inner.write_all(&buf) { + return Err(DekuError::Io(e.kind())); } self.bits_written += buf.len() * 8; diff --git a/tests/test_attributes/test_ctx.rs b/tests/test_attributes/test_ctx.rs index f945cd34..fd7fb42f 100644 --- a/tests/test_attributes/test_ctx.rs +++ b/tests/test_attributes/test_ctx.rs @@ -1,8 +1,6 @@ use std::convert::{TryFrom, TryInto}; use std::io::Cursor; -use bitvec::bitvec; -use deku::bitvec::Msb0; use deku::prelude::*; use deku::reader::Reader; use deku::writer::Writer; @@ -230,7 +228,6 @@ fn test_ctx_default_struct() { ) .unwrap(); assert_eq!(expected, ret_read); - let mut ret_write = bitvec![u8, Msb0;]; let mut out_buf = vec![]; let mut writer = Writer::new(&mut out_buf); ret_read.to_writer(&mut writer, (1, 2)).unwrap(); diff --git a/tests/test_compile/cases/internal_variables.stderr b/tests/test_compile/cases/internal_variables.stderr index 78531216..faddbb3d 100644 --- a/tests/test_compile/cases/internal_variables.stderr +++ b/tests/test_compile/cases/internal_variables.stderr @@ -3,3 +3,11 @@ error: Unexpected meta-item format `attribute cannot contain `__deku_` these are | 88 | #[deku(cond = "__deku_bit_offset == *field_a as usize")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: unused variable: `offset` + --> tests/test_compile/cases/internal_variables.rs:53:5 + | +53 | offset: usize, + | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_offset` + | + = note: `#[warn(unused_variables)]` on by default diff --git a/tests/test_compile/cases/temp_field.stderr b/tests/test_compile/cases/temp_field.stderr index b64d3d81..f96e8bc3 100644 --- a/tests/test_compile/cases/temp_field.stderr +++ b/tests/test_compile/cases/temp_field.stderr @@ -13,7 +13,3 @@ error: pattern requires `..` due to inaccessible fields | ^^^^^^^^^ | = note: this error originates in the derive macro `DekuWrite` (in Nightly builds, run with -Z macro-backtrace for more info) -help: ignore the inaccessible and unused fields - | -4 | #[derive(DekuRead, DekuWrite { .. } { - | ~~~~~~