bit_field_derive/
bit_field_derive.rs

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
7extern crate proc_macro;
8
9use proc_macro2::Span;
10use proc_macro2::TokenStream;
11use quote::quote;
12use quote::quote_spanned;
13use syn::parse::Error;
14use syn::parse::Result;
15use syn::parse_macro_input;
16use syn::Attribute;
17use syn::Data;
18use syn::DataEnum;
19use syn::DeriveInput;
20use syn::Fields;
21use syn::FieldsNamed;
22use syn::FieldsUnnamed;
23use syn::Ident;
24use syn::Lit;
25use syn::LitInt;
26use syn::Meta;
27use syn::MetaNameValue;
28use syn::Type;
29use syn::Visibility;
30
31/// The function that derives the actual implementation.
32#[proc_macro_attribute]
33pub 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
53fn 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
78fn 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
152fn 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
161fn 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//
234fn 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
286fn 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
339fn 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
362struct 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))
370fn 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]
391fn 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 = *].
410fn 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
426fn 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
444fn 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.
478fn 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.
525fn 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
548fn 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)]
620pub 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)]
664mod tests {
665    use syn::parse_quote;
666
667    use super::*;
668
669    #[test]
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}