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