@@ -598,51 +598,83 @@ impl Qualif for IsNotImplicitlyPromotable {
598
598
}
599
599
}
600
600
601
- // Ensure the `IDX` values are sequential (`0..QUALIF_COUNT`).
602
- macro_rules! define_qualif_indices {
601
+ macro_rules! define_qualifs {
602
+ // Top-level, non-recursive mode
603
+
604
+ ( $( $Q: ident ) ,* $( , ) ? ) => {
605
+ /// Executes `body` once for each implementor of `Qualif`.
606
+ ///
607
+ /// This macro overloads closure syntax to put the type of each `Qualif` as well as
608
+ /// a value of that type into scope for `body`. For example, the following code would print
609
+ /// the result of `in_any_value_of_ty` for each `Qualif` (assuming `cx` and `ty` are
610
+ /// already in scope).
611
+ ///
612
+ /// ```
613
+ /// for_each_qualif!(|q: Q| dbg!(Q::in_any_value_of_ty(cx, ty)));
614
+ /// ```
615
+ ///
616
+ /// Note that the type annotation for the closure argument (the `Q` in `q: Q`) is
617
+ /// mandatory and must be a valid identifier (it is used as the name of a type alias within
618
+ /// the macro).
619
+ macro_rules! for_each_qualif {
620
+ ( |$q: ident : $ty: ident| $body: expr ) => {
621
+ {
622
+ $(
623
+ ( |$q| {
624
+ #[ allow( unused) ]
625
+ type $ty = $Q;
626
+ $body
627
+ } ) ( $Q) ;
628
+ ) *
629
+ }
630
+ }
631
+ }
632
+
633
+ // Enter recursive mode to assign a numeric index to each `Qualif`
634
+ define_qualifs!( 0 => $( $Q ) ,* ) ;
635
+ } ;
636
+
637
+ // Recursive mode
638
+
603
639
( $i: expr => $first: ident $( , $rest: ident) * ) => {
604
640
impl QualifIdx for $first {
605
641
const IDX : usize = $i;
606
642
}
607
643
608
- define_qualif_indices !( $i + 1 => $( $rest) ,* ) ;
644
+ define_qualifs !( $i + 1 => $( $rest) ,* ) ;
609
645
} ;
610
646
( $i: expr =>) => {
611
647
const QUALIF_COUNT : usize = $i;
612
648
} ;
613
649
}
614
650
615
- define_qualif_indices ! (
616
- 0 => HasMutInterior , NeedsDrop , IsNotPromotable , IsNotImplicitlyPromotable
651
+ define_qualifs ! (
652
+ HasMutInterior , NeedsDrop , IsNotPromotable , IsNotImplicitlyPromotable
617
653
) ;
618
654
static_assert ! ( QUALIF_COUNT == 4 ) ;
619
655
620
656
impl ConstCx < ' _ , ' tcx > {
621
657
fn qualifs_in_any_value_of_ty ( & self , ty : Ty < ' tcx > ) -> PerQualif < bool > {
622
658
let mut qualifs = PerQualif :: default ( ) ;
623
- qualifs[ HasMutInterior ] = HasMutInterior :: in_any_value_of_ty ( self , ty) . unwrap_or ( false ) ;
624
- qualifs[ NeedsDrop ] = NeedsDrop :: in_any_value_of_ty ( self , ty) . unwrap_or ( false ) ;
625
- qualifs[ IsNotPromotable ] = IsNotPromotable :: in_any_value_of_ty ( self , ty) . unwrap_or ( false ) ;
626
- qualifs[ IsNotImplicitlyPromotable ] =
627
- IsNotImplicitlyPromotable :: in_any_value_of_ty ( self , ty) . unwrap_or ( false ) ;
659
+ for_each_qualif ! ( |q: Q | {
660
+ qualifs[ q] = Q :: in_any_value_of_ty( self , ty) . unwrap_or( false ) ;
661
+ } ) ;
628
662
qualifs
629
663
}
630
664
631
665
fn qualifs_in_local ( & self , local : Local ) -> PerQualif < bool > {
632
666
let mut qualifs = PerQualif :: default ( ) ;
633
- qualifs[ HasMutInterior ] = HasMutInterior :: in_local ( self , local) ;
634
- qualifs[ NeedsDrop ] = NeedsDrop :: in_local ( self , local) ;
635
- qualifs[ IsNotPromotable ] = IsNotPromotable :: in_local ( self , local) ;
636
- qualifs[ IsNotImplicitlyPromotable ] = IsNotImplicitlyPromotable :: in_local ( self , local) ;
667
+ for_each_qualif ! ( |q: Q | {
668
+ qualifs[ q] = Q :: in_local( self , local) ;
669
+ } ) ;
637
670
qualifs
638
671
}
639
672
640
673
fn qualifs_in_value ( & self , source : ValueSource < ' _ , ' tcx > ) -> PerQualif < bool > {
641
674
let mut qualifs = PerQualif :: default ( ) ;
642
- qualifs[ HasMutInterior ] = HasMutInterior :: in_value ( self , source) ;
643
- qualifs[ NeedsDrop ] = NeedsDrop :: in_value ( self , source) ;
644
- qualifs[ IsNotPromotable ] = IsNotPromotable :: in_value ( self , source) ;
645
- qualifs[ IsNotImplicitlyPromotable ] = IsNotImplicitlyPromotable :: in_value ( self , source) ;
675
+ for_each_qualif ! ( |q: Q | {
676
+ qualifs[ q] = Q :: in_value( self , source) ;
677
+ } ) ;
646
678
qualifs
647
679
}
648
680
}
0 commit comments