summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-11-04 10:24:20 +0000
committerbors <bors@rust-lang.org>2017-11-04 10:24:20 +0000
commita6885cb853390fc79a8ff0b223ea1471e261d60e (patch)
tree732a966af0d57b74a079ae60311e7f81d02cea2a
parent9acc3331e187d329d29a70c788c44e25a79edf45 (diff)
parent97692afda9e493db65c833b931a6971fb58352b2 (diff)
downloadrust-a6885cb853390fc79a8ff0b223ea1471e261d60e.tar.gz
Auto merge of #45605 - Nashenas88:derive-newtype, r=nikomatsakis
Add derive and doc comment capabilities to newtype_index macro This moves `RustcDecodable` and `RustcEncodable` out of the macro definition and into the macro uses. They were conflicting with `CrateNum`'s impls of `serialize::UseSpecializedEncodable` and `serialize::UseSpecializedDecodable`, and now it's not :). `CrateNum` is now defined with the `newtype_index` macro. I also added support for doc comments on constant definitions and allowed a type to remove the pub specification on the tuple param (otherwise a LOT of code would refuse to compile for `CrateNum`). I was getting dozens of errors like this if `CrateNum` was defined as `pub struct CrateNum(pub u32)`: ``` error[E0530]: match bindings cannot shadow tuple structs --> src/librustc/dep_graph/dep_node.rs:624:25 | 63 | use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX}; | -------- a tuple struct `CrateNum` is imported here ... 624 | [] MissingLangItems(CrateNum), | ^^^^^^^^ cannot be named the same as a tuple struct ``` I also cleaned up the formatting of the macro bodies as they were getting impossibly long. Should I go back and fix the matching rules to this style too? I also want to see what the test results look like because `CrateNum` used to just derive `Debug`, but the `newtype_index` macro has a custom implementation. This might require further pushes. Feel free to bikeshed on the macro language, I have no preference here.
-rw-r--r--src/librustc/hir/def_id.rs41
-rw-r--r--src/librustc/middle/region.rs4
-rw-r--r--src/librustc/mir/mod.rs1
-rw-r--r--src/librustc_data_structures/indexed_vec.rs265
4 files changed, 255 insertions, 56 deletions
diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs
index 69d23504cda..cc30fdfaca6 100644
--- a/src/librustc/hir/def_id.rs
+++ b/src/librustc/hir/def_id.rs
@@ -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 {
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index e725592ff99..89707839144 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -158,8 +158,8 @@ pub struct BlockRemainder {
newtype_index!(FirstStatementIndex
{
- DEBUG_FORMAT = "{}",
- MAX = SCOPE_DATA_REMAINDER_MAX,
+ pub idx
+ MAX = SCOPE_DATA_REMAINDER_MAX
});
impl From<ScopeData> for Scope {
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 8f86d1b9d78..2fc27de137f 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1552,6 +1552,7 @@ pub struct Constant<'tcx> {
newtype_index!(Promoted { DEBUG_FORMAT = "promoted[{}]" });
+
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum Literal<'tcx> {
Value {
diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs
index 0660cd96a4a..dc169c67a76 100644
--- a/src/librustc_data_structures/indexed_vec.rs
+++ b/src/librustc_data_structures/indexed_vec.rs
@@ -45,38 +45,62 @@ 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)
@@ -84,38 +108,219 @@ macro_rules! newtype_index {
}
);
+ // 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)*);
);
}