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