macro_rules! impl_tag { ( impl Tag for $Self:ty; $( $($path:ident)::* $( { $( $fields:tt )* })?, )* ) => { ... }; }
Expand description
Implements Tag
for a given type.
You can use impl_tag
on structs and enums.
You need to specify the type and all its possible values,
which can only be paths with optional fields.
§Examples
Basic usage:
#![feature(macro_metavar_expr)]
use rustc_data_structures::{impl_tag, tagged_ptr::Tag};
#[derive(Copy, Clone, PartialEq, Debug)]
enum SomeTag {
A,
B,
X { v: bool },
Y(bool, bool),
}
impl_tag! {
// The type for which the `Tag` will be implemented
impl Tag for SomeTag;
// You need to specify all possible tag values:
SomeTag::A, // 0
SomeTag::B, // 1
// For variants with fields, you need to specify the fields:
SomeTag::X { v: true }, // 2
SomeTag::X { v: false }, // 3
// For tuple variants use named syntax:
SomeTag::Y { 0: true, 1: true }, // 4
SomeTag::Y { 0: false, 1: true }, // 5
SomeTag::Y { 0: true, 1: false }, // 6
SomeTag::Y { 0: false, 1: false }, // 7
}
// Tag values are assigned in order:
assert_eq!(SomeTag::A.into_usize(), 0);
assert_eq!(SomeTag::X { v: false }.into_usize(), 3);
assert_eq!(SomeTag::Y(false, true).into_usize(), 5);
assert_eq!(unsafe { SomeTag::from_usize(1) }, SomeTag::B);
assert_eq!(unsafe { SomeTag::from_usize(2) }, SomeTag::X { v: true });
assert_eq!(unsafe { SomeTag::from_usize(7) }, SomeTag::Y(false, false));
Structs are supported:
#![feature(macro_metavar_expr)]
#[derive(Copy, Clone)]
struct Flags { a: bool, b: bool }
impl_tag! {
impl Tag for Flags;
Flags { a: true, b: true },
Flags { a: false, b: true },
Flags { a: true, b: false },
Flags { a: false, b: false },
}
Not specifying all values results in a compile error:
ⓘ
#![feature(macro_metavar_expr)]
#[derive(Copy, Clone)]
enum E {
A,
B,
}
impl_tag! {
impl Tag for E;
E::A,
}