# Macro rustc_data_structures::impl_tag

source ·

    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,
    }