-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @eddyb (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
|
||
// 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); |
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.
I'm making all const
s pub
here, this is how all instances were used. Does anyone think this should be configurable? Maybe something like
newtype_index!(NewType,
const {
pub RETURN_LOCATION = 0, // this one is public
PRIVATE_LOCATION = 1, // this one is private
});
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.
I don't see a need for private constants, personally. We can always change it later I guess.
src/librustc/mir/mod.rs
Outdated
|
||
pub const RETURN_POINTER: Local = Local(0); | ||
newtype_index!(Local, | ||
const { |
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 MAX
and DESCRIPTION
are 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?
I'd rename |
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.
This is great. =) I left a few nits, but I like this overall direction.
src/librustc/mir/mod.rs
Outdated
pub const RETURN_POINTER: Local = Local(0); | ||
newtype_index!(Local, | ||
const { | ||
DESCRIPTION = "_", |
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.
Nit: I don't think I would include DESCRIPTION
in the list of constants, since it's not a constant.. But I sort of like having one big list. Maybe we should just remove the const
keyword and instead write something like:
newtype_index!(Local {
DESCRIPTION = "_",
RETURN_POINTER = 0,
});
Alternatively, put the const
keyword on the actual constants:
newtype_index!(Local {
DESCRIPTION = "_",
const RETURN_POINTER = 0,
});
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.
And we could even lowercase the non constants ...
newtype_index!(Local {
debug_name = "_",
const RETURN_POINTER = 0,
});
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.
If we go with something like
newtype_index!(Local {
DESCRIPTION = "_",
const RETURN_POINTER = 0,
});
Can we add the restriction that MAX
and DEBUG_NAME
come first? Coming up with a macro that supports an optional, initial keyword for each definition in the list is going to be much more challenging. It may not be worth the extra effort. I can document that limitation at the macro definition.
@spastorino I would still keep them all caps since their values don't change. I think the const
keyword will signify that it's an externally accessible definition.
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.
For clarification, the challenge comes in defining the macro expression to parse the entire list. Something like
{ $($(const)* $idents:ident = $constants:expr),+ }
Fails with local ambiguity: multiple parsing options: built-in NTs ident ('idents') or 1 other option.
.
I can change it to $($definitions:tt),* but then I'll need to account for macro variable type casting (things like @as_expr $e:expr
and @as_ident $i:ident
) to convert the generic tokens into something more parselable. I'm not sure how long that will take to figure out vs just distinguishing between non-consts first followed by consts.
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.
Can we add the restriction that MAX and DEBUG_NAME come first?
Definitely. This is an internal macro, so it doesn't have to be particularly flexible. I'd say make it so that MAX / DEBUG_NAME must come first and in a particular order.
(Incidentally, usually when I have to struct macros like this, I have a kind of "consume loop" where it peels off tokens from the front and then recursively calls itself on the remaining tokens. But I guess that's what you were trying to avoid.)
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.
Somehow I missed this comment and in the meantime implemented a version that does work and is less lines. It doesn't enforce MAX and DEBUG_NAME coming first, though. Should I still add that restriction in?
|
||
// 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); |
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.
I don't see a need for private constants, personally. We can always change it later I guess.
); | ||
|
||
// Rewrite missing trailing comma in const to version with trailing comma | ||
($name:ident, const { $($idents:ident = $constants:expr),+ }) => ( |
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.
Nit: I would prefer to start with the PUBLIC rules. I always find it easier to read top-down -- that is, start from the public starting point, then gradually come to the details.
@bors r+ |
📌 Commit 97fe353 has been approved by |
@bors rollup |
newtype_index!(VisibilityScope | ||
{ | ||
DEBUG_NAME = "scope", | ||
const ARGUMENT_VISIBILITY_SCOPE = 0, |
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.
very cool =)
Improve newtype_index macro to handle description and constants consistently
No description provided.