-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
Implement RFC#1559: allow all literals in attributes #35850
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @nikomatsakis (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. |
continue | ||
let name = word.name(); | ||
let message = match name { | ||
Some(word) => match &*word { |
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 could probably be if let Some(word) = word.name() {
.
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.
Wait, doesn't .name()
cause an error for repr(5)
currently, that would be silenced?
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'll use if let ...
. The check you're referring to happens here (libsyntax/attr.rs find_repr_attrs()).
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.
Actually, it's slightly cleaner to use match word.name()
, so I'll switch it to that.
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.
Might be able to do match word.name().as_ref().map_or("", |s| s)
(or map_or("", |s| &**s)
) - assuming that it has been previously validated.
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.
Yeah, I considered that, but we don't know if it's a word at this point (though it doesn't matter too much, yet). Plus, it seems a bit more obvious to specifically match on the None case.
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.
Two nested match
are pretty ugly 😞.
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.
Changed to (from IRC):
let name = match word.name() {
Some(word) => word,
None => continue,
};
let message = match &*name {
...
}
span_err!(self.sess, attr.span, E0517, "{}", message);
Looks pretty good to me, great job! 🎉 |
if meta_item.is_word() && id.is_none() { | ||
id = Some(meta_item.name().clone()); | ||
} else { | ||
// FIXME better-encapsulate meta_item (don't directly access `node`) |
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.
node
is still directly accessed in the span_bug! so perhaps the FIXME shouldn't be removed?
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 happens in a lot of places without a similar comment. Is it more important to place such a comment here than in other places?
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 added those fixmes; ultimately, there should be some encapsulation to make meta-items more opaque (so that their internal representation is less obvious and more resilient to changes). If it's done other places, this fixme should be added there, too.
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.
Okay, I'll re-add them.
There should be some |
Aside from my comments and request for tests, this is basically all awesome. 🎉 |
When this is ready to merge, let me know, we can batch up everything in #31645 (comment) |
if let Some(mi) = item.meta_item() { | ||
if mi.check_name(name) { | ||
return Some(mi.clone()) | ||
} |
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.
Needing double if
s here is annoying - could check_name return None for non-meta items? (More generally, I kind of hate the concept of meta-item - it is arbitrary and meaningless. We should do our best not to expose the concept outside of libsyntax).
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.
Actually, we can call check_name directly on the list item. I'll change it to that.
Edit: Actually, we need to get the meta item somehow to return it. How do you feel about:
for item in items.iter().flat_map(|l| l.iter()) {
match item.meta_item() {
Some(mi) if mi.check_name(name) => return Some(mi.clone()),
_ => continue
}
}
This should be feature-gated, right? |
Why should this be feature gated? The syntax is backwards compatible, and custom attributes are nightly only. |
@SergioBenitez So you're saying all stable attributes do checks that prevent new uses of literals? |
@eddyb: That's the intention with this PR, yeah. |
span: span | ||
} | ||
})).collect() | ||
v.into_iter().map(|(_, m)| sort_meta_item(m)).collect() |
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 used to recursively sort MetaItemKind::List
s but now does nothing.
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.
(now that they can contain literals, sorting MetaItemKind::List
s might not even make sense)
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.
Same as above.
☔ The latest upstream changes (presumably #35764) made this pull request unmergeable. Please resolve the merge conflicts. |
Rebased on master. |
r+ with MetaListItem renamed and with the commits squashed. Thanks for the PR, awesome work! |
@nrc: Done. |
@Manishearth r=nrc |
☔ The latest upstream changes (presumably #35979) made this pull request unmergeable. Please resolve the merge conflicts. |
@Manishearth: Rebased. |
@bors r=nrc |
📌 Commit 8250a26 has been approved by |
r? @nrc |
This will land in the next breaking batch. |
@jseyfried Wasn't this supposed to be part of the previous batch? Don't see the harm in landing it now if so. |
@SergioBenitez Which previous batch? Afaik, none of the pending syntax-[breaking-change] PRs have landed yet (c.f. #31645 (comment)). |
Those aren't syntax-[breaking-change]s though. |
Implement RFC#1559: allow all literals in attributes Implemented rust-lang/rfcs#1559, tracked by rust-lang#34981.
Batch up libsyntax breaking changes Batch of the following syntax-[breaking-change] changes: - #35591: Add a field `span: Span` to `ast::Generics`. - #35618: Remove variant `Mod` of `ast::PathListItemKind` and refactor the remaining variant `ast::PathListKind::Ident` to a struct `ast::PathListKind_`. - #35480: Change uses of `Constness` in the AST to `Spanned<Constness>`. - c.f. `MethodSig`, `ItemKind` - #35728: Refactor `cx.pat_enum()` into `cx.pat_tuple_struct()` and `cx.pat_path()`. - #35850: Generalize the elements of lists in attributes from `MetaItem` to a new type `NestedMetaItem` that can represent a `MetaItem` or a literal. - #35917: Remove traits `AttrMetaMethods`, `AttributeMethods`, and `AttrNestedMetaItemMethods`. - Besides removing imports of these traits, this won't cause fallout. - Add a variant `Union` to `ItemKind` to future proof for `union` (c.f. #36016). - Remove inherent methods `attrs` and `fold_attrs` of `Annotatable`. - Use methods `attrs` and `map_attrs` of `HasAttrs` instead. r? @Manishearth
Implemented rust-lang/rfcs#1559, tracked by #34981.