1use std::collections::HashSet;
8use std::str::FromStr;
9
10use proc_macro::TokenStream;
11use proc_macro2::{Literal, Span, TokenStream as TokenStream2};
12use quote::{ToTokens, format_ident, quote};
13use syn::parse::discouraged::Speculative;
14use syn::parse::{Error, Parse, ParseStream, Result};
15use syn::spanned::Spanned;
16use syn::{
17 Attribute, Expr, ExprLit, Fields, GenericArgument, Ident, ItemStruct, Lit,
18 MetaNameValue, Pat, Path, PathArguments, Stmt, Type, braced,
19 parse_macro_input, parse_quote,
20};
21
22#[proc_macro_attribute]
23pub fn bitfield_repr(attr: TokenStream, item: TokenStream) -> TokenStream {
24 let attr: TokenStream2 = attr.into();
25 let item: TokenStream2 = item.into();
26 quote! {
27 #[repr(#attr)]
28 #[derive(
29 Debug,
30 Eq,
31 PartialEq,
32 ::zerocopy::Immutable,
33 ::zerocopy::IntoBytes,
34 ::zerocopy::TryFromBytes,
35 )]
36 #item
37 }
38 .into()
39}
40
41#[proc_macro]
42pub fn layout(item: TokenStream) -> TokenStream {
43 parse_macro_input!(item as Bitfields)
44 .to_token_stream()
45 .into()
46}
47
48enum BaseType {
53 U8,
54 U16,
55 U32,
56 U64,
57 U128,
58 Usize,
59}
60
61impl BaseType {
62 const fn high_bit(&self) -> Option<usize> {
63 match *self {
64 Self::U8 => Some(7),
65 Self::U16 => Some(15),
66 Self::U32 => Some(31),
67 Self::U64 => Some(63),
68 Self::U128 => Some(127),
69 Self::Usize => None,
70 }
71 }
72}
73
74struct BaseTypeDef {
75 def: Type,
76 ty: BaseType,
77}
78
79impl TryFrom<Type> for BaseTypeDef {
80 type Error = Error;
81
82 fn try_from(type_def: Type) -> Result<Self> {
83 const INVALID_BASE_TYPE: &str =
84 "base type must be an unsigned integral type";
85 let Type::Path(ref path_ty) = type_def else {
86 return Err(Error::new_spanned(type_def, INVALID_BASE_TYPE));
87 };
88 let path = &path_ty.path;
89 let ty = if path.is_ident("u8") {
90 BaseType::U8
91 } else if path.is_ident("u16") {
92 BaseType::U16
93 } else if path.is_ident("u32") {
94 BaseType::U32
95 } else if path.is_ident("u64") {
96 BaseType::U64
97 } else if path.is_ident("u128") {
98 BaseType::U128
99 } else if path.is_ident("usize") {
100 BaseType::Usize
101 } else {
102 return Err(Error::new_spanned(path, INVALID_BASE_TYPE));
103 };
104 Ok(Self { def: type_def, ty })
105 }
106}
107
108struct TypeDef {
109 def: ItemStruct,
110 base: BaseTypeDef,
111}
112
113impl Parse for TypeDef {
114 fn parse(input: ParseStream) -> Result<Self> {
115 let mut strct: ItemStruct = input.parse()?;
116
117 let mut repr = false;
120 for attr in &strct.attrs {
121 if attr.path().is_ident("derive") {
122 attr.parse_nested_meta(|meta| {
123 for t in &[
124 "Copy",
125 "Clone",
126 "Debug",
127 "Default",
128 "Eq",
129 "PartialEq",
130 ] {
131 if meta.path.is_ident(t) {
132 return Err(Error::new_spanned(
133 meta.path,
134 format!("layout! already derives {t}"),
135 ));
136 }
137 }
138 Ok(())
139 })?;
140 continue;
141 }
142
143 if attr.path().is_ident("repr") {
144 repr = true;
145 }
146 }
147 if !repr {
148 strct.attrs.push(parse_quote!(#[repr(transparent)]));
149 }
150
151 let base_type = if let Fields::Unnamed(fields) = &strct.fields {
153 if fields.unnamed.is_empty() {
154 return Err(Error::new_spanned(
155 &fields.unnamed,
156 "no base type provided",
157 ));
158 }
159 if fields.unnamed.len() > 1 {
160 return Err(Error::new_spanned(
161 &fields.unnamed,
162 "too many tuple fields; only the base type should be provided",
163 ));
164 }
165 BaseTypeDef::try_from(fields.unnamed.first().unwrap().ty.clone())?
166 } else {
167 return Err(Error::new_spanned(
168 &strct.fields,
169 "bitfld type must be defined as a tuple struct",
170 ));
171 };
172
173 if let Some(param) = strct.generics.type_params().next() {
174 return Err(Error::new_spanned(
175 ¶m.ident,
176 "only const generic parameters are supported",
177 ));
178 }
179 if let Some(param) = strct.generics.lifetimes().next() {
180 return Err(Error::new_spanned(
181 param,
182 "only const generic parameters are supported",
183 ));
184 }
185
186 Ok(Self {
187 def: strct,
188 base: base_type,
189 })
190 }
191}
192
193struct Bitfield {
198 span: Span,
199 name: Option<Ident>,
200 high_bit: usize,
201 low_bit: usize,
202 repr: Option<Type>,
203 cfg_pointer_width: Option<String>,
204
205 default: Option<Box<Expr>>,
207
208 shifted_mask: TokenStream2,
210}
211
212impl Bitfield {
213 fn new(
214 span: Span,
215 name: Option<Ident>,
216 high_bit: usize,
217 low_bit: usize,
218 repr: Option<Type>,
219 cfg_pointer_width: Option<String>,
220 default: Option<Box<Expr>>,
221 ) -> Self {
222 let shifted_mask = {
223 let num_ones = high_bit - low_bit + 1;
224 let mut mask_str = "0x".to_string();
225
226 if !num_ones.is_multiple_of(4) {
230 mask_str.push(match num_ones % 4 {
231 1 => '1',
232 2 => '3',
233 3 => '7',
234 _ => unreachable!(),
235 });
236 }
237
238 let mut remaining = num_ones / 4;
239 while remaining > 0 {
240 if mask_str.len() > 2 && remaining.is_multiple_of(4) {
241 mask_str.push('_');
242 }
243 mask_str.push('f');
244 remaining -= 1;
245 }
246 TokenStream2::from_str(&mask_str).unwrap()
247 };
248
249 Self {
250 span,
251 name,
252 high_bit,
253 low_bit,
254 repr,
255 cfg_pointer_width,
256 default,
257 shifted_mask,
258 }
259 }
260
261 const fn is_reserved(&self) -> bool {
262 self.name.is_none()
263 }
264
265 fn display_name(&self) -> String {
266 match &self.name {
267 Some(name) => format!("`{name}`"),
268 None => "reserved".to_string(),
269 }
270 }
271
272 fn display_kind(&self) -> &'static str {
273 if self.bit_width() == 1 {
274 "bit"
275 } else {
276 "field"
277 }
278 }
279
280 fn display_range(&self) -> String {
281 if self.bit_width() == 1 {
282 format!("{}", self.low_bit)
283 } else {
284 format!("[{}:{}]", self.high_bit, self.low_bit)
285 }
286 }
287
288 const fn bit_width(&self) -> usize {
289 self.high_bit - self.low_bit + 1
290 }
291
292 fn minimum_width_integral_type(&self) -> TokenStream2 {
293 match self.bit_width() {
294 2..=8 => quote! {u8},
295 9..=16 => quote! {u16},
296 17..=32 => quote! {u32},
297 33..=64 => quote! {u64},
298 65..=128 => quote! {u128},
299 width => panic!("unexpected integral bit width: {width}"),
300 }
301 }
302
303 fn getter_and_setter(&self, ty: &TypeDef) -> TokenStream2 {
304 debug_assert!(!self.is_reserved());
305
306 let cfg_attr = cfg_attr(self);
307 let name = self.name.as_ref().unwrap();
308 let setter_name = format_ident!("set_{}", name);
309
310 let base_type = &ty.base.def;
311 let ty = &ty.def.ident;
312 let low_bit = Literal::usize_unsuffixed(self.low_bit);
313 let bit_width = self.bit_width();
314
315 if bit_width == 1 {
316 let get_doc = format!(
317 "Returns the value of the `{name}` bit (i.e., {ty}[{}]).",
318 self.low_bit,
319 );
320 let set_doc = format!(
321 "Sets the value of the `{name}` bit (i.e., {ty}[{}]).",
322 self.low_bit,
323 );
324 return quote! {
325 #cfg_attr
326 #[doc = #get_doc]
327 #[inline]
328 pub const fn #name(&self) -> bool {
329 (self.0 & (1 << #low_bit)) != 0
330 }
331
332 #cfg_attr
333 #[doc = #set_doc]
334 #[inline]
335 pub const fn #setter_name(&mut self, value: bool) -> &mut Self {
336 if value {
337 self.0 |= (1 << #low_bit);
338 } else {
339 self.0 &= !(1 << #low_bit);
340 }
341 self
342 }
343 };
344 }
345
346 let get_doc = format!(
347 "Returns the value of the `{name}` field (i.e., `{ty}[{}:{}]`).",
348 self.high_bit, self.low_bit,
349 );
350 let set_doc = format!(
351 "Sets the value of the `{name}` field (i.e., `{ty}[{}:{}]`).",
352 self.high_bit, self.low_bit,
353 );
354
355 let min_width = self.minimum_width_integral_type();
356 let shifted_mask = &self.shifted_mask;
357 let get_value =
358 quote! { ((self.0 >> #low_bit) & #shifted_mask) as #min_width };
359 let getter = if let Some(repr) = &self.repr {
360 quote! {
361 #[doc = #get_doc]
362 #[inline]
363 pub fn #name(&self)
364 -> ::core::result::Result<#repr, ::bitfld::InvalidBits<#min_width>>
365 where
366 #repr: ::zerocopy::TryFromBytes,
367 {
368 use ::zerocopy::IntoBytes;
369 use ::zerocopy::TryFromBytes;
370 let value = #get_value;
371 #repr::try_read_from_bytes(value.as_bytes())
372 .map_err(|_| ::bitfld::InvalidBits(value))
373 }
374 }
375 } else {
376 quote! {
377 #[doc = #get_doc]
378 #[inline]
379 pub const fn #name(&self) -> #min_width {
380 #get_value
381 }
382 }
383 };
384
385 let set_value = {
386 let value_check = if bit_width >= 8 && bit_width.is_power_of_two() {
387 quote! {}
388 } else {
389 quote! { debug_assert!((value & !#shifted_mask) == 0); }
390 };
391 quote! {
392 #value_check
393 self.0 &= !(#shifted_mask << #low_bit);
394 self.0 |= ((value & #shifted_mask) as #base_type) << #low_bit;
395 }
396 };
397
398 let setter = if let Some(repr) = &self.repr {
399 quote! {
400 #[doc = #set_doc]
401 #[inline]
402 pub fn #setter_name(&mut self, value: #repr) -> &mut Self
403 where
404 #repr: ::zerocopy::IntoBytes + ::zerocopy::Immutable
405 {
406 use ::zerocopy::IntoBytes;
407 use ::zerocopy::FromBytes;
408 const { assert!(::core::mem::size_of::<#repr>() == ::core::mem::size_of::<#min_width>()) }
409 let value = #min_width::read_from_bytes(value.as_bytes()).unwrap();
410 #set_value
411 self
412 }
413 }
414 } else {
415 quote! {
416 #[doc = #set_doc]
417 #[inline]
418 pub const fn #setter_name(&mut self, value: #min_width) -> &mut Self {
419 #set_value
420 self
421 }
422 }
423 };
424
425 quote! {
426 #cfg_attr
427 #getter
428 #cfg_attr
429 #setter
430 }
431 }
432}
433
434fn cfg_attr(field: &Bitfield) -> Option<TokenStream2> {
435 field.cfg_pointer_width.as_ref().map(|w| {
436 quote! { #[cfg(target_pointer_width = #w)] }
437 })
438}
439
440impl Parse for Bitfield {
441 fn parse(input: ParseStream) -> Result<Self> {
442 const INVALID_BITFIELD_DECL_FORM: &str = "bitfield declaration should take one of the following forms:\n\
443 * `let $name: Bit<$bit> (= $default)?;`\n\
444 * `let $name: Bits<$high, $low (, $repr)?> (= $default)?;`\n\
445 * `let _: Bit<$bit> (= $value)?;`\n\
446 * `let _: Bits<$high, $low> (= $value)?;`";
447 let err = |spanned: &dyn ToTokens| {
448 Error::new_spanned(spanned, INVALID_BITFIELD_DECL_FORM)
449 };
450
451 let stmt = input.parse::<Stmt>()?;
452 let Stmt::Local(ref local) = stmt else {
453 return Err(err(&stmt));
454 };
455
456 if let Some(attr) = local.attrs.first() {
457 return Err(Error::new_spanned(
458 attr,
459 "attributes are not permitted on individual fields",
460 ));
461 }
462
463 let Pat::Type(ref pat_type) = local.pat else {
464 return Err(err(&local));
465 };
466
467 let name: Option<Ident> = match *pat_type.pat {
468 Pat::Ident(ref pat_ident) => {
469 if let Some(by_ref) = &pat_ident.by_ref {
470 return Err(err(by_ref));
471 }
472 if let Some(mutability) = &pat_ident.mutability {
473 return Err(err(mutability));
474 }
475 if let Some(subpat) = &pat_ident.subpat {
476 return Err(err(&subpat.0));
477 }
478 Some(pat_ident.ident.clone())
479 }
480 Pat::Wild(_) => None,
481 _ => return Err(err(&*pat_type.pat)),
482 };
483
484 let path: &Path = if let Type::Path(ref type_path) = *pat_type.ty {
485 if type_path.qself.is_some() {
486 return Err(err(&*pat_type.ty));
487 }
488 &type_path.path
489 } else {
490 return Err(err(&*pat_type.ty));
491 };
492
493 let get_bits_and_repr = |bits: &mut [usize]| -> Result<Option<Type>> {
494 let args = &path.segments.first().unwrap().arguments;
495 let args = if let PathArguments::AngleBracketed(bracketed) = args {
496 &bracketed.args
497 } else {
498 return Err(err(&args));
499 };
500 if args.len() < bits.len() || args.len() > bits.len() + 1 {
501 return Err(err(&args));
502 }
503 for (i, bit) in bits.iter_mut().enumerate() {
504 let arg = args.get(i).unwrap();
505 match arg {
506 GenericArgument::Const(Expr::Lit(ExprLit {
507 lit: Lit::Int(b),
508 ..
509 })) => {
510 *bit = b.base10_parse()?;
511 }
512 _ => return Err(err(&arg)),
513 }
514 }
515 if args.len() == bits.len() + 1 {
516 let arg = args.last().unwrap();
517 if let GenericArgument::Type(repr) = arg {
518 Ok(Some(repr.clone()))
519 } else {
520 Err(err(&arg))
521 }
522 } else {
523 Ok(None)
524 }
525 };
526
527 let type_ident = &path.segments.first().unwrap().ident;
528 let (high, low, repr) = if type_ident == "Bits" {
529 let mut bits = [0usize; 2];
530 let repr = get_bits_and_repr(&mut bits)?;
531 if bits[0] < bits[1] {
532 Err(Error::new_spanned(
533 &path.segments,
534 "first high bit, then low",
535 ))
536 } else {
537 Ok((bits[0], bits[1], repr))
538 }
539 } else if type_ident == "Bit" {
540 let mut bit = [0usize; 1];
541 let repr = get_bits_and_repr(&mut bit)?;
542 Ok((bit[0], bit[0], repr))
543 } else {
544 Err(err(path))
545 }?;
546
547 let default_or_value = if let Some(ref init) = local.init {
548 if init.diverge.is_some() {
549 return Err(err(local));
550 }
551 Some(init.expr.clone())
552 } else {
553 None
554 };
555
556 if repr.is_some() {
557 if name.is_none() {
558 return Err(Error::new_spanned(
559 repr,
560 "custom representations are not permitted for reserved fields",
561 ));
562 }
563 if high == low {
564 return Err(Error::new_spanned(
565 repr,
566 "custom representations are not permitted for bits",
567 ));
568 }
569 }
570
571 Ok(Bitfield::new(
572 stmt.span(),
573 name,
574 high,
575 low,
576 repr,
577 None,
578 default_or_value,
579 ))
580 }
581}
582
583fn parse_target_pointer_width_cfg(attr: &Attribute) -> Result<String> {
586 const ERROR_MSG: &str = "expected #[cfg(target_pointer_width = \"...\")]";
587 let meta = attr
588 .meta
589 .require_list()
590 .map_err(|_| Error::new_spanned(attr, ERROR_MSG))?;
591 let cfg: MetaNameValue = meta
592 .parse_args()
593 .map_err(|_| Error::new_spanned(attr, ERROR_MSG))?;
594 if !cfg.path.is_ident("target_pointer_width") {
595 return Err(Error::new_spanned(attr, ERROR_MSG));
596 }
597 match cfg.value {
598 Expr::Lit(ExprLit {
599 lit: Lit::Str(s), ..
600 }) => Ok(s.value()),
601 _ => Err(Error::new_spanned(attr, ERROR_MSG)),
602 }
603}
604
605struct Bitfields {
606 ty: TypeDef,
607 named: Vec<Bitfield>,
608 reserved: Vec<Bitfield>,
609 errors: Vec<Error>,
610}
611
612impl Bitfields {
613 fn constants(&self) -> TokenStream2 {
614 let base = &self.ty.base.def;
615 let is_usize = matches!(self.ty.base.ty, BaseType::Usize);
616
617 let mut field_constants = Vec::new();
618 let mut field_metadata = Vec::new();
619 let mut num_field_stmts = Vec::new();
620 let mut checks = Vec::new();
621 let mut default_stmts = Vec::new();
622
623 for field in &self.named {
624 let cfg_attr = cfg_attr(field);
625 let name_lower = field.name.as_ref().unwrap().to_string();
626 let name_upper = name_lower.to_uppercase();
627 let low_bit = Literal::usize_unsuffixed(field.low_bit);
628 let shifted_mask = &field.shifted_mask;
629
630 if field.bit_width() == 1 {
631 let bit_name = format_ident!("{name_upper}_BIT");
632 let doc = format!("Bit position of the `{name_lower}` field.",);
633 field_constants.push(quote! {
634 #cfg_attr
635 #[doc = #doc]
636 pub const #bit_name: usize = #low_bit;
637 });
638 } else {
639 let mask_name = format_ident!("{name_upper}_MASK");
640 let shift_name = format_ident!("{name_upper}_SHIFT");
641 let mask_doc =
642 format!("Unshifted bitmask of the `{name_lower}` field.");
643 let shift_doc = format!(
644 "Bit shift (i.e., the low bit) of the `{name_lower}` field."
645 );
646 field_constants.push(quote! {
647 #cfg_attr
648 #[doc = #mask_doc]
649 pub const #mask_name: #base = #shifted_mask;
650 #cfg_attr
651 #[doc = #shift_doc]
652 pub const #shift_name: usize = #low_bit;
653 });
654 }
655
656 if let Some(default) = &field.default {
657 let default_name = format_ident!("{name_upper}_DEFAULT");
658 let doc = format!(
659 "Pre-shifted default value of the `{name_lower}` field.",
660 );
661 field_constants.push(quote! {
662 #cfg_attr
663 #[doc = #doc]
664 pub const #default_name: #base = ((#default) as #base) << #low_bit;
665 });
666 checks.push(quote! {
667 #cfg_attr
668 const { assert!(((#default) as #base) << #low_bit & !(#shifted_mask << #low_bit) == 0) }
669 });
670 default_stmts.push(quote! {
671 #cfg_attr
672 { v |= Self::#default_name; }
673 });
674 }
675
676 if is_usize {
677 let high_bit = Literal::usize_unsuffixed(field.high_bit);
678 checks.push(quote! {
679 #cfg_attr
680 const { assert!(#high_bit < usize::BITS as usize) }
681 });
682 }
683
684 let high_bit = Literal::usize_unsuffixed(field.high_bit);
685 let default = if let Some(default) = &field.default {
686 quote! { #default }
687 } else {
688 quote! { 0 }
689 };
690 field_metadata.push(quote! {
691 #cfg_attr
692 ::bitfld::FieldMetadata::<#base>{
693 name: #name_lower,
694 high_bit: #high_bit,
695 low_bit: #low_bit,
696 default: #default as #base,
697 },
698 });
699 num_field_stmts.push(quote! {
700 #cfg_attr
701 { n += 1; }
702 });
703 }
704
705 let mut rsvd1_stmts = Vec::new();
706 let mut rsvd0_stmts = Vec::new();
707 for rsvd in &self.reserved {
708 let cfg_attr = cfg_attr(rsvd);
709 let rsvd_value = rsvd.default.as_ref().unwrap();
710 let low_bit = Literal::usize_unsuffixed(rsvd.low_bit);
711 let shifted_mask = &rsvd.shifted_mask;
712 let name = format_ident!("RSVD_{}_{}", rsvd.high_bit, rsvd.low_bit);
713
714 field_constants.push(quote! {
715 #cfg_attr
716 const #name: #base = (#rsvd_value as #base) << #low_bit;
717 });
718 checks.push(quote! {
719 #cfg_attr
720 const { assert!((#rsvd_value as #base) << #low_bit & !(#shifted_mask << #low_bit) == 0) }
721 });
722 rsvd1_stmts.push(quote! {
723 #cfg_attr
724 { v |= Self::#name; }
725 });
726 rsvd0_stmts.push(quote! {
727 #cfg_attr
728 { v |= !Self::#name & (#shifted_mask << #low_bit); }
729 });
730
731 if is_usize {
732 let high_bit = Literal::usize_unsuffixed(rsvd.high_bit);
733 checks.push(quote! {
734 #cfg_attr
735 const { assert!(#high_bit < usize::BITS as usize) }
736 });
737 }
738 }
739
740 let num_fields_expr = quote! {
741 {
742 let mut n = 0usize;
743 #(#num_field_stmts)*
744 n
745 }
746 };
747 field_constants.push(quote! {
748 #[doc(hidden)]
749 const NUM_FIELDS: usize = #num_fields_expr;
750 pub const FIELDS: [::bitfld::FieldMetadata::<#base>; #num_fields_expr] = [
752 #(#field_metadata)*
753 ];
754 });
755
756 let check_fn = if checks.is_empty() {
757 quote! {}
758 } else {
759 let checks = checks.into_iter();
760 quote! {
761 #[forbid(overflowing_literals)]
762 const fn check_defaults() -> () {
763 #(#checks)*
764 }
765 }
766 };
767
768 quote! {
769 pub const RSVD1_MASK: #base = {
771 let mut v: #base = 0;
772 #(#rsvd1_stmts)*
773 v
774 };
775 pub const RSVD0_MASK: #base = {
777 let mut v: #base = 0;
778 #(#rsvd0_stmts)*
779 v
780 };
781 pub const DEFAULT: #base = {
784 let mut v: #base = Self::RSVD1_MASK;
785 #(#default_stmts)*
786 v
787 };
788
789 #(#field_constants)*
790
791 #check_fn
792 }
793 }
794
795 fn iter_impl(&self) -> TokenStream2 {
796 let ty = &self.ty.def.ident;
797 let base = &self.ty.base.def;
798 let iter_type = format_ident!("{}Iter", ty);
799 let vis = &self.ty.def.vis;
800
801 let generics = &self.ty.def.generics;
802 let (impl_generics, ty_generics, where_clause) =
803 generics.split_for_impl();
804
805 let mut ref_generics = generics.clone();
806 ref_generics.params.insert(0, parse_quote!('a));
807 let (ref_impl_generics, _, _) = ref_generics.split_for_impl();
808
809 quote! {
810 #[doc(hidden)]
811 #vis struct #iter_type #impl_generics (#base, usize) #where_clause;
812
813 impl #impl_generics ::core::iter::Iterator for #iter_type #ty_generics #where_clause {
814 type Item = (&'static ::bitfld::FieldMetadata<#base>, #base);
815
816 fn next(&mut self) -> Option<Self::Item> {
817 if self.1 >= <#ty #ty_generics>::NUM_FIELDS {
818 return None;
819 }
820 let metadata = &<#ty #ty_generics>::FIELDS[self.1];
821 let shifted_mask = (1 << (metadata.high_bit - metadata.low_bit + 1)) - 1;
822 let value = (self.0 >> metadata.low_bit) & shifted_mask;
823 self.1 += 1;
824 Some((metadata, value))
825 }
826 }
827
828 impl #impl_generics #ty #ty_generics #where_clause {
829 pub fn iter(&self) -> #iter_type #ty_generics {
832 #iter_type(self.0, 0)
833 }
834 }
835
836 impl #impl_generics ::core::iter::IntoIterator for #ty #ty_generics #where_clause {
837 type Item = (&'static ::bitfld::FieldMetadata<#base>, #base);
838 type IntoIter = #iter_type #ty_generics;
839
840 fn into_iter(self) -> Self::IntoIter { #iter_type(self.0, 0) }
841 }
842
843 impl #ref_impl_generics ::core::iter::IntoIterator for &'a #ty #ty_generics #where_clause {
844 type Item = (&'static ::bitfld::FieldMetadata<#base>, #base);
845 type IntoIter = #iter_type #ty_generics;
846
847 fn into_iter(self) -> Self::IntoIter { #iter_type(self.0, 0) }
848 }
849 }
850 }
851
852 fn getters_and_setters(&self) -> impl Iterator<Item = TokenStream2> + '_ {
853 self.named
854 .iter()
855 .map(|field| field.getter_and_setter(&self.ty))
856 }
857
858 fn fmt_fn(&self, integral_specifier: &str) -> TokenStream2 {
859 let ty_str = &self.ty.def.ident.to_string();
860
861 let mut custom_repr_fields = self
862 .named
863 .iter()
864 .filter(|field| field.repr.is_some())
865 .peekable();
866
867 let where_clause = if custom_repr_fields.peek().is_some() {
868 let bounds = custom_repr_fields.map(|field| {
869 let repr = field.repr.as_ref().unwrap();
870 quote! {#repr: ::core::fmt::Debug,}
871 });
872 quote! {
873 where
874 #(#bounds)*
875 }
876 } else {
877 quote! {}
878 };
879
880 let fmt_fields = self.named.iter().map(|field| {
881 let cfg_attr = cfg_attr(field);
882 let name = &field.name;
883 let name_str = name.as_ref().unwrap().to_string();
884 let default_specifier = if field.bit_width() == 1 {
885 ""
886 } else {
887 integral_specifier
888 };
889 if field.repr.is_some() {
890 let ok_format_string =
891 format!("{{indent}}{name_str}: {{:#?}},{{sep}}");
892 let ok_format_string = Literal::string(&ok_format_string);
893 let err_format_string = format!(
894 "{{indent}}{name_str}: InvalidBits({{{default_specifier}}}),{{sep}}"
895 );
896 let err_format_string = Literal::string(&err_format_string);
897 quote! {
898 #cfg_attr
899 {
900 match self.#name() {
901 Ok(value) => write!(f, #ok_format_string, value),
902 Err(invalid) => write!(f, #err_format_string, invalid.0),
903 }?;
904 }
905 }
906 } else {
907 let format_string = format!(
908 "{{indent}}{name_str}: {{{default_specifier}}},{{sep}}"
909 );
910 let format_string = Literal::string(&format_string);
911 quote! {
912 #cfg_attr
913 { write!(f, #format_string, self.#name())?; }
914 }
915 }
916 });
917
918 quote! {
919 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result
920 #where_clause
921 {
922 let (sep, indent) = if f.alternate() {
923 ('\n', " ")
924 } else {
925 (' ', "")
926 };
927 write!(f, "{} {{{sep}", #ty_str)?;
928 #(#fmt_fields)*
929 write!(f, "}}")
930 }
931 }
932 }
933
934 fn fmt_impls(&self) -> TokenStream2 {
935 let ty = &self.ty.def.ident;
936 let (impl_generics, ty_generics, where_clause) =
937 self.ty.def.generics.split_for_impl();
938 let lower_hex_fmt = self.fmt_fn(":#x");
939 let upper_hex_fmt = self.fmt_fn(":#X");
940 let binary_fmt = self.fmt_fn(":#b");
941 let octal_fmt = self.fmt_fn(":#o");
942 quote! {
943 impl #impl_generics ::core::fmt::Debug for #ty #ty_generics #where_clause {
944 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
945 ::core::fmt::LowerHex::fmt(self, f)
946 }
947 }
948
949 impl #impl_generics ::core::fmt::Binary for #ty #ty_generics #where_clause {
950 #binary_fmt
951 }
952
953 impl #impl_generics ::core::fmt::LowerHex for #ty #ty_generics #where_clause {
954 #lower_hex_fmt
955 }
956
957 impl #impl_generics ::core::fmt::UpperHex for #ty #ty_generics #where_clause {
958 #upper_hex_fmt
959 }
960
961 impl #impl_generics ::core::fmt::Octal for #ty #ty_generics #where_clause {
962 #octal_fmt
963 }
964 }
965 }
966}
967
968impl Parse for Bitfields {
969 fn parse(input: ParseStream) -> Result<Self> {
970 let input = {
971 let content;
972 braced!(content in input);
973 content
974 };
975
976 let ty = input.parse::<TypeDef>()?;
977
978 let input = {
979 let content;
980 braced!(content in input);
981 content
982 };
983
984 let mut fields = Vec::new();
985 let mut errors = Vec::new();
986 let is_usize = matches!(ty.base.ty, BaseType::Usize);
987
988 let mut seen_widths = HashSet::new();
992 while input.peek(syn::Token![#]) {
993 let fork = input.fork();
994 let attrs = fork.call(Attribute::parse_outer)?;
995 if !fork.peek(syn::token::Brace) {
996 break;
997 }
998 input.advance_to(&fork);
999
1000 let attr = &attrs[0];
1001 if attrs.len() > 1 {
1002 return Err(Error::new_spanned(
1003 &attrs[1],
1004 "expected `{` after cfg attribute",
1005 ));
1006 }
1007 let width = parse_target_pointer_width_cfg(attr)?;
1008
1009 if !is_usize {
1010 errors.push(Error::new_spanned(
1011 attr,
1012 "#[cfg] blocks are only permitted in `usize`-based layouts",
1013 ));
1014 }
1015 if seen_widths.contains(width.as_str()) {
1016 errors.push(Error::new_spanned(
1017 attr,
1018 format!(
1019 "duplicate cfg block for target_pointer_width = \"{width}\""
1020 ),
1021 ));
1022 }
1023
1024 let block;
1025 braced!(block in input);
1026 if block.is_empty() {
1027 errors.push(Error::new_spanned(
1028 attr,
1029 "cfg block must contain at least one field",
1030 ));
1031 }
1032 while !block.is_empty() {
1033 let mut field = block.parse::<Bitfield>()?;
1034 field.cfg_pointer_width = Some(width.clone());
1035 fields.push(field);
1036 }
1037 seen_widths.insert(width);
1038 }
1039
1040 while !input.is_empty() {
1042 fields.push(input.parse::<Bitfield>()?);
1043 }
1044
1045 fields.sort_by_key(|field| field.low_bit);
1046
1047 for i in 0..fields.len() {
1048 let curr = &fields[i];
1049
1050 for next in fields.iter().skip(i + 1) {
1054 if curr.high_bit < next.low_bit {
1055 break;
1056 }
1057 let can_overlap = curr.cfg_pointer_width.is_some()
1058 && next.cfg_pointer_width.is_some()
1059 && curr.cfg_pointer_width != next.cfg_pointer_width;
1060 if !can_overlap {
1061 errors.push(Error::new(
1065 next.span,
1066 format!(
1067 "{} ({} {}) overlaps with {} ({} {})",
1068 next.display_name(),
1069 next.display_kind(),
1070 next.display_range(),
1071 curr.display_name(),
1072 curr.display_kind(),
1073 curr.display_range(),
1074 ),
1075 ));
1076 }
1077 }
1078 }
1079
1080 if let Some(highest_possible) = ty.base.ty.high_bit()
1081 && let Some(highest) = fields.last()
1082 && highest.high_bit > highest_possible
1083 {
1084 errors.push(Error::new(
1085 highest.span,
1086 format!(
1087 "high bit {} exceeds the highest possible value \
1088 of {highest_possible}",
1089 highest.high_bit
1090 ),
1091 ));
1092 }
1093
1094 let mut bitfld = Self {
1095 ty,
1096 named: vec![],
1097 reserved: vec![],
1098 errors,
1099 };
1100
1101 while let Some(field) = fields.pop() {
1102 if field.is_reserved() {
1103 if field.default.is_some() {
1104 bitfld.reserved.push(field);
1105 }
1106 } else {
1107 bitfld.named.push(field);
1108 }
1109 }
1110
1111 Ok(bitfld)
1112 }
1113}
1114
1115impl ToTokens for Bitfields {
1116 fn to_tokens(&self, tokens: &mut TokenStream2) {
1117 let type_def = &self.ty.def;
1118 let type_name = &type_def.ident;
1119 let base = &self.ty.base.def;
1120
1121 let (impl_generics, ty_generics, where_clause) =
1122 type_def.generics.split_for_impl();
1123
1124 if !self.errors.is_empty() {
1125 let errors = self.errors.iter().map(Error::to_compile_error);
1126 quote! {
1127 #[derive(Copy, Clone, Eq, PartialEq)]
1128 #type_def
1129 #(#errors)*
1130 }
1131 .to_tokens(tokens);
1132 return;
1133 }
1134
1135 let constants = self.constants();
1136 let getters_and_setters = self.getters_and_setters();
1137 let iter_impl = self.iter_impl();
1138 let fmt_impls = self.fmt_impls();
1139 quote! {
1140 #[derive(Copy, Clone, Eq, PartialEq)]
1141 #type_def
1142
1143 impl #impl_generics #type_name #ty_generics #where_clause {
1144 #constants
1145
1146 pub const fn new() -> Self {
1150 Self(Self::RSVD1_MASK)
1151 }
1152
1153 #(#getters_and_setters)*
1154 }
1155
1156 impl #impl_generics ::core::default::Default for #type_name #ty_generics #where_clause {
1157 fn default() -> Self {
1160 Self(Self::DEFAULT)
1161 }
1162 }
1163
1164 impl #impl_generics ::core::convert::From<#base> for #type_name #ty_generics #where_clause {
1165 #[allow(clippy::bad_bit_mask)]
1168 fn from(value: #base) -> Self {
1169 debug_assert!(
1170 value & Self::RSVD1_MASK == Self::RSVD1_MASK,
1171 "from(): Invalid base value ({value:#x}) has reserved-as-1 bits ({:#x}) unset",
1172 Self::RSVD1_MASK,
1173 );
1174 debug_assert!(
1175 !value & Self::RSVD0_MASK == Self::RSVD0_MASK,
1176 "from(): Invalid base value ({value:#x}) has reserved-as-0 bits ({:#x}) set",
1177 Self::RSVD0_MASK,
1178 );
1179 Self(value)
1180 }
1181 }
1182
1183 impl #impl_generics ::core::ops::Deref for #type_name #ty_generics #where_clause {
1184 type Target = #base;
1185
1186 fn deref(&self) -> &Self::Target {
1187 &self.0
1188 }
1189 }
1190
1191 impl #impl_generics ::core::ops::DerefMut for #type_name #ty_generics #where_clause {
1192 fn deref_mut(&mut self) -> &mut Self::Target {
1193 &mut self.0
1194 }
1195 }
1196
1197 #iter_impl
1198
1199 #fmt_impls
1200 }
1201 .to_tokens(tokens);
1202 }
1203}