-
-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Improve newtype_index macro to handle description and constants consistently #45110
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -402,9 +402,11 @@ pub enum BorrowKind { | |
| /////////////////////////////////////////////////////////////////////////// | ||
| // Variables and temps | ||
|
|
||
| newtype_index!(Local, "_"); | ||
|
|
||
| pub const RETURN_POINTER: Local = Local(0); | ||
| newtype_index!(Local, | ||
| const { | ||
| DESCRIPTION = "_", | ||
|
||
| RETURN_POINTER = 0, | ||
| }); | ||
|
|
||
| /// Classifies locals into categories. See `Mir::local_kind`. | ||
| #[derive(PartialEq, Eq, Debug)] | ||
|
|
@@ -538,7 +540,7 @@ pub struct UpvarDecl { | |
| /////////////////////////////////////////////////////////////////////////// | ||
| // BasicBlock | ||
|
|
||
| newtype_index!(BasicBlock, "bb"); | ||
| newtype_index!(BasicBlock, const { DESCRIPTION = "bb" }); | ||
|
|
||
| /////////////////////////////////////////////////////////////////////////// | ||
| // BasicBlockData and Terminator | ||
|
|
@@ -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, const { DESCRIPTION = "field" }); | ||
|
|
||
| impl<'tcx> Lvalue<'tcx> { | ||
| pub fn field(self, f: Field, ty: Ty<'tcx>) -> Lvalue<'tcx> { | ||
|
|
@@ -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, | ||
| const { | ||
| DESCRIPTION = "scope", | ||
| ARGUMENT_VISIBILITY_SCOPE = 0, | ||
| }); | ||
|
|
||
| #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] | ||
| pub struct VisibilityScopeData { | ||
|
|
@@ -1509,7 +1514,7 @@ pub struct Constant<'tcx> { | |
| pub literal: Literal<'tcx>, | ||
| } | ||
|
|
||
| newtype_index!(Promoted, "promoted"); | ||
| newtype_index!(Promoted, const { DESCRIPTION = "promoted" }); | ||
|
|
||
| #[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] | ||
| pub enum Literal<'tcx> { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,39 +40,86 @@ impl Idx for u32 { | |
|
|
||
| #[macro_export] | ||
| macro_rules! newtype_index { | ||
| ($name:ident) => ( | ||
| newtype_index!($name, unsafe { ::std::intrinsics::type_name::<$name>() }); | ||
| ); | ||
| // ---- private rules ---- | ||
|
|
||
| ($name:ident, $debug_name:expr) => ( | ||
| // Base case, user-defined constants (if any) have already been defined | ||
| (@type[$type:ident] @max[$max:expr] @descr[$descr: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) | ||
| write!(fmt, "{}{}", $descr, self.0) | ||
| } | ||
| } | ||
| ) | ||
| ); | ||
|
|
||
| // Replace existing default for max (as final param) | ||
| (@type[$type:ident] @max[$_max:expr] @descr[$descr:expr] MAX = $max:expr) => ( | ||
| newtype_index!(@type[$type] @max[$max] @descr[$descr]); | ||
| ); | ||
|
|
||
| // Replace existing default for max | ||
| (@type[$type:ident] @max[$_max:expr] @descr[$descr:expr] MAX = $max:expr, $($idents:ident = $constants:expr),*) => ( | ||
| newtype_index!(@type[$type] @max[$max] @descr[$descr]); | ||
| ); | ||
|
|
||
| // Replace existing default for description (as final param) | ||
| (@type[$type:ident] @max[$max:expr] @descr[$_descr:expr] DESCRIPTION = $descr:expr) => ( | ||
| newtype_index!(@type[$type] @max[$max] @descr[$descr]); | ||
| ); | ||
|
|
||
| // Replace existing default for description | ||
| (@type[$type:ident] @max[$max:expr] @descr[$_descr:expr] DESCRIPTION = $descr:expr, $($idents:ident = $constants:expr),*) => ( | ||
| newtype_index!(@type[$type] @max[$max] @descr[$descr] $($idents = $constants),*); | ||
| ); | ||
|
|
||
| // Assign a user-defined constant (as final param) | ||
| (@type[$type:ident] @max[$max:expr] @descr[$descr:expr] $name:ident = $constant:expr) => ( | ||
| pub const $name: $type = $type($constant); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm making all
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see a need for private constants, personally. We can always change it later I guess. |
||
| newtype_index!(@type[$type] @max[$max] @descr[$descr]); | ||
| ); | ||
|
|
||
| // Assign a user-defined constant | ||
| (@type[$type:ident] @max[$max:expr] @descr[$descr:expr] $name:ident = $constant:expr, $($idents:ident = $constants:expr),*) => ( | ||
| pub const $name: $type = $type($constant); | ||
| newtype_index!(@type[$type] @max[$max] @descr[$descr] $($idents = $constants),*); | ||
| ); | ||
|
|
||
| // ---- public rules ---- | ||
|
|
||
| // Use default constants | ||
| ($name:ident) => ( | ||
| newtype_index!( | ||
| @type[$name] | ||
| @max[::std::u32::MAX] | ||
| @descr[unsafe {::std::intrinsics::type_name::<$name>() }]); | ||
| ); | ||
|
|
||
| // Define any constants | ||
| ($name:ident, const { $($idents:ident = $constants:expr,)+ }) => ( | ||
| newtype_index!( | ||
| @type[$name] | ||
| @max[::std::u32::MAX] | ||
| @descr[unsafe {::std::intrinsics::type_name::<$name>() }] | ||
| $($idents = $constants),+); | ||
| ); | ||
|
|
||
| // Rewrite missing trailing comma in const to version with trailing comma | ||
| ($name:ident, const { $($idents:ident = $constants:expr),+ }) => ( | ||
|
||
| newtype_index!($name, const { $($idents = $constants,)+ }); | ||
| ); | ||
| } | ||
|
|
||
| #[derive(Clone, PartialEq, Eq)] | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nikomatsakis this design is based on a conversation I had with @spastorino. So
MAXandDESCRIPTIONare handled as special cases, but all other items in this block are constant. Did I interpret this correctly or was there some other nuance I missed?