Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upRFC for attributes on statements and blocks. #16
Conversation
sfackler
reviewed
Mar 20, 2014
| ```rust | ||
| fn name(method: SslMethod) -> &'static str { | ||
| match method { | ||
| Sslv2 => "SSLv2", |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
cmr
reviewed
Mar 20, 2014
|
|
||
| # Unresolved questions | ||
|
|
||
| - Should one be able to annotate the `else` branch(es) of an `if`? e.g. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
pnkfelix
Apr 8, 2014
Member
If we go down this road, I assume there would be a distinction between:
#[attr] if foo { ... } else { ... } // applies to whole statement, including both branchesand
if foo #[attr] { ... } else { ... } // only applies to the then-branchI don't have a problem with this; if you cfg-disable a then-branch, you get a compilation error, presumably. (Though I do think it might motivate support for inner attributes.)
This comment has been minimized.
This comment has been minimized.
cmr
Apr 8, 2014
Member
I think this is an important detail. As I see it, #[attr] if ..., the attribute would apply to the expression, but if foo { #![attr] ... } would have it apply to the block. I do not want to allow if foo #[attr] { ... }, I find it confusing.
This comment has been minimized.
This comment has been minimized.
pnkfelix
Apr 8, 2014
Member
I'm not inclined to disallow if foo #[attr] { ... } though I also would probably find inner-attributes more readable.
(I'd suggest we "just lint for it", but ... Does our lint infrastructure have enough info to try to catch the outer-attribute form here? Or are all the attributes boiled away by the time the lints run?)
This comment has been minimized.
This comment has been minimized.
huonw
Apr 8, 2014
Author
Member
I was thinking that if ... { ... } was a single unit, i.e. the {} are part of the if not a separate block. Maybe having both separately would be OK (I hadn't thought about it at all).
This comment has been minimized.
This comment has been minimized.
lilyball
Apr 8, 2014
Contributor
@huonw I have the same feeling. if expr { ... } feels like a single unit to me. If #[attr] were allowed on just the { ... } then I would expect if expr expr to be valid (e.g. if true println!("this works?");. But it's not valid.
Given that, I also find the suggestion of if expr { ... } else #[attr] if expr { ... } to be invalid. An else-statement is also a syntactical construct where the body is either an if-statement or a braced block. And if you really think this should be valid, then I question what happens if the #[cfg(foo)] evaluates to false? You then have a bare else with no associated code. I think that if you want an attribute on an else-if then you just need to nest, as in if expr { ... } else { #[attr] if expr { ... } }. Usage of this should be rare enough that this nesting is not a problem.
This comment has been minimized.
This comment has been minimized.
lilyball
Apr 8, 2014
Contributor
Oh, and given all that I said above, I think the inner-attribute form doesn't make sense, as it appears as though it should affect the block, not the entire if-statement (especially if it occurs inside of an else-block). Similarly, putting the attribute in between the expression and the block makes no sense.
Disallowing these usages also resolves the question of how to deal with needing to select between several behaviors. if expr #[cfg(one)] { ... } #[cfg(two)] { ... } #[cfg(three)] { ... } looks pretty nonsensical, especially if two of the configs match (or if none match).
Additionally, if we did allow #[attr] on just the block, that would imply that we should allow it on all expressions, not just statements. I can see why that might be desired, but in actual practice it seems like it would be extremely confusing. Restricting it to blocks instead of arbitrary expressions would lessen the confusion, but would reintroduce confusion over why you can't put an attribute on the block of an if-statement (and allowing that brings up the problems I already mentioned).
Overall, I think the simplest thing to do is to just allow it on match arms and on statements. Not on blocks or expressions (unless those happen to be statements as well).
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
andrew-d
commented
Mar 21, 2014
|
|
This comment has been minimized.
This comment has been minimized.
esummers
commented
Mar 22, 2014
|
Looks unnatural to me if extended to if/else. My random thought is that maybe if/else should look more like a match:
|
This comment has been minimized.
This comment has been minimized.
|
I've been thinking about it a little more, and I actually think my second proposed if ... {
...
} else Xwhere |
This comment has been minimized.
This comment has been minimized.
esummers
commented
Mar 22, 2014
|
I think that looks the best too. |
This comment has been minimized.
This comment has been minimized.
andrew-d
commented
Mar 25, 2014
|
So, what's the process to get a consensus on this? Having this merged would be super useful for me right now. |
This comment has been minimized.
This comment has been minimized.
|
@andrew-d, the process is outlined in RFC #1, the relevant part being:
Discussions of RFCs are predominately occurring during weekly meetings right now, but this is not a hard requirement. |
This comment has been minimized.
This comment has been minimized.
|
I'm generally in favor. I'm vaguely concerned about parser ambiguities but it should probably be ok. (Oh, my kingdom for a proper grammar.) |
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis I don't see any ambiguities: attributes and only attributes start with |
This comment has been minimized.
This comment has been minimized.
|
@chris-morgan I generally agree, I've just learned to be cautious when it comes to annotations that precede blocks etc. |
This comment has been minimized.
This comment has been minimized.
flaper87
commented
Mar 26, 2014
|
I'm in favor |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
I don't think its explicitly spelled out in the RFC, so I will ask: Are only outer-attributes allowed to be used in this manner? Or are inner-attributes allowed as well? Supporting inner-attributes could help improve the appearance of e.g. the So, If the intent is that inner-attributes should also be allowed, then we would need to resolve questions of what their scope is (I'm guessing it would be the most tightly enclosing block), and it would probably be good to require all inner-attributes to occur at the start of the block, before any items/declarations/outer-attributes etc). But I would be fine if inner-attributes are not supported, or are not supported in the first iteration of this feature. |
brendanzab
reviewed
Apr 9, 2014
This comment has been minimized.
This comment has been minimized.
|
There was a good amount of discussion in today's meeting about this RFC. The general opinion is that it seems a little odd to limit attributes to just statements. One big reason is that many things which look like statements are actually expressions, such as: fn foo() {
if some_condition() { println!("test") } // this is an expression, not a statement
}There are some concerns about how far-reaching it would be to modify the grammar to allow attributes on all expressions (which is the ideal ending point for something like this). In the meantime, how would you feel about paring down the RFC to just attributes on match arms? That seems have a very real and pressing use case, and it pretty much works as expected because it can appear anywhere a match can appear. |
This comment has been minimized.
This comment has been minimized.
|
Should I cut it down here? Or open a new RFC, since it will be a rather large simplification (maybe this RFC can be co-opted for the more general statements/expressions attributes). |
This comment has been minimized.
This comment has been minimized.
|
I think either way is ok. It sounds like statements/expressions will want to be a separate RFC, so feel free to pick either one to be this one (whichever is easiest) |
This comment has been minimized.
This comment has been minimized.
|
I opened #49 since pretty much none of the discussion here is about match arms. (I'll update this to be statement/expression specific at some point.) |
alexcrichton
added a commit
that referenced
this pull request
May 13, 2014
This comment has been minimized.
This comment has been minimized.
|
Updated. |
huonw
changed the title
RFC for attributes on match arms and statements.
RFC for attributes on statements and blocks.
May 17, 2014
This comment has been minimized.
This comment has been minimized.
anasazi
commented
Jun 3, 2014
|
+1 Attributes on all the things! |
This comment has been minimized.
This comment has been minimized.
|
A possibly better way to implement this generically would be to add an On Tue, Jun 3, 2014 at 2:09 PM, Eric Reed notifications@github.com wrote:
|
This comment has been minimized.
This comment has been minimized.
|
Some notes from discussion during triage meeting:
@nikomatsakis you had some additional thoughts that seemed a little implementation oriented in terms of what it would be like to parse code that has an arbitrary number of attributes followed by some statment-or-expression, feel free to to to clarify my points above. Anyway, @huonw , we invite you to revise the RFC and then we will try to address it formally at a team meeting. |
This comment has been minimized.
This comment has been minimized.
|
This would be really useful, especially with lint plugins. I'm interested in implementing this if the RFC is accepted. |
This comment has been minimized.
This comment has been minimized.
|
As a point of reference, Java 8 significantly expanded the parts of the grammar that can be tagged with annotations: http://java.dzone.com/articles/java-8-type-annotations |
This comment has been minimized.
This comment has been minimized.
|
Updated to include expressions more definitely. There are some annoying interactions with |
glaebhoerl
reviewed
Jun 27, 2014
|
|
||
| This can be addressed by having `#[attr] if cond { ...` be an exterior | ||
| attribute (applying to the whole `if`/`else` chain) and `if cond | ||
| #[attr] { ... ` be an interior attribute (applying to only the current |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Not related to attributes in general, but allowing #[cfg]s everywhere makes it harder to reason about the code, like in C/C++ when you have preprocessor logic all over a function instead of different functions where the platform specific behavior is isolated. That's why I think it might be a bit dangerous to allow this as this might make people move away from separate functions for #[cfg]-dependant behavior. |
huonw
added some commits
Jul 8, 2014
pnkfelix
reviewed
Jul 15, 2014
| general `unsafe` block). | ||
|
|
||
| Only allowing attributes on "statement expressions" that is, | ||
| expressions at the top level of a block, |
This comment has been minimized.
This comment has been minimized.
pnkfelix
Jul 15, 2014
Member
@huonw oops, missed this earlier: I assume you wanted to finish this sentence with a period, or some expository text explaining why narrowing the scope of the change could be good, or more importantly, why it is not good, i.e. reiterating why it is important to support annotating (most) expressions.
brson
referenced this pull request
Jul 15, 2014
Open
Tracking issue for stmt_expr_attributes: Add attributes to expressions, etc. #15701
brson
merged commit 12e924b
into
rust-lang:master
Jul 15, 2014
This comment has been minimized.
This comment has been minimized.
CloudiDust
referenced this pull request
Aug 23, 2014
Closed
Unify and sweeten the syntax for attributes and macros using the `@foo` notation. #208
This comment has been minimized.
This comment has been minimized.
slimsag
commented
Jun 7, 2015
|
shouldn't this be removed from the active RFC list if it's been accepted/merged? |
This comment has been minimized.
This comment has been minimized.
|
The active list contains RFCs that have been accepted but not implemented. |
This comment has been minimized.
This comment has been minimized.
|
I'm currently in the process of implementing this, and in accordance with the current RFC text attributes will be initially prohibited on However, thinking about it I wonder if the following scheme could be used: #[covers_remaining_three] if expr #[covers_block] {
// ...
} else #[covers_remaining_two] if expr #[covers_block] {
// ...
} else #[covers_block] {
// ...
}The idea being that an attribute before an Of course, the "disadvantage" here is that for consistency you'd want to support those block-only attributes on anything taking a block, like the loop expressions. And then there would be more than one location per block-taking expression where a attribute might apply, which while not ambiguous could become potentially confusing. |
This comment has been minimized.
This comment has been minimized.
|
@Kimundi, that is in fact one of the alternatives. I think nailing down this aspect of the behaviour is probably worth an amendment RFC. |
huonw commentedMar 20, 2014
Allow attributes on more places inside functions, such as statements and blocks.