1use std::str::FromStr;
8
9use proc_macro::TokenStream;
10use proc_macro2::{Literal, Span, TokenStream as TokenStream2};
11use quote::{format_ident, quote, ToTokens};
12use syn::parse::{Error, Parse, ParseStream, Result};
13use syn::spanned::Spanned;
14use syn::{
15 braced, parse_macro_input, parse_quote, Expr, ExprLit, Fields,
16 GenericArgument, Ident, ItemStruct, Lit, Pat, Path, PathArguments, Stmt,
17 Type,
18};
19
20#[proc_macro_attribute]
21pub fn bitfield_repr(attr: TokenStream, item: TokenStream) -> TokenStream {
22 let attr: TokenStream2 = attr.into();
23 let item: TokenStream2 = item.into();
24 quote! {
25 #[repr(#attr)]
26 #[derive(
27 Debug,
28 Eq,
29 PartialEq,
30 ::zerocopy::Immutable,
31 ::zerocopy::IntoBytes,
32 ::zerocopy::TryFromBytes,
33 )]
34 #item
35 }
36 .into()
37}
38
39#[proc_macro]
40pub fn layout(item: TokenStream) -> TokenStream {
41 parse_macro_input!(item as Bitfields)
42 .to_token_stream()
43 .into()
44}
45
46enum BaseType {
51 U8,
52 U16,
53 U32,
54 U64,
55 U128,
56}
57
58impl BaseType {
59 const fn high_bit(&self) -> usize {
60 match *self {
61 Self::U8 => 7,
62 Self::U16 => 15,
63 Self::U32 => 31,
64 Self::U64 => 63,
65 Self::U128 => 127,
66 }
67 }
68}
69
70struct BaseTypeDef {
71 def: Type,
72 ty: BaseType,
73}
74
75impl TryFrom<Type> for BaseTypeDef {
76 type Error = Error;
77
78 fn try_from(type_def: Type) -> Result<Self> {
79 const INVALID_BASE_TYPE: &str =
80 "base type must be an unsigned integral type";
81 let Type::Path(ref path_ty) = type_def else {
82 return Err(Error::new_spanned(type_def, INVALID_BASE_TYPE));
83 };
84 let path = &path_ty.path;
85 let ty = if path.is_ident("u8") {
86 BaseType::U8
87 } else if path.is_ident("u16") {
88 BaseType::U16
89 } else if path.is_ident("u32") {
90 BaseType::U32
91 } else if path.is_ident("u64") {
92 BaseType::U64
93 } else if path.is_ident("u128") {
94 BaseType::U128
95 } else {
96 return Err(Error::new_spanned(path, INVALID_BASE_TYPE));
97 };
98 Ok(Self { def: type_def, ty })
99 }
100}
101
102struct TypeDef {
103 def: ItemStruct,
104 base: BaseTypeDef,
105}
106
107impl Parse for TypeDef {
108 fn parse(input: ParseStream) -> Result<Self> {
109 let mut strct: ItemStruct = input.parse()?;
110
111 let mut repr = false;
114 for attr in &strct.attrs {
115 if attr.path().is_ident("derive") {
116 attr.parse_nested_meta(|meta| {
117 for t in &[
118 "Copy",
119 "Clone",
120 "Debug",
121 "Default",
122 "Eq",
123 "PartialEq",
124 ] {
125 if meta.path.is_ident(t) {
126 return Err(Error::new_spanned(
127 meta.path,
128 format!("layout! already derives {t}"),
129 ));
130 }
131 }
132 Ok(())
133 })?;
134 continue;
135 }
136
137 if attr.path().is_ident("repr") {
138 repr = true;
139 continue;
140 }
141 }
142 if !repr {
143 strct.attrs.push(parse_quote!(#[repr(transparent)]));
144 }
145
146 let base_type = if let Fields::Unnamed(ref fields) = &strct.fields {
148 if fields.unnamed.is_empty() {
149 return Err(Error::new_spanned(
150 &fields.unnamed,
151 "no base type provided",
152 ));
153 }
154 if fields.unnamed.len() > 1 {
155 return Err(Error::new_spanned(
156 &fields.unnamed,
157 "too many tuple fields; only the base type should be provided",
158 ));
159 }
160 BaseTypeDef::try_from(fields.unnamed.first().unwrap().ty.clone())?
161 } else {
162 return Err(Error::new_spanned(
163 &strct.fields,
164 "bitfld type must be defined as a tuple struct",
165 ));
166 };
167
168 Ok(Self {
169 def: strct,
170 base: base_type,
171 })
172 }
173}
174
175struct Bitfield {
180 span: Span,
181 name: Option<Ident>,
182 high_bit: usize,
183 low_bit: usize,
184 repr: Option<Type>,
185
186 default: Option<Box<Expr>>,
188
189 shifted_mask: TokenStream2,
191}
192
193impl Bitfield {
194 fn new(
195 span: Span,
196 name: Option<Ident>,
197 high_bit: usize,
198 low_bit: usize,
199 repr: Option<Type>,
200 default: Option<Box<Expr>>,
201 ) -> Self {
202 let shifted_mask = {
203 let num_ones = high_bit - low_bit + 1;
204 let mut mask_str = "0x".to_string();
205
206 if num_ones % 4 != 0 {
210 mask_str.push(match num_ones % 4 {
211 1 => '1',
212 2 => '3',
213 3 => '7',
214 _ => unreachable!(),
215 });
216 }
217
218 let mut remaining = num_ones / 4;
219 while remaining > 0 {
220 if mask_str.len() > 2 && remaining % 4 == 0 {
221 mask_str.push('_');
222 }
223 mask_str.push('f');
224 remaining -= 1;
225 }
226 TokenStream2::from_str(&mask_str).unwrap()
227 };
228
229 Self {
230 span,
231 name,
232 high_bit,
233 low_bit,
234 repr,
235 default,
236 shifted_mask,
237 }
238 }
239
240 const fn is_reserved(&self) -> bool {
241 self.name.is_none()
242 }
243
244 const fn bit_width(&self) -> usize {
245 self.high_bit - self.low_bit + 1
246 }
247
248 fn minimum_width_integral_type(&self) -> TokenStream2 {
249 match self.bit_width() {
250 2..=8 => quote! {u8},
251 9..=16 => quote! {u16},
252 17..=32 => quote! {u32},
253 33..=64 => quote! {u64},
254 65..=128 => quote! {u128},
255 width => panic!("unexpected integral bit width: {width}"),
256 }
257 }
258
259 fn getter_and_setter(&self, base: &BaseTypeDef) -> TokenStream2 {
260 debug_assert!(!self.is_reserved());
261
262 let name = self.name.as_ref().unwrap();
263 let setter_name = format_ident!("set_{}", name);
264
265 let base_type = &base.def;
266 let low_bit = Literal::usize_unsuffixed(self.low_bit);
267 let bit_width = self.bit_width();
268
269 if bit_width == 1 {
270 return quote! {
271 #[inline]
272 pub const fn #name(&self) -> bool {
273 (self.0 & (1 << #low_bit)) != 0
274 }
275
276 #[inline]
277 pub const fn #setter_name(&mut self, value: bool) -> &mut Self {
278 if value {
279 self.0 |= (1 << #low_bit);
280 } else {
281 self.0 &= (1 << #low_bit);
282 }
283 self
284 }
285 };
286 }
287
288 let min_width = self.minimum_width_integral_type();
289 let shifted_mask = &self.shifted_mask;
290 let get_value =
291 quote! { ((self.0 >> #low_bit) & #shifted_mask) as #min_width };
292 let getter = if self.repr.is_some() {
293 let repr = self.repr.as_ref().unwrap();
294 quote! {
295 #[inline]
296 pub fn #name(&self)
297 -> ::core::result::Result<#repr, ::bitfld::InvalidBits<#min_width>>
298 where
299 #repr: ::zerocopy::TryFromBytes,
300 {
301 use ::zerocopy::IntoBytes;
302 use ::zerocopy::TryFromBytes;
303 let value = #get_value;
304 #repr::try_read_from_bytes(value.as_bytes())
305 .map_err(|_| ::bitfld::InvalidBits(value))
306 }
307 }
308 } else {
309 quote! {
310 #[inline]
311 pub const fn #name(&self) -> #min_width {
312 #get_value
313 }
314 }
315 };
316
317 let set_value = {
318 let value_check = if bit_width >= 8 && bit_width.is_power_of_two() {
319 quote! {}
320 } else {
321 quote! { debug_assert!((value & !#shifted_mask) == 0); }
322 };
323 quote! {
324 #value_check
325 self.0 &= !(#shifted_mask << #low_bit);
326 self.0 |= ((value & #shifted_mask) as #base_type) << #low_bit;
327 }
328 };
329
330 let setter = if self.repr.is_some() {
331 let repr = self.repr.as_ref().unwrap();
332 quote! {
333 #[inline]
334 pub fn #setter_name(&mut self, value: #repr) -> &mut Self
335 where
336 #repr: ::zerocopy::IntoBytes + ::zerocopy::Immutable
337 {
338 use ::zerocopy::IntoBytes;
339 use ::zerocopy::FromBytes;
340 const { assert!(::core::mem::size_of::<#repr>() == ::core::mem::size_of::<#min_width>()) }
341 let value = #min_width::read_from_bytes(value.as_bytes()).unwrap();
342 #set_value
343 self
344 }
345 }
346 } else {
347 quote! {
348 #[inline]
349 pub const fn #setter_name(&mut self, value: #min_width) -> &mut Self {
350 #set_value
351 self
352 }
353 }
354 };
355
356 quote! {
357 #getter
358 #setter
359 }
360 }
361}
362
363impl Parse for Bitfield {
364 fn parse(input: ParseStream) -> Result<Self> {
365 const INVALID_BITFIELD_DECL_FORM: &str =
366 "bitfield declaration should take one of the following forms:\n\
367 * `let $name: Bit<$bit> (= $default)?;`\n\
368 * `let $name: Bits<$high, $low (, $repr)?> (= $default)?;`\n\
369 * `let _: Bit<$bit> (= $value)?;`\n\
370 * `let _: Bits<$high, $low> (= $value)?;`";
371 let err = |spanned: &dyn ToTokens| {
372 Error::new_spanned(spanned, INVALID_BITFIELD_DECL_FORM)
373 };
374
375 let stmt = input.parse::<Stmt>()?;
376 let Stmt::Local(ref local) = stmt else {
377 return Err(err(&stmt));
378 };
379 let Pat::Type(ref pat_type) = local.pat else {
380 return Err(err(&local));
381 };
382
383 let name: Option<Ident> = match *pat_type.pat {
384 Pat::Ident(ref pat_ident) => {
385 if pat_ident.by_ref.is_some() {
386 return Err(err(pat_ident.by_ref.as_ref().unwrap()));
387 }
388 if pat_ident.mutability.is_some() {
389 return Err(err(pat_ident.mutability.as_ref().unwrap()));
390 }
391 if pat_ident.subpat.is_some() {
392 return Err(err(&pat_ident.subpat.as_ref().unwrap().0));
393 }
394 Some(pat_ident.ident.clone())
395 }
396 Pat::Wild(_) => None,
397 _ => return Err(err(&*pat_type.pat)),
398 };
399
400 let path: &Path = if let Type::Path(ref type_path) = *pat_type.ty {
401 if type_path.qself.is_some() {
402 return Err(err(&*pat_type.ty));
403 }
404 &type_path.path
405 } else {
406 return Err(err(&*pat_type.ty));
407 };
408
409 let get_bits_and_repr = |bits: &mut [usize]| -> Result<Option<Type>> {
410 let args = &path.segments.first().unwrap().arguments;
411 let args =
412 if let PathArguments::AngleBracketed(ref bracketed) = args {
413 &bracketed.args
414 } else {
415 return Err(err(&args));
416 };
417 if args.len() < bits.len() || args.len() > bits.len() + 1 {
418 return Err(err(&args));
419 }
420 for (i, bit) in bits.iter_mut().enumerate() {
421 let arg = args.get(i).unwrap();
422 match arg {
423 GenericArgument::Const(Expr::Lit(ExprLit {
424 lit: Lit::Int(b),
425 ..
426 })) => {
427 *bit = b.base10_parse()?;
428 }
429 _ => return Err(err(&arg)),
430 };
431 }
432 if args.len() == bits.len() + 1 {
433 let arg = args.last().unwrap();
434 if let GenericArgument::Type(repr) = arg {
435 Ok(Some(repr.clone()))
436 } else {
437 Err(err(&arg))
438 }
439 } else {
440 Ok(None)
441 }
442 };
443
444 let type_ident = &path.segments.first().unwrap().ident;
445 let (high, low, repr) = if type_ident == "Bits" {
446 let mut bits = [0usize; 2];
447 let repr = get_bits_and_repr(&mut bits)?;
448 if bits[0] < bits[1] {
449 Err(Error::new_spanned(
450 &path.segments,
451 "first high bit, then low",
452 ))
453 } else {
454 Ok((bits[0], bits[1], repr))
455 }
456 } else if type_ident == "Bit" {
457 let mut bit = [0usize; 1];
458 let repr = get_bits_and_repr(&mut bit)?;
459 Ok((bit[0], bit[0], repr))
460 } else {
461 Err(err(path))
462 }?;
463
464 let default_or_value = if let Some(ref init) = local.init {
465 if init.diverge.is_some() {
466 return Err(err(local));
467 }
468 Some(init.expr.clone())
469 } else {
470 None
471 };
472
473 if repr.is_some() {
474 if name.is_none() {
475 return Err(Error::new_spanned(
476 repr,
477 "custom representations are not permitted for reserved fields",
478 ));
479 }
480 if high == low {
481 return Err(Error::new_spanned(
482 repr,
483 "custom representations are not permitted for bits",
484 ));
485 }
486 }
487
488 Ok(Bitfield::new(
489 stmt.span(),
490 name,
491 high,
492 low,
493 repr,
494 default_or_value,
495 ))
496 }
497}
498
499struct Bitfields {
500 ty: TypeDef,
501 named: Vec<Bitfield>,
502 reserved: Vec<Bitfield>,
503}
504
505impl Bitfields {
506 fn constants(&self) -> TokenStream2 {
507 let base = &self.ty.base.def;
508
509 let mut field_constants = Vec::new();
510 let mut checks = Vec::new();
511 let mut default_values = vec![quote! {Self::RSVD1_MASK}];
512
513 for field in &self.named {
514 let field_name =
515 field.name.as_ref().unwrap().to_string().to_uppercase();
516 let low_bit = Literal::usize_unsuffixed(field.low_bit);
517 let shifted_mask = &field.shifted_mask;
518
519 if field.bit_width() == 1 {
520 let bit_name = format_ident!("{field_name}_BIT");
521 field_constants.push(quote! {
522 pub const #bit_name: usize = #low_bit;
523 });
524 } else {
525 let mask_name = format_ident!("{field_name}_MASK");
526 let shift_name = format_ident!("{field_name}_SHIFT");
527 field_constants.push(quote! {
528 pub const #mask_name: #base = #shifted_mask;
529 pub const #shift_name: usize = #low_bit;
530 });
531 }
532
533 if field.default.is_some() {
534 let default = field.default.as_ref().unwrap();
535
536 let default_name = format_ident!("{field_name}_DEFAULT");
537 field_constants.push(quote! {
538 pub const #default_name: #base = ((#default) as #base) << #low_bit;
539 });
540 checks.push(quote! {
541 const { assert!(Self::#default_name & !(#shifted_mask << #low_bit) == 0) }
542 });
543 default_values.push(quote! { Self::#default_name });
544 }
545 }
546
547 let mut rsvd1_values = Vec::new();
548 let mut rsvd0_values = Vec::new();
549 for rsvd in &self.reserved {
550 let rsvd_value = rsvd.default.as_ref().unwrap();
551 let low_bit = Literal::usize_unsuffixed(rsvd.low_bit);
552 let shifted_mask = &rsvd.shifted_mask;
553 let name = format_ident!("RSVD_{}_{}", rsvd.high_bit, rsvd.low_bit);
554
555 field_constants.push(quote! {
556 const #name: #base = (#rsvd_value as #base) << #low_bit;
557 });
558 checks.push(quote! {
559 const { assert!(Self::#name & !(#shifted_mask << #low_bit) == 0) }
560 });
561 rsvd1_values.push(quote! { Self::#name });
562 rsvd0_values.push(quote! {
563 (!Self::#name & (#shifted_mask << #low_bit))
564 });
565 }
566
567 let field_constants = field_constants.into_iter();
568
569 let check_fn = if checks.is_empty() {
570 quote! {}
571 } else {
572 let checks = checks.into_iter();
573 quote! {
574 #[forbid(overflowing_literals)]
575 const fn check_defaults() -> () {
576 #(#checks)*
577 }
578 }
579 };
580
581 if self.reserved.is_empty() {
582 rsvd1_values.push(quote! {0});
583 rsvd0_values.push(quote! {0});
584 }
585 let rsvd1_values = rsvd1_values.into_iter();
586 let rsvd0_values = rsvd0_values.into_iter();
587 let default_values = default_values.into_iter();
588
589 quote! {
590 pub const RSVD1_MASK: #base = #(#rsvd1_values)|* ;
591 pub const RSVD0_MASK: #base = #(#rsvd0_values)|* ;
592 pub const DEFAULT: #base = #(#default_values)|* ;
593
594 #(#field_constants)*
595
596 #check_fn
597 }
598 }
599
600 fn iter_impl(&self) -> TokenStream2 {
601 let ty = &self.ty.def.ident;
602 let base = &self.ty.base.def;
603 let num_fields = Literal::usize_unsuffixed(self.named.len());
604
605 let metadata = self.named.iter().map(|field| {
606 let low_bit = Literal::usize_unsuffixed(field.low_bit);
607 let high_bit = Literal::usize_unsuffixed(field.high_bit);
608 let name = field.name.as_ref().unwrap().to_string();
609 let default = if let Some(default) = &field.default {
610 quote! { #default }
611 } else {
612 quote! { 0 }
613 };
614 quote! {
615 ::bitfld::FieldMetadata::<#base>{
616 name: #name,
617 high_bit: #high_bit,
618 low_bit: #low_bit,
619 default: #default as #base,
620 },
621 }
622 });
623
624 let layout_metadata_impl = quote! {
625 impl ::bitfld::LayoutMetadata<#num_fields> for #ty {
626 type Base = #base;
627
628 const FIELDS: [::bitfld::FieldMetadata::<#base>; #num_fields] = [
629 #(#metadata)*
630 ];
631 }
632 };
633
634 let iter_type = format_ident!("{}Iter", ty);
635 let vis = &self.ty.def.vis;
636
637 quote! {
638 #layout_metadata_impl
639
640 #[allow(dead_code)]
641 #vis struct #iter_type(#base, usize);
642
643 impl ::core::iter::Iterator for #iter_type {
644 type Item = (#base, &'static ::bitfld::FieldMetadata<#base>);
645
646 fn next(&mut self) -> Option<Self::Item> {
647 if self.1 >= #num_fields {
648 return None;
649 }
650 let metadata = &<#ty as ::bitfld::LayoutMetadata<#num_fields>>::FIELDS[self.1];
651 let shifted_mask = (1 << (metadata.high_bit - metadata.low_bit + 1)) - 1;
652 let value = (self.0 >> metadata.low_bit) & shifted_mask;
653 self.1 += 1;
654 Some((value, metadata))
655 }
656 }
657
658 impl #ty {
659 pub fn iter(&self) -> #iter_type {
660 #iter_type(self.0, 0)
661 }
662 }
663
664 impl ::core::iter::IntoIterator for #ty {
665 type Item = <#iter_type as ::core::iter::Iterator>::Item;
666 type IntoIter = #iter_type;
667
668 fn into_iter(self) -> Self::IntoIter { self.iter() }
669 }
670
671 impl<'a> ::core::iter::IntoIterator for &'a #ty {
672 type Item = <#iter_type as ::core::iter::Iterator>::Item;
673 type IntoIter = #iter_type;
674
675 fn into_iter(self) -> Self::IntoIter { self.iter() }
676 }
677 }
678 }
679
680 fn getters_and_setters(&self) -> impl Iterator<Item = TokenStream2> + '_ {
681 self.named
682 .iter()
683 .map(|field| field.getter_and_setter(&self.ty.base))
684 }
685
686 fn fmt_fn(&self, integral_specifier: &str) -> TokenStream2 {
687 let ty_str = &self.ty.def.ident.to_string();
688
689 let mut custom_repr_fields = self
690 .named
691 .iter()
692 .filter(|field| field.repr.is_some())
693 .peekable();
694
695 let where_clause = if custom_repr_fields.peek().is_some() {
696 let bounds = custom_repr_fields.map(|field| {
697 let repr = field.repr.as_ref().unwrap();
698 quote! {#repr: ::core::fmt::Debug,}
699 });
700 quote! {
701 where
702 #(#bounds)*
703 }
704 } else {
705 quote! {}
706 };
707
708 let fmt_fields = self.named.iter().enumerate().map(|(idx, field)| {
709 let name = &field.name;
710 let name_str = name.as_ref().unwrap().to_string();
711 let default_specifier = if field.bit_width() == 1 {
712 ""
713 } else {
714 integral_specifier
715 };
716 let comma = if idx < self.named.len() - 1 { "," } else { "" };
717 if field.repr.is_some() {
718 let ok_format_string = format!("{{indent}}{name_str}: {{:#?}}{comma}{{sep}}");
719 let ok_format_string = Literal::string(&ok_format_string);
720 let err_format_string = format!(
721 "{{indent}}{name_str}: InvalidBits({{{default_specifier}}}){comma}{{sep}}"
722 );
723 let err_format_string = Literal::string(&err_format_string);
724 quote! {
725 match self.#name() {
726 Ok(value) => write!(f, #ok_format_string, value),
727 Err(invalid) => write!(f, #err_format_string, invalid.0),
728 }?;
729 }
730 } else {
731 let format_string =
732 format!("{{indent}}{name_str}: {{{default_specifier}}}{comma}{{sep}}");
733 let format_string = Literal::string(&format_string);
734 quote! {write!(f, #format_string, self.#name())?;}
735 }
736 });
737
738 quote! {
739 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result
740 #where_clause
741 {
742 let (sep, indent) = if f.alternate() {
743 ('\n', " ")
744 } else {
745 (' ', "")
746 };
747 write!(f, "{} {{{sep}", #ty_str)?;
748 #(#fmt_fields)*
749 write!(f, "}}")
750 }
751 }
752 }
753
754 fn fmt_impls(&self) -> TokenStream2 {
755 let ty = &self.ty.def.ident;
756 let lower_hex_fmt = self.fmt_fn(":#x");
757 let upper_hex_fmt = self.fmt_fn(":#X");
758 let binary_fmt = self.fmt_fn(":#b");
759 let octal_fmt = self.fmt_fn(":#o");
760 quote! {
761 impl ::core::fmt::Display for #ty {
762 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
763 ::core::fmt::LowerHex::fmt(self, f)
764 }
765 }
766
767 impl ::core::fmt::Debug for #ty {
768 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
769 ::core::fmt::LowerHex::fmt(self, f)
770 }
771 }
772
773 impl ::core::fmt::Binary for #ty {
774 #binary_fmt
775 }
776
777 impl ::core::fmt::LowerHex for #ty {
778 #lower_hex_fmt
779 }
780
781 impl ::core::fmt::UpperHex for #ty {
782 #upper_hex_fmt
783 }
784
785 impl ::core::fmt::Octal for #ty {
786 #octal_fmt
787 }
788 }
789 }
790}
791
792impl Parse for Bitfields {
793 fn parse(input: ParseStream) -> Result<Self> {
794 let input = {
795 let content;
796 braced!(content in input);
797 content
798 };
799
800 let ty = input.parse::<TypeDef>()?;
801
802 let input = {
803 let content;
804 braced!(content in input);
805 content
806 };
807
808 let mut fields = Vec::new();
809 while !input.is_empty() {
810 fields.push(input.parse::<Bitfield>()?);
811 }
812 fields.sort_by_key(|field| field.low_bit);
813
814 for i in 1..fields.len() {
815 let prev = &fields[i - 1];
816 let curr = &fields[i];
817 if prev.high_bit >= curr.low_bit {
818 return Err(Error::new(
822 curr.span,
823 format!(
824 "field overlaps with another: [{}:{}] vs. [{}:{}]",
825 prev.high_bit,
826 prev.low_bit,
827 curr.high_bit,
828 curr.low_bit
829 ),
830 ));
831 }
832 }
833
834 if let Some(highest) = fields.last() {
835 let highest_possible = ty.base.ty.high_bit();
836 if highest.high_bit > highest_possible {
837 return Err(Error::new(
838 highest.span,
839 format!(
840 "high bit {} exceeds the highest possible value of {highest_possible}",
841 highest.high_bit
842 ),
843 ));
844 }
845 }
846
847 let mut bitfld = Self {
848 ty,
849 named: vec![],
850 reserved: vec![],
851 };
852
853 while let Some(field) = fields.pop() {
854 if field.is_reserved() {
855 if field.default.is_some() {
856 bitfld.reserved.push(field);
857 }
858 } else {
859 bitfld.named.push(field);
860 }
861 }
862
863 Ok(bitfld)
864 }
865}
866
867impl ToTokens for Bitfields {
868 fn to_tokens(&self, tokens: &mut TokenStream2) {
869 let type_def = &self.ty.def;
870 let type_name = &type_def.ident;
871 let base = &self.ty.base.def;
872
873 let constants = self.constants();
874 let getters_and_setters = self.getters_and_setters();
875 let iter_impl = self.iter_impl();
876 let fmt_impls = self.fmt_impls();
877 quote! {
878 #[derive(Copy, Clone, Eq, PartialEq)]
879 #type_def
880
881 impl #type_name {
882 #constants
883
884 pub const fn new() -> Self {
885 Self(Self::RSVD1_MASK)
886 }
887
888 #(#getters_and_setters)*
889 }
890
891 impl ::core::default::Default for #type_name {
892 fn default() -> Self {
893 Self(Self::DEFAULT)
894 }
895 }
896
897 impl ::core::convert::From<#base> for #type_name {
898 #[allow(clippy::bad_bit_mask)]
901 fn from(value: #base) -> Self {
902 debug_assert!(
903 value & Self::RSVD1_MASK == Self::RSVD1_MASK,
904 "from(): Invalid base value ({value:#x}) has reserved-as-1 bits ({:#x}) unset",
905 Self::RSVD1_MASK,
906 );
907 debug_assert!(
908 !value & Self::RSVD0_MASK == Self::RSVD0_MASK,
909 "from(): Invalid base value ({value:#x}) has reserved-as-0 bits ({:#x}) set",
910 Self::RSVD0_MASK,
911 );
912 Self(value)
913 }
914 }
915
916 impl ::core::ops::Deref for #type_name {
917 type Target = #base;
918
919 fn deref(&self) -> &Self::Target {
920 &self.0
921 }
922 }
923
924 impl ::core::ops::DerefMut for #type_name {
925 fn deref_mut(&mut self) -> &mut Self::Target {
926 &mut self.0
927 }
928 }
929
930 #iter_impl
931
932 #fmt_impls
933 }
934 .to_tokens(tokens);
935 }
936}