Skip to content

Commit 72e3f72

Browse files
Define for_each_qualif macro
1 parent 4160021 commit 72e3f72

File tree

1 file changed

+50
-18
lines changed

1 file changed

+50
-18
lines changed

src/librustc_mir/transform/qualify_consts.rs

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -598,51 +598,83 @@ impl Qualif for IsNotImplicitlyPromotable {
598598
}
599599
}
600600

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+
603639
($i:expr => $first:ident $(, $rest:ident)*) => {
604640
impl QualifIdx for $first {
605641
const IDX: usize = $i;
606642
}
607643

608-
define_qualif_indices!($i + 1 => $($rest),*);
644+
define_qualifs!($i + 1 => $($rest),*);
609645
};
610646
($i:expr =>) => {
611647
const QUALIF_COUNT: usize = $i;
612648
};
613649
}
614650

615-
define_qualif_indices!(
616-
0 => HasMutInterior, NeedsDrop, IsNotPromotable, IsNotImplicitlyPromotable
651+
define_qualifs!(
652+
HasMutInterior, NeedsDrop, IsNotPromotable, IsNotImplicitlyPromotable
617653
);
618654
static_assert!(QUALIF_COUNT == 4);
619655

620656
impl ConstCx<'_, 'tcx> {
621657
fn qualifs_in_any_value_of_ty(&self, ty: Ty<'tcx>) -> PerQualif<bool> {
622658
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+
});
628662
qualifs
629663
}
630664

631665
fn qualifs_in_local(&self, local: Local) -> PerQualif<bool> {
632666
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+
});
637670
qualifs
638671
}
639672

640673
fn qualifs_in_value(&self, source: ValueSource<'_, 'tcx>) -> PerQualif<bool> {
641674
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+
});
646678
qualifs
647679
}
648680
}

0 commit comments

Comments
 (0)