about summary refs log tree commit diff
path: root/src/librustc_data_structures
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustc_data_structures')
-rw-r--r--src/librustc_data_structures/indexed_vec.rs75
1 files changed, 58 insertions, 17 deletions
diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs
index 4b7f55eba06..6c5a37aa1e5 100644
--- a/src/librustc_data_structures/indexed_vec.rs
+++ b/src/librustc_data_structures/indexed_vec.rs
@@ -40,39 +40,80 @@ impl Idx for u32 {
 
 #[macro_export]
 macro_rules! newtype_index {
+    // ---- public rules ----
+
+    // Use default constants
     ($name:ident) => (
-        newtype_index!($name, unsafe { ::std::intrinsics::type_name::<$name>() });
+        newtype_index!(
+            @type[$name]
+            @max[::std::u32::MAX]
+            @debug_name[unsafe {::std::intrinsics::type_name::<$name>() }]);
+    );
+
+    // Define any constants
+    ($name:ident { $($tokens:tt)+ }) => (
+        newtype_index!(
+            @type[$name]
+            @max[::std::u32::MAX]
+            @debug_name[unsafe {::std::intrinsics::type_name::<$name>() }]
+            $($tokens)+);
     );
 
-    ($name:ident, $debug_name:expr) => (
+    // ---- private rules ----
+
+    // Base case, user-defined constants (if any) have already been defined
+    (@type[$type:ident] @max[$max:expr] @debug_name[$debug_name:expr]) => (
         #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord,
-         RustcEncodable, RustcDecodable)]
-        pub struct $name(u32);
-
-        impl $name {
-            // HACK use for constants
-            #[allow(unused)]
-            const fn const_new(x: u32) -> Self {
-                $name(x)
-            }
-        }
+            RustcEncodable, RustcDecodable)]
+        pub struct $type(u32);
 
-        impl Idx for $name {
+        impl Idx for $type {
             fn new(value: usize) -> Self {
-                assert!(value < (::std::u32::MAX) as usize);
-                $name(value as u32)
+                assert!(value < ($max) as usize);
+                $type(value as u32)
             }
             fn index(self) -> usize {
                 self.0 as usize
             }
         }
 
-        impl ::std::fmt::Debug for $name {
+        impl ::std::fmt::Debug for $type {
             fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                 write!(fmt, "{}{}", $debug_name, self.0)
             }
         }
-    )
+    );
+
+    // Rewrite final without comma to one that includes comma
+    (@type[$type:ident] @max[$max:expr] @debug_name[$debug_name:expr]
+            $name:ident = $constant:expr) => (
+        newtype_index!(@type[$type] @max[$max] @debug_name[$debug_name] $name = $constant,);
+    );
+
+    // Rewrite final const without comma to one that includes comma
+    (@type[$type:ident] @max[$_max:expr] @debug_name[$debug_name:expr]
+            const $name:ident = $constant:expr) => (
+        newtype_index!(@type[$type] @max[$max] @debug_name[$debug_name] const $name = $constant,);
+    );
+
+    // Replace existing default for max
+    (@type[$type:ident] @max[$_max:expr] @debug_name[$debug_name:expr]
+            MAX = $max:expr, $($tokens:tt)*) => (
+        newtype_index!(@type[$type] @max[$max] @debug_name[$debug_name] $(tokens)*);
+    );
+
+    // Replace existing default for debug_name
+    (@type[$type:ident] @max[$max:expr] @debug_name[$_debug_name:expr]
+            DEBUG_NAME = $debug_name:expr, $($tokens:tt)*) => (
+        newtype_index!(@type[$type] @max[$max] @debug_name[$debug_name] $($tokens)*);
+    );
+
+    // Assign a user-defined constant (as final param)
+    (@type[$type:ident] @max[$max:expr] @debug_name[$debug_name:expr]
+            const $name:ident = $constant:expr, $($tokens:tt)*) => (
+        pub const $name: $type = $type($constant);
+        newtype_index!(@type[$type] @max[$max] @debug_name[$debug_name] $($tokens)*);
+    );
 }
 
 #[derive(Clone, PartialEq, Eq)]