xref: /aosp_15_r20/external/crosvm/bit_field/bit_field_derive/bit_field_derive.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2018 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #![recursion_limit = "256"]
6 
7 extern crate proc_macro;
8 
9 use proc_macro2::Span;
10 use proc_macro2::TokenStream;
11 use quote::quote;
12 use quote::quote_spanned;
13 use syn::parse::Error;
14 use syn::parse::Result;
15 use syn::parse_macro_input;
16 use syn::Attribute;
17 use syn::Data;
18 use syn::DataEnum;
19 use syn::DeriveInput;
20 use syn::Fields;
21 use syn::FieldsNamed;
22 use syn::FieldsUnnamed;
23 use syn::Ident;
24 use syn::Lit;
25 use syn::LitInt;
26 use syn::Meta;
27 use syn::MetaNameValue;
28 use syn::Type;
29 use syn::Visibility;
30 
31 /// The function that derives the actual implementation.
32 #[proc_macro_attribute]
bitfield( _args: proc_macro::TokenStream, input: proc_macro::TokenStream, ) -> proc_macro::TokenStream33 pub fn bitfield(
34     _args: proc_macro::TokenStream,
35     input: proc_macro::TokenStream,
36 ) -> proc_macro::TokenStream {
37     let derive_input = parse_macro_input!(input as DeriveInput);
38 
39     let expanded = bitfield_impl(&derive_input).unwrap_or_else(|err| {
40         let compile_error = err.to_compile_error();
41         quote! {
42             #compile_error
43 
44             // Include the original input to avoid "use of undeclared type"
45             // errors elsewhere.
46             #derive_input
47         }
48     });
49 
50     expanded.into()
51 }
52 
bitfield_impl(ast: &DeriveInput) -> Result<TokenStream>53 fn bitfield_impl(ast: &DeriveInput) -> Result<TokenStream> {
54     if !ast.generics.params.is_empty() {
55         return Err(Error::new(
56             Span::call_site(),
57             "#[bitfield] does not support generic parameters",
58         ));
59     }
60 
61     match &ast.data {
62         Data::Struct(data_struct) => match &data_struct.fields {
63             Fields::Named(fields_named) => bitfield_struct_impl(ast, fields_named),
64             Fields::Unnamed(fields_unnamed) => bitfield_tuple_struct_impl(ast, fields_unnamed),
65             Fields::Unit => Err(Error::new(
66                 Span::call_site(),
67                 "#[bitfield] does not work with unit struct",
68             )),
69         },
70         Data::Enum(data_enum) => bitfield_enum_impl(ast, data_enum),
71         Data::Union(_) => Err(Error::new(
72             Span::call_site(),
73             "#[bitfield] does not support unions",
74         )),
75     }
76 }
77 
bitfield_tuple_struct_impl(ast: &DeriveInput, fields: &FieldsUnnamed) -> Result<TokenStream>78 fn bitfield_tuple_struct_impl(ast: &DeriveInput, fields: &FieldsUnnamed) -> Result<TokenStream> {
79     let mut ast = ast.clone();
80     let width = match parse_remove_bits_attr(&mut ast)? {
81         Some(w) => w,
82         None => {
83             return Err(Error::new(
84                 Span::call_site(),
85                 "tuple struct field must have bits attribute",
86             ));
87         }
88     };
89 
90     let ident = &ast.ident;
91 
92     if width > 64 {
93         return Err(Error::new(
94             Span::call_site(),
95             "max width of bitfield field is 64",
96         ));
97     }
98 
99     let bits = width as u8;
100 
101     if fields.unnamed.len() != 1 {
102         return Err(Error::new(
103             Span::call_site(),
104             "tuple struct field must have exactly 1 field",
105         ));
106     }
107 
108     let field_type = match &fields.unnamed.first().unwrap().ty {
109         Type::Path(t) => t,
110         _ => {
111             return Err(Error::new(
112                 Span::call_site(),
113                 "tuple struct field must have primitive field",
114             ));
115         }
116     };
117     let span = field_type.path.segments.first().unwrap().ident.span();
118 
119     let from_u64 = quote_spanned! {
120         span => val as #field_type
121     };
122 
123     let into_u64 = quote_spanned! {
124         span => val.0 as u64
125     };
126 
127     let expanded = quote! {
128         #ast
129 
130         impl bit_field::BitFieldSpecifier for #ident {
131             const FIELD_WIDTH: u8 = #bits;
132             type SetterType = Self;
133             type GetterType = Self;
134 
135             #[inline]
136             #[allow(clippy::unnecessary_cast)]
137             fn from_u64(val: u64) -> Self::GetterType {
138                 Self(#from_u64)
139             }
140 
141             #[inline]
142             #[allow(clippy::unnecessary_cast)]
143             fn into_u64(val: Self::SetterType) -> u64 {
144                 #into_u64
145             }
146         }
147     };
148 
149     Ok(expanded)
150 }
151 
bitfield_enum_impl(ast: &DeriveInput, data: &DataEnum) -> Result<TokenStream>152 fn bitfield_enum_impl(ast: &DeriveInput, data: &DataEnum) -> Result<TokenStream> {
153     let mut ast = ast.clone();
154     let width = parse_remove_bits_attr(&mut ast)?;
155     match width {
156         None => bitfield_enum_without_width_impl(&ast, data),
157         Some(width) => bitfield_enum_with_width_impl(&ast, data, width),
158     }
159 }
160 
bitfield_enum_with_width_impl( ast: &DeriveInput, data: &DataEnum, width: u64, ) -> Result<TokenStream>161 fn bitfield_enum_with_width_impl(
162     ast: &DeriveInput,
163     data: &DataEnum,
164     width: u64,
165 ) -> Result<TokenStream> {
166     if width > 64 {
167         return Err(Error::new(
168             Span::call_site(),
169             "max width of bitfield enum is 64",
170         ));
171     }
172     let bits = width as u8;
173     let declare_discriminants = get_declare_discriminants_for_enum(bits, ast, data);
174 
175     let ident = &ast.ident;
176     let type_name = ident.to_string();
177     let variants = &data.variants;
178     let match_discriminants = variants.iter().map(|variant| {
179         let variant = &variant.ident;
180         quote! {
181             discriminant::#variant => Ok(#ident::#variant),
182         }
183     });
184 
185     let expanded = quote! {
186         #ast
187 
188         impl bit_field::BitFieldSpecifier for #ident {
189             const FIELD_WIDTH: u8 = #bits;
190             type SetterType = Self;
191             type GetterType = std::result::Result<Self, bit_field::Error>;
192 
193             #[inline]
194             fn from_u64(val: u64) -> Self::GetterType {
195                 struct discriminant;
196                 impl discriminant {
197                     #(#declare_discriminants)*
198                 }
199                 match val {
200                     #(#match_discriminants)*
201                     v => Err(bit_field::Error::new(#type_name, v)),
202                 }
203             }
204 
205             #[inline]
206             fn into_u64(val: Self::SetterType) -> u64 {
207                 val as u64
208             }
209         }
210     };
211 
212     Ok(expanded)
213 }
214 // Expand to an impl of BitFieldSpecifier for an enum like:
215 //
216 //     #[bitfield]
217 //     #[derive(Debug, PartialEq)]
218 //     enum TwoBits {
219 //         Zero = 0b00,
220 //         One = 0b01,
221 //         Two = 0b10,
222 //         Three = 0b11,
223 //     }
224 //
225 // Such enums may be used as a field of a bitfield struct.
226 //
227 //     #[bitfield]
228 //     struct Struct {
229 //         prefix: BitField1,
230 //         two_bits: TwoBits,
231 //         suffix: BitField5,
232 //     }
233 //
bitfield_enum_without_width_impl(ast: &DeriveInput, data: &DataEnum) -> Result<TokenStream>234 fn bitfield_enum_without_width_impl(ast: &DeriveInput, data: &DataEnum) -> Result<TokenStream> {
235     let ident = &ast.ident;
236     let variants = &data.variants;
237     let len = variants.len();
238     if len.count_ones() != 1 {
239         return Err(Error::new(
240             Span::call_site(),
241             "#[bitfield] expected a number of variants which is a power of 2 when bits is not \
242              specified for the enum",
243         ));
244     }
245 
246     let bits = len.trailing_zeros() as u8;
247     let declare_discriminants = get_declare_discriminants_for_enum(bits, ast, data);
248 
249     let match_discriminants = variants.iter().map(|variant| {
250         let variant = &variant.ident;
251         quote! {
252             discriminant::#variant => #ident::#variant,
253         }
254     });
255 
256     let expanded = quote! {
257         #ast
258 
259         impl bit_field::BitFieldSpecifier for #ident {
260             const FIELD_WIDTH: u8 = #bits;
261             type SetterType = Self;
262             type GetterType = Self;
263 
264             #[inline]
265             fn from_u64(val: u64) -> Self::GetterType {
266                 struct discriminant;
267                 impl discriminant {
268                     #(#declare_discriminants)*
269                 }
270                 match val {
271                     #(#match_discriminants)*
272                     _ => unreachable!(),
273                 }
274             }
275 
276             #[inline]
277             fn into_u64(val: Self::SetterType) -> u64 {
278                 val as u64
279             }
280         }
281     };
282 
283     Ok(expanded)
284 }
285 
get_declare_discriminants_for_enum( bits: u8, ast: &DeriveInput, data: &DataEnum, ) -> Vec<TokenStream>286 fn get_declare_discriminants_for_enum(
287     bits: u8,
288     ast: &DeriveInput,
289     data: &DataEnum,
290 ) -> Vec<TokenStream> {
291     let variants = &data.variants;
292     let upper_bound = 2u64.pow(bits as u32);
293     let ident = &ast.ident;
294 
295     variants
296         .iter()
297         .map(|variant| {
298             let variant = &variant.ident;
299             let span = variant.span();
300 
301             let assertion = quote_spanned! {span=>
302                 // If IS_IN_BOUNDS is true, this evaluates to 0.
303                 //
304                 // If IS_IN_BOUNDS is false, this evaluates to `0 - 1` which
305                 // triggers a compile error on underflow when referenced below. The
306                 // error is not beautiful but does carry the span of the problematic
307                 // enum variant so at least it points to the right line.
308                 //
309                 //     error: any use of this value will cause an error
310                 //       --> bit_field/test.rs:10:5
311                 //        |
312                 //     10 |     OutOfBounds = 0b111111,
313                 //        |     ^^^^^^^^^^^ attempt to subtract with overflow
314                 //        |
315                 //
316                 //     error[E0080]: erroneous constant used
317                 //      --> bit_field/test.rs:5:1
318                 //       |
319                 //     5 | #[bitfield]
320                 //       | ^^^^^^^^^^^ referenced constant has errors
321                 //
322                 const ASSERT: u64 = 0 - !IS_IN_BOUNDS as u64;
323             };
324 
325             quote! {
326                 #[allow(non_upper_case_globals)]
327                 const #variant: u64 = {
328                     const IS_IN_BOUNDS: bool = (#ident::#variant as u64) < #upper_bound;
329 
330                     #assertion
331 
332                     #ident::#variant as u64 + ASSERT
333                 };
334             }
335         })
336         .collect()
337 }
338 
bitfield_struct_impl(ast: &DeriveInput, fields: &FieldsNamed) -> Result<TokenStream>339 fn bitfield_struct_impl(ast: &DeriveInput, fields: &FieldsNamed) -> Result<TokenStream> {
340     let name = &ast.ident;
341     let vis = &ast.vis;
342     let attrs = &ast.attrs;
343     let fields = get_struct_fields(fields)?;
344     let struct_def = get_struct_def(vis, name, &fields);
345     let bits_impl = get_bits_impl(name);
346     let fields_impl = get_fields_impl(&fields);
347     let debug_fmt_impl = get_debug_fmt_impl(name, &fields);
348 
349     let expanded = quote! {
350         #(#attrs)*
351         #struct_def
352         #bits_impl
353         impl #name {
354             #(#fields_impl)*
355         }
356         #debug_fmt_impl
357     };
358 
359     Ok(expanded)
360 }
361 
362 struct FieldSpec<'a> {
363     ident: &'a Ident,
364     ty: &'a Type,
365     expected_bits: Option<LitInt>,
366 }
367 
368 // Unwrap ast to get the named fields. We only care about field names and types:
369 // "myfield : BitField3" -> ("myfield", Token(BitField3))
get_struct_fields(fields: &FieldsNamed) -> Result<Vec<FieldSpec>>370 fn get_struct_fields(fields: &FieldsNamed) -> Result<Vec<FieldSpec>> {
371     let mut vec = Vec::new();
372 
373     for field in &fields.named {
374         let ident = field
375             .ident
376             .as_ref()
377             .expect("Fields::Named has named fields");
378         let ty = &field.ty;
379         let expected_bits = parse_bits_attr(&field.attrs)?;
380         vec.push(FieldSpec {
381             ident,
382             ty,
383             expected_bits,
384         });
385     }
386 
387     Ok(vec)
388 }
389 
390 // For example: #[bits = 1]
parse_bits_attr(attrs: &[Attribute]) -> Result<Option<LitInt>>391 fn parse_bits_attr(attrs: &[Attribute]) -> Result<Option<LitInt>> {
392     let mut expected_bits = None;
393 
394     for attr in attrs {
395         if attr.path().is_ident("doc") {
396             continue;
397         }
398         if let Some(v) = try_parse_bits_attr(attr) {
399             expected_bits = Some(v);
400             continue;
401         }
402 
403         return Err(Error::new_spanned(attr, "unrecognized attribute"));
404     }
405 
406     Ok(expected_bits)
407 }
408 
409 // This function will return None if the attribute is not #[bits = *].
try_parse_bits_attr(attr: &Attribute) -> Option<LitInt>410 fn try_parse_bits_attr(attr: &Attribute) -> Option<LitInt> {
411     if attr.path().is_ident("bits") {
412         if let Meta::NameValue(MetaNameValue {
413             value:
414                 syn::Expr::Lit(syn::ExprLit {
415                     lit: Lit::Int(int), ..
416                 }),
417             ..
418         }) = &attr.meta
419         {
420             return Some(int).cloned();
421         }
422     }
423     None
424 }
425 
parse_remove_bits_attr(ast: &mut DeriveInput) -> Result<Option<u64>>426 fn parse_remove_bits_attr(ast: &mut DeriveInput) -> Result<Option<u64>> {
427     let mut width = None;
428     let mut bits_idx = 0;
429 
430     for (i, attr) in ast.attrs.iter().enumerate() {
431         if let Some(w) = try_parse_bits_attr(attr) {
432             bits_idx = i;
433             width = Some(w.base10_parse()?);
434         }
435     }
436 
437     if width.is_some() {
438         ast.attrs.remove(bits_idx);
439     }
440 
441     Ok(width)
442 }
443 
get_struct_def(vis: &Visibility, name: &Ident, fields: &[FieldSpec]) -> TokenStream444 fn get_struct_def(vis: &Visibility, name: &Ident, fields: &[FieldSpec]) -> TokenStream {
445     let mut field_types = Vec::new();
446     for spec in fields {
447         field_types.push(spec.ty);
448     }
449 
450     // `(BitField1::FIELD_WIDTH + BitField3::FIELD_WIDTH + ...)`
451     let data_size_in_bits = quote! {
452         (
453             #(
454                 <#field_types as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
455             )+*
456         )
457     };
458 
459     quote! {
460         #[repr(C)]
461         #vis struct #name {
462             data: [u8; #data_size_in_bits / 8],
463         }
464 
465         impl #name {
466             pub fn new() -> #name {
467                 let _: ::bit_field::Check<[u8; #data_size_in_bits % 8]>;
468 
469                 #name {
470                     data: [0; #data_size_in_bits / 8],
471                 }
472             }
473         }
474     }
475 }
476 
477 // Implement setter and getter for all fields.
get_fields_impl(fields: &[FieldSpec]) -> Vec<TokenStream>478 fn get_fields_impl(fields: &[FieldSpec]) -> Vec<TokenStream> {
479     let mut impls = Vec::new();
480     // This vec keeps track of types before this field, used to generate the offset.
481     let current_types = &mut vec![quote!(::bit_field::BitField0)];
482 
483     for spec in fields {
484         let ty = spec.ty;
485         let getter_ident = Ident::new(format!("get_{}", spec.ident).as_str(), Span::call_site());
486         let setter_ident = Ident::new(format!("set_{}", spec.ident).as_str(), Span::call_site());
487 
488         // Optional #[bits = N] attribute to provide compile-time checked
489         // documentation of how many bits some field covers.
490         let check_expected_bits = spec.expected_bits.as_ref().map(|expected_bits| {
491             // If expected_bits does not match the actual number of bits in the
492             // bit field specifier, this will fail to compile with an error
493             // pointing into the #[bits = N] attribute.
494             let span = expected_bits.span();
495             quote_spanned! {span=>
496                 #[allow(dead_code)]
497                 const EXPECTED_BITS: [(); #expected_bits] =
498                     [(); <#ty as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize];
499             }
500         });
501 
502         impls.push(quote! {
503             pub fn #getter_ident(&self) -> <#ty as ::bit_field::BitFieldSpecifier>::GetterType {
504                 #check_expected_bits
505                 let offset = #(<#current_types as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize)+*;
506                 let val = self.get(offset, <#ty as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH);
507                 <#ty as ::bit_field::BitFieldSpecifier>::from_u64(val)
508             }
509 
510             pub fn #setter_ident(&mut self, val: <#ty as ::bit_field::BitFieldSpecifier>::SetterType) {
511                 let val = <#ty as ::bit_field::BitFieldSpecifier>::into_u64(val);
512                 debug_assert!(val <= ::bit_field::max::<#ty>());
513                 let offset = #(<#current_types as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize)+*;
514                 self.set(offset, <#ty as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH, val)
515             }
516         });
517 
518         current_types.push(quote!(#ty));
519     }
520 
521     impls
522 }
523 
524 // Implement setter and getter for all fields.
get_debug_fmt_impl(name: &Ident, fields: &[FieldSpec]) -> TokenStream525 fn get_debug_fmt_impl(name: &Ident, fields: &[FieldSpec]) -> TokenStream {
526     // print fields:
527     let mut impls = Vec::new();
528     for spec in fields {
529         let field_name = spec.ident.to_string();
530         let getter_ident = Ident::new(&format!("get_{}", spec.ident), Span::call_site());
531         impls.push(quote! {
532             .field(#field_name, &self.#getter_ident())
533         });
534     }
535 
536     let name_str = format!("{}", name);
537     quote! {
538         impl std::fmt::Debug for #name {
539             fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
540                 f.debug_struct(#name_str)
541                 #(#impls)*
542                     .finish()
543             }
544         }
545     }
546 }
547 
get_bits_impl(name: &Ident) -> TokenStream548 fn get_bits_impl(name: &Ident) -> TokenStream {
549     quote! {
550         impl #name {
551             #[inline]
552             fn check_access(&self, offset: usize, width: u8) {
553                 debug_assert!(width <= 64);
554                 debug_assert!(offset / 8 < self.data.len());
555                 debug_assert!((offset + (width as usize)) <= (self.data.len() * 8));
556             }
557 
558             #[inline]
559             pub fn get_bit(&self, offset: usize) -> bool {
560                 self.check_access(offset, 1);
561 
562                 let byte_index = offset / 8;
563                 let bit_offset = offset % 8;
564 
565                 let byte = self.data[byte_index];
566                 let mask = 1 << bit_offset;
567 
568                 byte & mask == mask
569             }
570 
571             #[inline]
572             pub fn set_bit(&mut self, offset: usize, val: bool) {
573                 self.check_access(offset, 1);
574 
575                 let byte_index = offset / 8;
576                 let bit_offset = offset % 8;
577 
578                 let byte = &mut self.data[byte_index];
579                 let mask = 1 << bit_offset;
580 
581                 if val {
582                     *byte |= mask;
583                 } else {
584                     *byte &= !mask;
585                 }
586             }
587 
588             #[inline]
589             pub fn get(&self, offset: usize, width: u8) -> u64 {
590                 self.check_access(offset, width);
591                 let mut val = 0;
592 
593                 for i in 0..(width as usize) {
594                     if self.get_bit(i + offset) {
595                         val |= 1 << i;
596                     }
597                 }
598 
599                 val
600             }
601 
602             #[inline]
603             pub fn set(&mut self, offset: usize, width: u8, val: u64) {
604                 self.check_access(offset, width);
605 
606                 for i in 0..(width as usize) {
607                     let mask = 1 << i;
608                     let val_bit_is_set = val & mask == mask;
609                     self.set_bit(i + offset, val_bit_is_set);
610                 }
611             }
612         }
613     }
614 }
615 
616 // Only intended to be used from the bit_field crate. This macro emits the
617 // marker types bit_field::BitField0 through bit_field::BitField64.
618 #[proc_macro]
619 #[doc(hidden)]
define_bit_field_specifiers(_input: proc_macro::TokenStream) -> proc_macro::TokenStream620 pub fn define_bit_field_specifiers(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
621     let mut code = TokenStream::new();
622 
623     for width in 0u8..=64 {
624         let span = Span::call_site();
625         let long_name = Ident::new(&format!("BitField{}", width), span);
626         let short_name = Ident::new(&format!("B{}", width), span);
627 
628         let default_field_type = if width <= 8 {
629             quote!(u8)
630         } else if width <= 16 {
631             quote!(u16)
632         } else if width <= 32 {
633             quote!(u32)
634         } else {
635             quote!(u64)
636         };
637 
638         code.extend(quote! {
639             pub struct #long_name;
640             pub use self::#long_name as #short_name;
641 
642             impl BitFieldSpecifier for #long_name {
643                 const FIELD_WIDTH: u8 = #width;
644                 type SetterType = #default_field_type;
645                 type GetterType = #default_field_type;
646 
647                 #[inline]
648                 fn from_u64(val: u64) -> Self::GetterType {
649                     val as Self::GetterType
650                 }
651 
652                 #[inline]
653                 fn into_u64(val: Self::SetterType) -> u64 {
654                     val as u64
655                 }
656             }
657         });
658     }
659 
660     code.into()
661 }
662 
663 #[cfg(test)]
664 mod tests {
665     use syn::parse_quote;
666 
667     use super::*;
668 
669     #[test]
end_to_end()670     fn end_to_end() {
671         let input: DeriveInput = parse_quote! {
672             #[derive(Clone)]
673             struct MyBitField {
674                 a: BitField1,
675                 b: BitField2,
676                 c: BitField5,
677             }
678         };
679 
680         let expected = quote! {
681             #[derive(Clone)]
682             #[repr(C)]
683             struct MyBitField {
684                 data: [u8; (<BitField1 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
685                             + <BitField2 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
686                             + <BitField5 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize)
687                     / 8],
688             }
689             impl MyBitField {
690                 pub fn new() -> MyBitField {
691                     let _: ::bit_field::Check<[
692                         u8;
693                         (<BitField1 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
694                                 + <BitField2 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
695                                 + <BitField5 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize)
696                             % 8
697                     ]>;
698 
699                     MyBitField {
700                         data: [0; (<BitField1 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
701                                    + <BitField2 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
702                                    + <BitField5 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize)
703                             / 8],
704                     }
705                 }
706             }
707             impl MyBitField {
708                 #[inline]
709                 fn check_access(&self, offset: usize, width: u8) {
710                     debug_assert!(width <= 64);
711                     debug_assert!(offset / 8 < self.data.len());
712                     debug_assert!((offset + (width as usize)) <= (self.data.len() * 8));
713                 }
714                 #[inline]
715                 pub fn get_bit(&self, offset: usize) -> bool {
716                     self.check_access(offset, 1);
717                     let byte_index = offset / 8;
718                     let bit_offset = offset % 8;
719                     let byte = self.data[byte_index];
720                     let mask = 1 << bit_offset;
721                     byte & mask == mask
722                 }
723                 #[inline]
724                 pub fn set_bit(&mut self, offset: usize, val: bool) {
725                     self.check_access(offset, 1);
726                     let byte_index = offset / 8;
727                     let bit_offset = offset % 8;
728                     let byte = &mut self.data[byte_index];
729                     let mask = 1 << bit_offset;
730                     if val {
731                         *byte |= mask;
732                     } else {
733                         *byte &= !mask;
734                     }
735                 }
736                 #[inline]
737                 pub fn get(&self, offset: usize, width: u8) -> u64 {
738                     self.check_access(offset, width);
739                     let mut val = 0;
740                     for i in 0..(width as usize) {
741                         if self.get_bit(i + offset) {
742                             val |= 1 << i;
743                         }
744                     }
745                     val
746                 }
747                 #[inline]
748                 pub fn set(&mut self, offset: usize, width: u8, val: u64) {
749                     self.check_access(offset, width);
750                     for i in 0..(width as usize) {
751                         let mask = 1 << i;
752                         let val_bit_is_set = val & mask == mask;
753                         self.set_bit(i + offset, val_bit_is_set);
754                     }
755                 }
756             }
757             impl MyBitField {
758                 pub fn get_a(&self) -> <BitField1 as ::bit_field::BitFieldSpecifier>::GetterType {
759                     let offset = <::bit_field::BitField0 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize;
760                     let val = self.get(offset, <BitField1 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH);
761                     <BitField1 as ::bit_field::BitFieldSpecifier>::from_u64(val)
762                 }
763                 pub fn set_a(&mut self, val: <BitField1 as ::bit_field::BitFieldSpecifier>::SetterType) {
764                     let val = <BitField1 as ::bit_field::BitFieldSpecifier>::into_u64(val);
765                     debug_assert!(val <= ::bit_field::max::<BitField1>());
766                     let offset = <::bit_field::BitField0 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize;
767                     self.set(offset, <BitField1 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH, val)
768                 }
769                 pub fn get_b(&self) -> <BitField2 as ::bit_field::BitFieldSpecifier>::GetterType {
770                     let offset = <::bit_field::BitField0 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
771                         + <BitField1 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize;
772                     let val = self.get(offset, <BitField2 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH);
773                     <BitField2 as ::bit_field::BitFieldSpecifier>::from_u64(val)
774                 }
775                 pub fn set_b(&mut self, val: <BitField2 as ::bit_field::BitFieldSpecifier>::SetterType) {
776                     let val = <BitField2 as ::bit_field::BitFieldSpecifier>::into_u64(val);
777                     debug_assert!(val <= ::bit_field::max::<BitField2>());
778                     let offset = <::bit_field::BitField0 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
779                         + <BitField1 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize;
780                     self.set(offset, <BitField2 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH, val)
781                 }
782                 pub fn get_c(&self) -> <BitField5 as ::bit_field::BitFieldSpecifier>::GetterType {
783                     let offset = <::bit_field::BitField0 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
784                         + <BitField1 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
785                         + <BitField2 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize;
786                     let val = self.get(offset, <BitField5 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH);
787                     <BitField5 as ::bit_field::BitFieldSpecifier>::from_u64(val)
788                 }
789                 pub fn set_c(&mut self, val: <BitField5 as ::bit_field::BitFieldSpecifier>::SetterType) {
790                     let val = <BitField5 as ::bit_field::BitFieldSpecifier>::into_u64(val);
791                     debug_assert!(val <= ::bit_field::max::<BitField5>());
792                     let offset = <::bit_field::BitField0 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
793                         + <BitField1 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize
794                         + <BitField2 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH as usize;
795                     self.set(offset, <BitField5 as ::bit_field::BitFieldSpecifier>::FIELD_WIDTH, val)
796                 }
797             }
798             impl std::fmt::Debug for MyBitField {
799                 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
800                     f.debug_struct("MyBitField")
801                         .field("a", &self.get_a())
802                         .field("b", &self.get_b())
803                         .field("c", &self.get_c())
804                         .finish()
805                 }
806             }
807         };
808 
809         assert_eq!(
810             bitfield_impl(&input).unwrap().to_string(),
811             expected.to_string()
812         );
813     }
814 }
815