Skip to content

Add derive and doc comment capabilities to newtype_index macro #45605

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

Merged
merged 4 commits into from
Nov 4, 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
41 changes: 17 additions & 24 deletions src/librustc/hir/def_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,23 @@ use serialize::{self, Encoder, Decoder};
use std::fmt;
use std::u32;

#[derive(Clone, Copy, Eq, Ord, PartialOrd, PartialEq, Hash, Debug)]
pub struct CrateNum(u32);

impl Idx for CrateNum {
fn new(value: usize) -> Self {
assert!(value < (u32::MAX) as usize);
CrateNum(value as u32)
}

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);
newtype_index!(CrateNum
{
derive[Debug]
ENCODABLE = custom

/// Item definitions in the currently-compiled crate would have the CrateNum
/// LOCAL_CRATE in their DefId.
const LOCAL_CRATE = 0,

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

/// A CrateNum value that indicates that something is wrong.
const INVALID_CRATE = u32::MAX - 1,
});

impl CrateNum {
pub fn new(x: usize) -> CrateNum {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ pub struct BlockRemainder {

newtype_index!(FirstStatementIndex
{
DEBUG_FORMAT = "{}",
MAX = SCOPE_DATA_REMAINDER_MAX,
pub idx
Copy link
Contributor

Choose a reason for hiding this comment

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

private by default FTW =)

MAX = SCOPE_DATA_REMAINDER_MAX
});

impl From<ScopeData> for Scope {
Expand Down
1 change: 1 addition & 0 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1531,6 +1531,7 @@ pub struct Constant<'tcx> {

newtype_index!(Promoted { DEBUG_FORMAT = "promoted[{}]" });


#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum Literal<'tcx> {
Value {
Expand Down
265 changes: 235 additions & 30 deletions src/librustc_data_structures/indexed_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,77 +45,282 @@ 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]
@max [::std::u32::MAX]
@debug_format ["{}"]);
);

// 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]
@max [::std::u32::MAX]
@debug_format ["{}"]
$($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,)*]
@pub [$($pub:tt)*]
@type [$type:ident]
@max [$max:expr]
@debug_format [$debug_format: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
}
}

newtype_index!(
@handle_debug
@derives [$($derives,)*]
@type [$type]
@debug_format [$debug_format]);
);

// base case for handle_debug where format is custom. No Debug implementation is emitted.
(@handle_debug
@derives [$($_derives:ident,)*]
@type [$type:ident]
@debug_format [custom]) => ();

// base case for handle_debug, no debug overrides found, so use default
(@handle_debug
@derives []
@type [$type:ident]
@debug_format [$debug_format:expr]) => (
impl ::std::fmt::Debug for $type {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(fmt, $debug_format, self.0)
}
}
);

// Debug is requested for derive, don't generate any Debug implementation.
(@handle_debug
@derives [Debug, $($derives:ident,)*]
@type [$type:ident]
@debug_format [$debug_format:expr]) => ();

// It's not Debug, so just pop it off the front of the derives stack and check the rest.
(@handle_debug
@derives [$_derive:ident, $($derives:ident,)*]
@type [$type:ident]
@debug_format [$debug_format:expr]) => (
newtype_index!(
@handle_debug
@derives [$($derives,)*]
@type [$type]
@debug_format [$debug_format]);
);

// Handle the case where someone wants to make the internal field public
(@type [$type:ident]
@max [$max:expr]
@debug_format [$debug_format:expr]
pub idx
$($tokens:tt)*) => (
newtype_index!(
@pub [pub]
@type [$type]
@max [$max]
@debug_format [$debug_format]
$($tokens)*);
);

// The default case is that the internal field is private
(@type [$type:ident]
@max [$max:expr]
@debug_format [$debug_format:expr]
$($tokens:tt)*) => (
newtype_index!(
@pub []
@type [$type]
@max [$max]
@debug_format [$debug_format]
$($tokens)*);
);

// Append comma to end of derives list if it's missing
(@pub [$($pub:tt)*]
@type [$type:ident]
@max [$max:expr]
@debug_format [$debug_format:expr]
derive [$($derives:ident),*]
$($tokens:tt)*) => (
newtype_index!(
@pub [$($pub)*]
@type [$type]
@max [$max]
@debug_format [$debug_format]
derive [$($derives,)*]
$($tokens)*);
);

// By not including the @derives marker in this list nor in the default args, we can force it
// to come first if it exists. When encodable is custom, just use the derives list as-is.
(@pub [$($pub:tt)*]
@type [$type:ident]
@max [$max:expr]
@debug_format [$debug_format:expr]
derive [$($derives:ident,)+]
ENCODABLE = custom
$($tokens:tt)*) => (
newtype_index!(
@derives [$($derives,)+]
@pub [$($pub)*]
@type [$type]
@max [$max]
@debug_format [$debug_format]
$($tokens)*);
);

// By not including the @derives marker in this list nor in the default args, we can force it
// to come first if it exists. When encodable isn't custom, add serialization traits by default.
(@pub [$($pub:tt)*]
@type [$type:ident]
@max [$max:expr]
@debug_format [$debug_format:expr]
derive [$($derives:ident,)+]
$($tokens:tt)*) => (
newtype_index!(
@derives [$($derives,)+ RustcDecodable, RustcEncodable,]
@pub [$($pub)*]
@type [$type]
@max [$max]
@debug_format [$debug_format]
$($tokens)*);
);

// The case where no derives are added, but encodable is overriden. Don't
// derive serialization traits
(@pub [$($pub:tt)*]
@type [$type:ident]
@max [$max:expr]
@debug_format [$debug_format:expr]
ENCODABLE = custom
$($tokens:tt)*) => (
newtype_index!(
@derives []
@pub [$($pub)*]
@type [$type]
@max [$max]
@debug_format [$debug_format]
$($tokens)*);
);

// The case where no derives are added, add serialization derives by default
(@pub [$($pub:tt)*]
@type [$type:ident]
@max [$max:expr]
@debug_format [$debug_format:expr]
$($tokens:tt)*) => (
newtype_index!(
@derives [RustcDecodable, RustcEncodable,]
@pub [$($pub)*]
@type [$type]
@max [$max]
@debug_format [$debug_format]
$($tokens)*);
);

// Rewrite final without comma to one that includes comma
(@type[$type:ident] @max[$max:expr] @debug_format[$debug_format:expr]
$name:ident = $constant:expr) => (
newtype_index!(@type[$type] @max[$max] @debug_format[$debug_format] $name = $constant,);
(@derives [$($derives:ident,)*]
@pub [$($pub:tt)*]
@type [$type:ident]
@max [$max:expr]
@debug_format [$debug_format:expr]
$name:ident = $constant:expr) => (
newtype_index!(
@derives [$($derives,)*]
@pub [$($pub)*]
@type [$type]
@max [$max]
@debug_format [$debug_format]
$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,)*]
@pub [$($pub:tt)*]
@type [$type:ident]
@max [$_max:expr]
@debug_format [$debug_format:expr]
$(#[doc = $doc:expr])*
const $name:ident = $constant:expr) => (
newtype_index!(
@derives [$($derives,)*]
@pub [$($pub)*]
@type [$type]
@max [$max]
@debug_format [$debug_format]
$(#[doc = $doc])* const $name = $constant,);
);

// Replace existing default for max
(@type[$type:ident] @max[$_max:expr] @debug_format[$debug_format:expr]
MAX = $max:expr, $($tokens:tt)*) => (
newtype_index!(@type[$type] @max[$max] @debug_format[$debug_format] $($tokens)*);
(@derives [$($derives:ident,)*]
@pub [$($pub:tt)*]
@type [$type:ident]
@max [$_max:expr]
@debug_format [$debug_format:expr]
MAX = $max:expr,
$($tokens:tt)*) => (
newtype_index!(
@derives [$($derives,)*]
@pub [$($pub)*]
@type [$type]
@max [$max]
@debug_format [$debug_format]
$($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)*);
(@derives [$($derives:ident,)*]
@pub [$($pub:tt)*]
@type [$type:ident]
@max [$max:expr]
@debug_format [$_debug_format:expr]
DEBUG_FORMAT = $debug_format:expr,
$($tokens:tt)*) => (
newtype_index!(
@derives [$($derives,)*]
@pub [$($pub)*]
@type [$type]
@max [$max]
@debug_format [$debug_format]
$($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,)*]
@pub [$($pub:tt)*]
@type [$type:ident]
@max [$max:expr]
@debug_format [$debug_format: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,)*]
@pub [$($pub)*]
@type [$type]
@max [$max]
@debug_format [$debug_format]
$($tokens)*);
);
}

Expand Down