Skip to content

Commit 45a01bd

Browse files
committed
Change attribute syntax to @foo
1 parent 436e810 commit 45a01bd

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

text/0000-attribute-syntax.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
- Start Date: 2014-11-25
2+
- RFC PR:
3+
- Rust Issue:
4+
5+
# Summary
6+
7+
Change attribute syntax from `#[foo]` and `#![foo]` to `@foo` and `@!foo`.
8+
9+
# Motivation
10+
11+
Other languages like Java and Python use `@` for their equivalents of
12+
attributes. In addition, `@foo` is easier to type than `#[foo]`, and is
13+
arguably less noisy looking.
14+
15+
This change was proposed as part of [RFC
16+
386](https://github.com/rust-lang/rfcs/pull/386/files) and was generally
17+
well-received.
18+
19+
# Detailed design
20+
21+
Attributes and inner attributes would be written in one of the following forms
22+
(BNF):
23+
24+
```
25+
ATTR = '@' [!] META
26+
META = ID
27+
| ID '(' META_SEQ ')'
28+
META_SEQ = META_ITEM {',' META_ITEM}
29+
META_ITEM = META
30+
| ID '=' STRING_LITERAL
31+
```
32+
33+
Here are some examples of legal syntax:
34+
35+
* `@inline`
36+
* `@!inline`
37+
* `@deprecated(reason = "foo")`
38+
* `@deriving(Eq)`
39+
40+
Note that some attributes which are legal today have no equivalent:
41+
42+
* `#[deprecated = "foo"]` becomes `@deprecated(reason = "foo")`
43+
44+
## Implementation
45+
46+
The parser will be adjusted to accept `@`-attributes in addition to current
47+
attributes. The internal data structures will remain the same. Once a snapshot
48+
lands, the Rust codebase can be converted, and parsing support for
49+
`#`-attributes can be removed with an error message added explaining how to fix
50+
code.
51+
52+
# Drawbacks
53+
54+
It's a large change that will cause a ton of churn very close to 1.0. Since the
55+
only compiler changes required will be to the parser and pretty printer, it's
56+
relatively low risk (compared to resolve or typeck changes for example).
57+
58+
# Alternatives
59+
60+
We can punt on this until after 1.0. `@`-attributes and `#`-attributes will
61+
have to coexist to avoid breaking backwards compatibility, but that won't be
62+
all that hard to deal with.
63+
64+
We can leave the syntax as is, which is also not that bad.
65+
66+
Support for `#[deprecated = "reason"]` style attributes is removed because
67+
`@deprecated = "reason"` is a bit visually confusing since there are no
68+
delimiters wrapping the attribute. There are a couple of alternatives here.
69+
One is to just allow that syntax. It's not grammatically ambiguous, after all.
70+
71+
Another is to change `foo = "bar'` to `foo("bar")`:
72+
```
73+
ATTR = '@' [!] META
74+
META = ID
75+
| ID '(' STRING_LITERAL ')
76+
| ID '(' META_SEQ ')'
77+
META_SEQ = META {',' META}
78+
```
79+
80+
For example:
81+
* `@deprecated("foo")`
82+
* `@cfg(all(target_os("linux"), feature("my_cargo_feature")))`
83+
84+
This allows for a more convenient syntax for deprecation, but does add even
85+
more parentheses to attribute invocations like the `cfg` example above.
86+
87+
# Unresolved questions
88+
89+
Should there be a "deprecation period" where the `#` syntax is accepted with a
90+
warning?

0 commit comments

Comments
 (0)