Add derive and doc comment capabilities to newtype_index macro

This commit is contained in:
Paul Daniel Faria 2017-10-29 00:13:49 -04:00
parent 2be4cc0402
commit 4e496de26d
6 changed files with 141 additions and 60 deletions

View file

@ -14,7 +14,7 @@ use dep_graph::DepNode;
use ich::Fingerprint;
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
newtype_index!(SerializedDepNodeIndex);
newtype_index!(SerializedDepNodeIndex { derive[RustcEncodable, RustcDecodable] });
/// Data for use when recompiling the **current crate**.
#[derive(Debug, RustcEncodable, RustcDecodable)]

View file

@ -16,30 +16,19 @@ use serialize::{self, Encoder, Decoder};
use std::fmt;
use std::u32;
#[derive(Clone, Copy, Eq, Ord, PartialOrd, PartialEq, Hash, Debug)]
pub struct CrateNum(u32);
newtype_index!(CrateNum nopub
{
/// Item definitions in the currently-compiled crate would have the CrateNum
/// LOCAL_CRATE in their DefId.
const LOCAL_CRATE = 0,
impl Idx for CrateNum {
fn new(value: usize) -> Self {
assert!(value < (u32::MAX) as usize);
CrateNum(value as u32)
}
/// Virtual crate for builtin macros
// FIXME(jseyfried): this is also used for custom derives until proc-macro crates get `CrateNum`s.
const BUILTIN_MACROS_CRATE = u32::MAX,
fn index(self) -> usize {
self.0 as usize
}
}
/// Item definitions in the currently-compiled crate would have the CrateNum
/// LOCAL_CRATE in their DefId.
pub const LOCAL_CRATE: CrateNum = CrateNum(0);
/// Virtual crate for builtin macros
// FIXME(jseyfried): this is also used for custom derives until proc-macro crates get `CrateNum`s.
pub const BUILTIN_MACROS_CRATE: CrateNum = CrateNum(u32::MAX);
/// A CrateNum value that indicates that something is wrong.
pub const INVALID_CRATE: CrateNum = CrateNum(u32::MAX - 1);
/// A CrateNum value that indicates that something is wrong.
const INVALID_CRATE = u32::MAX - 1,
});
impl CrateNum {
pub fn new(x: usize) -> CrateNum {

View file

@ -158,7 +158,8 @@ pub struct BlockRemainder {
newtype_index!(FirstStatementIndex
{
DEBUG_FORMAT = "{}",
derive[RustcEncodable, RustcDecodable]
DEBUG_NAME = "",
MAX = SCOPE_DATA_REMAINDER_MAX,
});

View file

@ -417,7 +417,8 @@ pub enum BorrowKind {
newtype_index!(Local
{
DEBUG_FORMAT = "_{}",
derive[RustcEncodable, RustcDecodable]
DEBUG_NAME = "_",
const RETURN_POINTER = 0,
});
@ -553,7 +554,11 @@ pub struct UpvarDecl {
///////////////////////////////////////////////////////////////////////////
// BasicBlock
newtype_index!(BasicBlock { DEBUG_FORMAT = "bb{}" });
newtype_index!(BasicBlock
{
derive[RustcEncodable, RustcDecodable]
DEBUG_NAME = "bb"
});
///////////////////////////////////////////////////////////////////////////
// BasicBlockData and Terminator
@ -1135,7 +1140,11 @@ pub type LvalueProjection<'tcx> = Projection<'tcx, Lvalue<'tcx>, Local, Ty<'tcx>
/// and the index is a local.
pub type LvalueElem<'tcx> = ProjectionElem<'tcx, Local, Ty<'tcx>>;
newtype_index!(Field { DEBUG_FORMAT = "field[{}]" });
newtype_index!(Field
{
derive[RustcEncodable, RustcDecodable]
DEBUG_NAME = "field"
});
impl<'tcx> Lvalue<'tcx> {
pub fn field(self, f: Field, ty: Ty<'tcx>) -> Lvalue<'tcx> {
@ -1202,7 +1211,8 @@ impl<'tcx> Debug for Lvalue<'tcx> {
newtype_index!(VisibilityScope
{
DEBUG_FORMAT = "scope[{}]",
derive[RustcEncodable, RustcDecodable]
DEBUG_NAME = "scope",
const ARGUMENT_VISIBILITY_SCOPE = 0,
});
@ -1529,7 +1539,12 @@ pub struct Constant<'tcx> {
pub literal: Literal<'tcx>,
}
newtype_index!(Promoted { DEBUG_FORMAT = "promoted[{}]" });
newtype_index!(Promoted
{
derive[RustcEncodable, RustcDecodable]
DEBUG_NAME = "promoted"
});
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum Literal<'tcx> {

View file

@ -45,33 +45,57 @@ macro_rules! newtype_index {
// Use default constants
($name:ident) => (
newtype_index!(
@type[$name]
@max[::std::u32::MAX]
@debug_format["{}"]);
// Leave out derives marker so we can use its absence to ensure it comes first
@type [$name]
@pub [pub]
@max [::std::u32::MAX]
@debug_name [unsafe {::std::intrinsics::type_name::<$name>() }]);
);
($name:ident nopub) => (
newtype_index!(
// Leave out derives marker so we can use its absence to ensure it comes first
@type [$name]
@pub []
@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_format["{}"]
$($tokens)+);
// Leave out derives marker so we can use its absence to ensure it comes first
@type [$name]
@pub [pub]
@max [::std::u32::MAX]
@debug_name [unsafe {::std::intrinsics::type_name::<$name>() }]
$($tokens)+);
);
// Define any constants
($name:ident nopub { $($tokens:tt)+ }) => (
newtype_index!(
// Leave out derives marker so we can use its absence to ensure it comes first
@type [$name]
@pub []
@max [::std::u32::MAX]
@debug_name [unsafe {::std::intrinsics::type_name::<$name>() }]
$($tokens)+);
);
// ---- private rules ----
// Base case, user-defined constants (if any) have already been defined
(@type[$type:ident] @max[$max:expr] @debug_format[$debug_format:expr]) => (
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord,
RustcEncodable, RustcDecodable)]
pub struct $type(pub u32);
(@derives[$($derives:ident),*] @type[$type:ident] @pub[$($pub:tt)*] @max[$max:expr] @debug_name[$debug_name:expr]) => (
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, $($derives),*)]
pub struct $type($($pub)* u32);
impl Idx for $type {
fn new(value: usize) -> Self {
assert!(value < ($max) as usize);
$type(value as u32)
}
fn index(self) -> usize {
self.0 as usize
}
@ -79,43 +103,95 @@ macro_rules! newtype_index {
impl ::std::fmt::Debug for $type {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(fmt, $debug_format, self.0)
write!(fmt, "{}{}", $debug_name, self.0)
}
}
);
// By not including the @derives marker in this list nor in the default args, we can force it
// to come first if it exists
(@type[$type:ident] @pub[$($pub:tt)*] @max[$max:expr] @debug_name[$debug_name:expr]
derive [$($derives:ident),+] $($tokens:tt)*) => (
newtype_index!(
@derives [$($derives),+]
@type [$type]
@pub [$($pub)*]
@max [$max]
@debug_name [$debug_name]
$($tokens)*);
);
// The case where no derives are added
(@type[$type:ident] @pub[$($pub:tt)*] @max[$max:expr] @debug_name[$debug_name:expr] $($tokens:tt)*) => (
newtype_index!(
@derives []
@type [$type]
@pub [$($pub)*]
@max [$max]
@debug_name [$debug_name]
$($tokens)*);
);
// Rewrite final without comma to one that includes comma
(@type[$type:ident] @max[$max:expr] @debug_format[$debug_format:expr]
(@derives[$($derives:ident),*] @type[$type:ident] @pub[$($pub:tt)*] @max[$max:expr] @debug_name[$debug_name:expr]
$name:ident = $constant:expr) => (
newtype_index!(@type[$type] @max[$max] @debug_format[$debug_format] $name = $constant,);
newtype_index!(
@derives [$($derives),*]
@type [$type]
@pub [$($pub)*]
@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_format[$debug_format:expr]
const $name:ident = $constant:expr) => (
newtype_index!(@type[$type]
@max[$max]
@debug_format[$debug_format]
const $name = $constant,);
(@derives[$($derives:ident),*] @type[$type:ident] @pub[$($pub:tt)*] @max[$_max:expr] @debug_name[$debug_name:expr]
$(#[doc = $doc:expr])* const $name:ident = $constant:expr) => (
newtype_index!(
@derives [$($derives),*]
@type [$type]
@pub [$($pub)*]
@max [$max]
@debug_name [$debug_name]
$(#[doc = $doc])* const $name = $constant,);
);
// Replace existing default for max
(@type[$type:ident] @max[$_max:expr] @debug_format[$debug_format:expr]
(@derives[$($derives:ident),*] @type[$type:ident] @pub[$($pub:tt)*] @max[$_max:expr] @debug_name[$debug_name:expr]
MAX = $max:expr, $($tokens:tt)*) => (
newtype_index!(@type[$type] @max[$max] @debug_format[$debug_format] $($tokens)*);
newtype_index!(
@derives [$($derives),*]
@type [$type]
@pub [$($pub)*]
@max [$max]
@debug_name [$debug_name]
$($tokens)*);
);
// Replace existing default for debug_format
(@type[$type:ident] @max[$max:expr] @debug_format[$_debug_format:expr]
DEBUG_FORMAT = $debug_format:expr, $($tokens:tt)*) => (
newtype_index!(@type[$type] @max[$max] @debug_format[$debug_format] $($tokens)*);
// Replace existing default for debug_name
(@derives[$($derives:ident),*] @type[$type:ident] @pub[$($pub:tt)*] @max[$max:expr] @debug_name[$_debug_name:expr]
DEBUG_NAME = $debug_name:expr, $($tokens:tt)*) => (
newtype_index!(
@derives [$($derives),*]
@type [$type]
@pub [$($pub)*]
@max [$max]
@debug_name [$debug_name]
$($tokens)*);
);
// Assign a user-defined constant (as final param)
(@type[$type:ident] @max[$max:expr] @debug_format[$debug_format:expr]
const $name:ident = $constant:expr, $($tokens:tt)*) => (
// Assign a user-defined constant
(@derives[$($derives:ident),*] @type[$type:ident] @pub[$($pub:tt)*] @max[$max:expr] @debug_name[$debug_name:expr]
$(#[doc = $doc:expr])* const $name:ident = $constant:expr, $($tokens:tt)*) => (
$(#[doc = $doc])*
pub const $name: $type = $type($constant);
newtype_index!(@type[$type] @max[$max] @debug_format[$debug_format] $($tokens)*);
newtype_index!(
@derives [$($derives),*]
@type [$type]
@pub [$($pub)*]
@max [$max]
@debug_name [$debug_name]
$($tokens)*);
);
}

View file

@ -312,7 +312,7 @@ struct CFG<'tcx> {
basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
}
newtype_index!(ScopeId);
newtype_index!(ScopeId { derive[RustcEncodable, RustcDecodable] });
///////////////////////////////////////////////////////////////////////////
/// The `BlockAnd` "monad" packages up the new basic block along with a