Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve newtype_index macro to handle description and constants consistently #45110

Merged
merged 3 commits into from
Oct 13, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,9 +402,11 @@ pub enum BorrowKind {
///////////////////////////////////////////////////////////////////////////
// Variables and temps

newtype_index!(Local, "_");

pub const RETURN_POINTER: Local = Local(0);
newtype_index!(Local
{
DEBUG_NAME = "_",
const RETURN_POINTER = 0,
});

/// Classifies locals into categories. See `Mir::local_kind`.
#[derive(PartialEq, Eq, Debug)]
Expand Down Expand Up @@ -538,7 +540,7 @@ pub struct UpvarDecl {
///////////////////////////////////////////////////////////////////////////
// BasicBlock

newtype_index!(BasicBlock, "bb");
newtype_index!(BasicBlock { DEBUG_NAME = "bb" });

///////////////////////////////////////////////////////////////////////////
// BasicBlockData and Terminator
Expand Down Expand Up @@ -1118,7 +1120,7 @@ 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, "field");
newtype_index!(Field { DEBUG_NAME = "field" });

impl<'tcx> Lvalue<'tcx> {
pub fn field(self, f: Field, ty: Ty<'tcx>) -> Lvalue<'tcx> {
Expand Down Expand Up @@ -1183,8 +1185,11 @@ impl<'tcx> Debug for Lvalue<'tcx> {
///////////////////////////////////////////////////////////////////////////
// Scopes

newtype_index!(VisibilityScope, "scope");
pub const ARGUMENT_VISIBILITY_SCOPE : VisibilityScope = VisibilityScope(0);
newtype_index!(VisibilityScope
{
DEBUG_NAME = "scope",
const ARGUMENT_VISIBILITY_SCOPE = 0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very cool =)

});

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct VisibilityScopeData {
Expand Down Expand Up @@ -1509,7 +1514,7 @@ pub struct Constant<'tcx> {
pub literal: Literal<'tcx>,
}

newtype_index!(Promoted, "promoted");
newtype_index!(Promoted { DEBUG_NAME = "promoted" });

#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum Literal<'tcx> {
Expand Down
75 changes: 58 additions & 17 deletions src/librustc_data_structures/indexed_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down