From 33aed5ea3ab6edc12d2ad0e62c4d44b543fe4315 Mon Sep 17 00:00:00 2001 From: bstrie <865233+bstrie@users.noreply.github.com> Date: Thu, 1 Apr 2021 16:39:16 -0400 Subject: [PATCH 1/8] RFC: reserved prefixes --- text/0000-reserved_prefixes.md | 137 +++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 text/0000-reserved_prefixes.md diff --git a/text/0000-reserved_prefixes.md b/text/0000-reserved_prefixes.md new file mode 100644 index 00000000000..7eb7006561b --- /dev/null +++ b/text/0000-reserved_prefixes.md @@ -0,0 +1,137 @@ +- Feature Name: reserved_prefixes +- Start Date: 2021-03-31 +- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) +- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) + +# Summary +[summary]: #summary + +Beginning with the 2021 edition, in all contexts, reserve the syntax `ident#foo` and `ident"foo"`, as a way of future-proofing against future language changes. + +# Motivation +[motivation]: #motivation + +In [RFC 2151](https://rust-lang.github.io/rfcs/2151-raw-identifiers.html), the language syntax was expanded to allow identifiers to optionally be prefixed with `r#`, to ease migrating code when new keywords are introduced. Conversely, [RFC 3098](https://github.com/rust-lang/rfcs/pull/3098) (still under discussion as of this writing) is proposing to allow keywords to be prefixed with `k#`, as an unobtrusive way to introduce new keywords without requiring any migration effort or edition-level coordination. + +In almost all circumstances these are frictionless additions; there is no place in the basic Rust grammar that would conflict with productions of the form `foo#bar`. However, there is a wrinkle with regard to macros. Consider the following code: +```rust +macro_rules! demo { + ( $a:tt ) => { println!("one token") }; + ( $a:tt $b:tt $c:tt ) => { println!("three tokens") }; +} + +demo!(a#foo); +demo!(r#foo); +demo!(k#foo); +``` + +Prior to Rust 1.30 and the stabilization of raw identifiers (RFC 2151), the above code would have produced the following compiler error: +``` +error: found invalid character; only `#` is allowed in raw string delimitation: f + --> tokens.rs:8:7 + | +8 | demo!(r#foo); + | ^^ +``` + +The `r#` prefix for raw identifiers was chosen because it exploited a quirk of the parser, which prevented any code containing `r#foo` from compiling due to the parser believing that it was processing a raw string literal. + +After Rust 1.30 , it prints the following: +``` +three tokens +one token +three tokens +``` + +If RFC 3098 were accepted, it would print the following: +``` +three tokens +one token +one token +``` + +This would be a breaking change, which is why RFC 3098 is currently aiming to be implemented across an edition. However, the time-sensitivity of that RFC could be obviated if the language merely guaranteed that such space was syntactically available. Therefore, this RFC proposes merely reserving such syntactic space, without attaching any semantic meaning to it, to accommodate both the "raw keywords" proposal and any other future changes that would benefit. + +As further motivation, the notion of reserving "syntactic space" as an aid to backwards-compatibility is an idea that has precedence from other languages. [C reserves large swathes of the identifier space](https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html) for its own use, most notably identifiers that begin with `_` or `__`. Likewise, Python reserves all identifiers of the form `__foo__` for special use by the language. + +In contrast to Python or C, reserving syntax via `#` rather than `_` is much less of an imposition on ordinary users, because `#` is not a valid character in identifiers. The only contexts in which this change would be observable is within macros: `foo#bar` would now lex as one token rather than three. As such, the above code would produce the following when compiled on the 2021 edition: +``` +one token +one token +one token +``` + +Note that this syntactic reservation is whitespace-sensitive: any whitespace to either side of the intervening `#` will cause three tokens to be produced rather than one. This provides a simple migration path for anyone who would be impacted by this change; they would need only change their macro invocations from `foo!(bar#qux)` to any of `foo!(bar # qux)`, `foo!(bar# qux)`, or `foo!(bar #qux)`. + +This RFC goes beyond merely reserving the prefix `k#` and reserves all identifiers directly preceding the `#`. This has the following benefits: + +1. It increases the amount of leeway for future language changes that might wish to use this space (e.g. a hypothetical mechanism for edition-specific keywords might be written as `edition2015#use`). +2. It has symmetry with the existing notion of [literal suffixes](https://doc.rust-lang.org/reference/tokens.html#suffixes). +3. It avoids complicating the grammar and parser with bespoke concepts. + +Finally, this RFC also proposes that this same syntactic reservation be applied to string literals (including raw string literals), whose syntax was the original inspiration for this design space. Once again, this reservation would be mostly unobservable by end-users and would only manifest in code using macros like so: + +```rust +macro_rules! demo { + ( $a:tt ) => { println!("one token") }; + ( $a:tt $b:tt ) => { println!("two tokens") }; + ( $a:tt $b:tt $c:tt $d:tt ) => { println!("four tokens") }; +} + +demo!(br"foo"); +demo!(bar"foo"); +demo!(bar#"foo"#); +``` + +Prior to the 2021 edition, this produces: +``` +one token +two tokens +four tokens +``` + +Following the 2021 edition, all would be lexed as one token. Once again, whitespace could be inserted to mitigate any breakage. + +The motivation in this case, aside from the symmetry with prefixed identifiers, would be to leave open the design space for additional string literal prefixes other than `b"` and `r"`, e.g. hypothetical format string literals `f"`, `String` literals `s"`, `CString` literals `c"`, `OsString` literals `o"`, UTF-16 literals `w"`, user-overloadable string literals `x"`, etc., and any sensible combinations of these. + +# Guide-level explanation +When writing macros that accept token trees as inputs, be aware that certain grammatical productions which have no meaning in Rust are nonetheless accepted by the grammar, as they represent "reserved space" for future Rust language development. This behavior can be observed by macros that consume token trees. In particular, anything of the form `#` or `""` will be consumed by a macro as a single token tree. This is in contrast to, for example, `@`, which would be consumed as three token trees, as `@` does not indicate reserved syntax in the way that `#` does. These single tokens rely on the absence of whitespace, so a macro invocation can use ` # ` (note the spaces) as a way to consume individual tokens adjacent to a `#`. + +# Reference-level explanation +[reference-level-explanation]: #reference-level-explanation + +New tokenizer rules are introduced: + +> RESERVED_IDENTIFIER : IDENTIFIER_OR_KEYWORDExcept `r` `#` IDENTIFIER_OR_KEYWORD +> +> RESERVED_STRING_LITERAL : IDENTIFIER_OR_KEYWORD RAW_BYTE_STRING_LITERAL | IDENTIFIER_OR_KEYWORD BYTE_STRING_LITERAL | IDENTIFIER_OR_KEYWORDExcept `b` RAW_STRING_LITERAL | IDENTIFIER_OR_KEYWORDExcept `b`, `r`, `br` STRING_LITERAL + +Any use of a reserved identifier or reserved string literal is a compilation error. + +The use of "identifier" in this document should be taken to refer to the definition of "identifier" that is in use by Rust as of the 2021 edition. At the time of this writing, the `non_ascii_idents` feature is not yet stabilized, but is on track to be. If `non_ascii_idents` is stabilized before the 2021 edition, then the syntactic reservations that take place in the 2021 edition will include things like `über#foo`. However, if `non_ascii_idents` is *not* stabilized before the 2021 edition, then any subsequent stabilization of `non_ascii_idents` would need to take care to *not* expand the reservations in this RFC, and instead defer that task to the next edition. + +An edition migration will be implemented that looks for `ident#ident` or `ident"string"` within macro calls and inserts whitespace to force individual tokenization. + +# Drawbacks +[drawbacks]: #drawbacks + +* Complicates macro tokenizing rules. + +# Rationale and alternatives +[rationale-and-alternatives]: #rationale-and-alternatives + +* Reserve only `ident#foo` and not `ident"foo"`. The former has a concrete RFC that would benefit from this, but the latter is currently just aspirational. +* Instead of `ident`, reserve only `[a-z]+` or `[a-z]`. However, it would probably be even more surprising if `x#foo` were considered one token and `X#foo` or `xx#foo` were considered three. +* Instead of `ident`, reserve prefixes that permit any sequence of identifier continuation characters. This would allow things like preceding digits, e.g. `4#foo`. +* In addition to adding reserved prefixes to string literals, add them to numeric literals as well: `ident#1234`, `ident#56.78`. + +# Unresolved questions +[unresolved-questions]: #unresolved-questions + +* Is the automatic migration possible to implement? I'm unclear if rustfmt, and hence rustfix, is capable of peering inside of macro invocations. + +# Prior art +[prior-art]: #prior-art + +* [C: Reserved names](https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html) +* [Python: Reserved classes of identifiers](https://docs.python.org/3/reference/lexical_analysis.html#reserved-classes-of-identifiers) From fa57e5f8a83cf8a9d3b8321ce1a454890579a7cb Mon Sep 17 00:00:00 2001 From: bstrie <865233+bstrie@users.noreply.github.com> Date: Thu, 1 Apr 2021 19:56:42 -0400 Subject: [PATCH 2/8] will -> may Co-authored-by: Josh Triplett --- text/0000-reserved_prefixes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-reserved_prefixes.md b/text/0000-reserved_prefixes.md index 7eb7006561b..8cfa2eb1cd1 100644 --- a/text/0000-reserved_prefixes.md +++ b/text/0000-reserved_prefixes.md @@ -110,7 +110,7 @@ Any use of a reserved identifier or reserved string literal is a compilation err The use of "identifier" in this document should be taken to refer to the definition of "identifier" that is in use by Rust as of the 2021 edition. At the time of this writing, the `non_ascii_idents` feature is not yet stabilized, but is on track to be. If `non_ascii_idents` is stabilized before the 2021 edition, then the syntactic reservations that take place in the 2021 edition will include things like `über#foo`. However, if `non_ascii_idents` is *not* stabilized before the 2021 edition, then any subsequent stabilization of `non_ascii_idents` would need to take care to *not* expand the reservations in this RFC, and instead defer that task to the next edition. -An edition migration will be implemented that looks for `ident#ident` or `ident"string"` within macro calls and inserts whitespace to force individual tokenization. +An edition migration may be implemented that looks for `ident#ident` or `ident"string"` within macro calls and inserts whitespace to force individual tokenization. # Drawbacks [drawbacks]: #drawbacks From 058309e9502dc147dcf53f85279d84fbe86b3b40 Mon Sep 17 00:00:00 2001 From: bstrie <865233+bstrie@users.noreply.github.com> Date: Thu, 1 Apr 2021 19:58:48 -0400 Subject: [PATCH 3/8] bikeshed-proofing Co-authored-by: Josh Triplett --- text/0000-reserved_prefixes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-reserved_prefixes.md b/text/0000-reserved_prefixes.md index 8cfa2eb1cd1..63c7aa61140 100644 --- a/text/0000-reserved_prefixes.md +++ b/text/0000-reserved_prefixes.md @@ -92,7 +92,7 @@ four tokens Following the 2021 edition, all would be lexed as one token. Once again, whitespace could be inserted to mitigate any breakage. -The motivation in this case, aside from the symmetry with prefixed identifiers, would be to leave open the design space for additional string literal prefixes other than `b"` and `r"`, e.g. hypothetical format string literals `f"`, `String` literals `s"`, `CString` literals `c"`, `OsString` literals `o"`, UTF-16 literals `w"`, user-overloadable string literals `x"`, etc., and any sensible combinations of these. +The motivation in this case, aside from the symmetry with prefixed identifiers, would be to leave open the design space for additional string literal prefixes other than `b"` and `r"`. Some hypothetical examples (not necessarily planned features or planned syntax): format string literals `f"`, `String` literals `s"`, `CString` literals `c"`, `OsString` literals `o"`, UTF-16 literals `w"`, user-overloadable string literals `x"`, etc., and any sensible combinations of these. # Guide-level explanation When writing macros that accept token trees as inputs, be aware that certain grammatical productions which have no meaning in Rust are nonetheless accepted by the grammar, as they represent "reserved space" for future Rust language development. This behavior can be observed by macros that consume token trees. In particular, anything of the form `#` or `""` will be consumed by a macro as a single token tree. This is in contrast to, for example, `@`, which would be consumed as three token trees, as `@` does not indicate reserved syntax in the way that `#` does. These single tokens rely on the absence of whitespace, so a macro invocation can use ` # ` (note the spaces) as a way to consume individual tokens adjacent to a `#`. From 38aa8caf4da6915e3a77af10506f002875ca8c70 Mon Sep 17 00:00:00 2001 From: bstrie <865233+bstrie@users.noreply.github.com> Date: Thu, 1 Apr 2021 19:59:30 -0400 Subject: [PATCH 4/8] expand alternatives rationale Co-authored-by: Josh Triplett --- text/0000-reserved_prefixes.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/text/0000-reserved_prefixes.md b/text/0000-reserved_prefixes.md index 63c7aa61140..c5d8cb9c5f6 100644 --- a/text/0000-reserved_prefixes.md +++ b/text/0000-reserved_prefixes.md @@ -121,7 +121,8 @@ An edition migration may be implemented that looks for `ident#ident` or `ident"s [rationale-and-alternatives]: #rationale-and-alternatives * Reserve only `ident#foo` and not `ident"foo"`. The former has a concrete RFC that would benefit from this, but the latter is currently just aspirational. -* Instead of `ident`, reserve only `[a-z]+` or `[a-z]`. However, it would probably be even more surprising if `x#foo` were considered one token and `X#foo` or `xx#foo` were considered three. +* Instead of `ident`, reserve only `[a-z]+` or `[a-z]`. However, it would probably be even more surprising if `x#foo` were considered one token and `X#foo` or `xx#foo` were considered three. In addition, reserving only `[a-z]` would force future language extensions to use exclusively pithy single-letter syntax, even for features that may not be common enough to warrant such abbreviated syntax. Reserving identifiers in this space provides more flexibility for future language design, without impacting Rust programs. +* Instead of `ident`, reserve only `[a-zA-Z_][a-zA-Z0-9_]*` (ASCII-only identifiers). This would cover the space future Rust language design extensions are likely to use. However, the explanation of the reserved space would require presenting a distinct concept separate from the definition of identifiers. In addition, reserving only ASCII identifiers seems unlikely to provide a benefit to future Rust programs. * Instead of `ident`, reserve prefixes that permit any sequence of identifier continuation characters. This would allow things like preceding digits, e.g. `4#foo`. * In addition to adding reserved prefixes to string literals, add them to numeric literals as well: `ident#1234`, `ident#56.78`. From 14f27bd08fe486b66be371444df1d9673fe3fe13 Mon Sep 17 00:00:00 2001 From: bstrie <865233+bstrie@users.noreply.github.com> Date: Mon, 5 Apr 2021 21:22:15 -0400 Subject: [PATCH 5/8] Incorporate feedback --- text/0000-reserved_prefixes.md | 94 +++++++++++++++++++++++++--------- 1 file changed, 70 insertions(+), 24 deletions(-) diff --git a/text/0000-reserved_prefixes.md b/text/0000-reserved_prefixes.md index c5d8cb9c5f6..fe83e77af2b 100644 --- a/text/0000-reserved_prefixes.md +++ b/text/0000-reserved_prefixes.md @@ -1,3 +1,4 @@ + - Feature Name: reserved_prefixes - Start Date: 2021-03-31 - RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) @@ -6,14 +7,14 @@ # Summary [summary]: #summary -Beginning with the 2021 edition, in all contexts, reserve the syntax `ident#foo` and `ident"foo"`, as a way of future-proofing against future language changes. +Beginning with the 2021 edition, reserve the syntax `ident#foo`, `ident"foo"`, `ident'f'`, and `ident#123`, as a way of future-proofing against future language changes. # Motivation [motivation]: #motivation In [RFC 2151](https://rust-lang.github.io/rfcs/2151-raw-identifiers.html), the language syntax was expanded to allow identifiers to optionally be prefixed with `r#`, to ease migrating code when new keywords are introduced. Conversely, [RFC 3098](https://github.com/rust-lang/rfcs/pull/3098) (still under discussion as of this writing) is proposing to allow keywords to be prefixed with `k#`, as an unobtrusive way to introduce new keywords without requiring any migration effort or edition-level coordination. -In almost all circumstances these are frictionless additions; there is no place in the basic Rust grammar that would conflict with productions of the form `foo#bar`. However, there is a wrinkle with regard to macros. Consider the following code: +In almost all circumstances these are frictionless additions; there is no place in the basic Rust grammar that would conflict with productions of the form `foo#bar`. However, there is a minor wrinkle with regard to macros. Consider the following code: ```rust macro_rules! demo { ( $a:tt ) => { println!("one token") }; @@ -34,7 +35,7 @@ error: found invalid character; only `#` is allowed in raw string delimitation: | ^^ ``` -The `r#` prefix for raw identifiers was chosen because it exploited a quirk of the parser, which prevented any code containing `r#foo` from compiling due to the parser believing that it was processing a raw string literal. +The `r#` prefix for raw identifiers was originally chosen because it exploited a quirk of the parser, which prevented any code containing `r#foo` from compiling due to the parser believing that it was processing a raw string literal. After Rust 1.30 , it prints the following: ``` @@ -50,26 +51,30 @@ one token one token ``` -This would be a breaking change, which is why RFC 3098 is currently aiming to be implemented across an edition. However, the time-sensitivity of that RFC could be obviated if the language merely guaranteed that such space was syntactically available. Therefore, this RFC proposes merely reserving such syntactic space, without attaching any semantic meaning to it, to accommodate both the "raw keywords" proposal and any other future changes that would benefit. +This would be a breaking change, which is why RFC 3098 is currently aiming to be implemented across an edition. However, the time-sensitivity of that RFC could be obviated if the language merely guaranteed that such space was syntactically available. Therefore this RFC proposes reserving such syntactic space, without attaching any semantic meaning to it, to accommodate both the "raw keywords" proposal or any other future language changes that would benefit. -As further motivation, the notion of reserving "syntactic space" as an aid to backwards-compatibility is an idea that has precedence from other languages. [C reserves large swathes of the identifier space](https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html) for its own use, most notably identifiers that begin with `_` or `__`. Likewise, Python reserves all identifiers of the form `__foo__` for special use by the language. +The notion of reserving "syntactic space" as an aid to backwards-compatibility is an idea that has precedence from other languages. [C reserves large swathes of the identifier space](https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html) for its own use, most notably identifiers that begin with `_` or `__`. Likewise, Python reserves all identifiers of the form `__foo__` for special use by the language. -In contrast to Python or C, reserving syntax via `#` rather than `_` is much less of an imposition on ordinary users, because `#` is not a valid character in identifiers. The only contexts in which this change would be observable is within macros: `foo#bar` would now lex as one token rather than three. As such, the above code would produce the following when compiled on the 2021 edition: +In contrast to Python or C, reserving syntax via `#` rather than `_` is much less of an imposition on ordinary users, because `#` is not a valid character in Rust identifiers. The only contexts in which this change would be observable is within macros: `foo!(bar#qux)` would now fail to lex (a.k.a. tokenize). As such, the above code would produce the following compilation error (wording TBD) when upgrading to the 2021 edition: ``` -one token -one token -one token +error: unknown prefix on identifier: a# + --> tokens.rs:7:7 + | +7 | demo!(a#foo); + | ^^ help: try using whitespace here: `a # foo` + | + = note: prefixed identifiers are reserved for future use ``` -Note that this syntactic reservation is whitespace-sensitive: any whitespace to either side of the intervening `#` will cause three tokens to be produced rather than one. This provides a simple migration path for anyone who would be impacted by this change; they would need only change their macro invocations from `foo!(bar#qux)` to any of `foo!(bar # qux)`, `foo!(bar# qux)`, or `foo!(bar #qux)`. +Note that this syntactic reservation is whitespace-sensitive: any whitespace to either side of the intervening `#` will allow this code to compile. This provides a simple migration path for anyone who would be impacted by this change; they would need only change their macro invocations from `foo!(bar#qux)` to any of `foo!(bar # qux)`, `foo!(bar# qux)`, or `foo!(bar #qux)`. It is possible to automate this mechanical migration via rustfix. -This RFC goes beyond merely reserving the prefix `k#` and reserves all identifiers directly preceding the `#`. This has the following benefits: +Rather than try to guess what prefixes it might be useful to reserve, this RFC reserves *all* [identifiers](https://doc.rust-lang.org/reference/identifiers.html) directly preceding a `#`. This has the following benefits: 1. It increases the amount of leeway for future language changes that might wish to use this space (e.g. a hypothetical mechanism for edition-specific keywords might be written as `edition2015#use`). 2. It has symmetry with the existing notion of [literal suffixes](https://doc.rust-lang.org/reference/tokens.html#suffixes). 3. It avoids complicating the grammar and parser with bespoke concepts. -Finally, this RFC also proposes that this same syntactic reservation be applied to string literals (including raw string literals), whose syntax was the original inspiration for this design space. Once again, this reservation would be mostly unobservable by end-users and would only manifest in code using macros like so: +Finally, this RFC also proposes that this same syntax be reserved for string literals (`ident"foo"`), char literals (`ident'f'`), and numeric literals (`ident#123`). Once again, this reservation would be mostly unobservable by end-users and would only manifest in code using macros like so: ```rust macro_rules! demo { @@ -90,27 +95,66 @@ two tokens four tokens ``` -Following the 2021 edition, all would be lexed as one token. Once again, whitespace could be inserted to mitigate any breakage. +Following the 2021 edition, these would become compiler errors. Once again, whitespace could be (automatically) inserted to mitigate any breakage. -The motivation in this case, aside from the symmetry with prefixed identifiers, would be to leave open the design space for additional string literal prefixes other than `b"` and `r"`. Some hypothetical examples (not necessarily planned features or planned syntax): format string literals `f"`, `String` literals `s"`, `CString` literals `c"`, `OsString` literals `o"`, UTF-16 literals `w"`, user-overloadable string literals `x"`, etc., and any sensible combinations of these. +The motivation here, aside from the symmetry with prefixed identifiers and [literal suffixes](https://doc.rust-lang.org/reference/tokens.html#suffixes), would be to leave open the design space for new literal prefixes along the lines of the existing `b"` and `r"` prefixes. Some hypothetical examples (not necessarily planned features or planned syntax): format string literals `f"`, `String` literals `s"`, `CString` literals `c"`, `OsString` literals `o"`, UTF-16 literals `w"`, user-overloadable string literals `x"`, etc. # Guide-level explanation -When writing macros that accept token trees as inputs, be aware that certain grammatical productions which have no meaning in Rust are nonetheless accepted by the grammar, as they represent "reserved space" for future Rust language development. This behavior can be observed by macros that consume token trees. In particular, anything of the form `#` or `""` will be consumed by a macro as a single token tree. This is in contrast to, for example, `@`, which would be consumed as three token trees, as `@` does not indicate reserved syntax in the way that `#` does. These single tokens rely on the absence of whitespace, so a macro invocation can use ` # ` (note the spaces) as a way to consume individual tokens adjacent to a `#`. +When designing DSLs via macros that take token trees as inputs, be aware that certain syntactic productions which have no meaning in Rust are nonetheless forbidden by the grammar, as they represent "reserved space" for future language development. In particular, anything of the form `#`, `""`, `''`, and `#` is reserved for exclusive use by the language; these are called *reserved prefixes*. + +Unless a prefix has been assigned a specific meaning by the language (e.g. `r#async`, `b"foo"`), Rust will fail to tokenize when encountering any code that attempts to make use of such prefixes. Note that these prefixes rely on the absence of whitespace, so a macro invocation can use ` # ` (note the spaces) as a way to consume individual tokens adjacent to a `#`. + +Putting it all together, this means that the following are valid macro invocations: + +* `foo!(r#async)`, +* `foo!(b'x')` +* `foo!(bar # qux)`, +* `foo!(bar #123)` +* `foo!(bar# "qux")` + +...but the following are invalid macro invocations: + +* `foo!(bar#async)` +* `foo!(bar#123)` +* `foo!(bar"qux")` # Reference-level explanation [reference-level-explanation]: #reference-level-explanation -New tokenizer rules are introduced: +New tokenizing rules are introduced: > RESERVED_IDENTIFIER : IDENTIFIER_OR_KEYWORDExcept `r` `#` IDENTIFIER_OR_KEYWORD > +> RESERVED_CHAR_LITERAL : IDENTIFIER_OR_KEYWORD BYTE_LITERAL | IDENTIFIER_OR_KEYWORDExcept `b` CHAR_LITERAL +> > RESERVED_STRING_LITERAL : IDENTIFIER_OR_KEYWORD RAW_BYTE_STRING_LITERAL | IDENTIFIER_OR_KEYWORD BYTE_STRING_LITERAL | IDENTIFIER_OR_KEYWORDExcept `b` RAW_STRING_LITERAL | IDENTIFIER_OR_KEYWORDExcept `b`, `r`, `br` STRING_LITERAL +> +> RESERVED_NUMERIC_LITERAL : IDENTIFIER_OR_KEYWORD `#` (INTEGER_LITERAL | FLOAT_LITERAL) + +When compiling under the Rust 2021 edition (as determined by the edition of the current crate), any instance of the above produces a tokenization error. -Any use of a reserved identifier or reserved string literal is a compilation error. +The use of "identifier" in this document proactively refers to whatever definition of "identifier" is in use by Rust as of the 2021 edition. At the time of this writing, the `non_ascii_idents` feature is not yet stabilized, but is on track to be. If `non_ascii_idents` is stabilized before the 2021 edition, then the syntactic reservations that take place in the 2021 edition will include things like `über#foo`. However, if `non_ascii_idents` is *not* stabilized before the 2021 edition, then any subsequent stabilization of `non_ascii_idents` would need to take care to *not* expand the reservations in this RFC, and instead defer that task to the next edition. -The use of "identifier" in this document should be taken to refer to the definition of "identifier" that is in use by Rust as of the 2021 edition. At the time of this writing, the `non_ascii_idents` feature is not yet stabilized, but is on track to be. If `non_ascii_idents` is stabilized before the 2021 edition, then the syntactic reservations that take place in the 2021 edition will include things like `über#foo`. However, if `non_ascii_idents` is *not* stabilized before the 2021 edition, then any subsequent stabilization of `non_ascii_idents` would need to take care to *not* expand the reservations in this RFC, and instead defer that task to the next edition. +An edition migration may be implemented that looks for `ident#ident`, `ident"string"`, etc. within macro calls and inserts whitespace to force proper tokenization. -An edition migration may be implemented that looks for `ident#ident` or `ident"string"` within macro calls and inserts whitespace to force individual tokenization. +What follows are some examples of suggested error message templates: +``` +error: unknown prefix on identifier: bar# + --> file.rs:x:y + | +1 | foo!(bar#qux); + | ^^^^ help: try using whitespace here: `bar # qux` + | + = note: prefixed identifiers are reserved for future use + +error: unknown prefix on string literal: bar + --> file.rs:x:y + | +1 | foo!(bar"qux"); + | ^^^ help: try using whitespace here: `bar "qux"` + | + = note: prefixed string literals are reserved for future use +``` # Drawbacks [drawbacks]: #drawbacks @@ -120,19 +164,21 @@ An edition migration may be implemented that looks for `ident#ident` or `ident"s # Rationale and alternatives [rationale-and-alternatives]: #rationale-and-alternatives -* Reserve only `ident#foo` and not `ident"foo"`. The former has a concrete RFC that would benefit from this, but the latter is currently just aspirational. -* Instead of `ident`, reserve only `[a-z]+` or `[a-z]`. However, it would probably be even more surprising if `x#foo` were considered one token and `X#foo` or `xx#foo` were considered three. In addition, reserving only `[a-z]` would force future language extensions to use exclusively pithy single-letter syntax, even for features that may not be common enough to warrant such abbreviated syntax. Reserving identifiers in this space provides more flexibility for future language design, without impacting Rust programs. -* Instead of `ident`, reserve only `[a-zA-Z_][a-zA-Z0-9_]*` (ASCII-only identifiers). This would cover the space future Rust language design extensions are likely to use. However, the explanation of the reserved space would require presenting a distinct concept separate from the definition of identifiers. In addition, reserving only ASCII identifiers seems unlikely to provide a benefit to future Rust programs. +* Reserve only prefixed identifiers, and not prefixed literals. The former has a concrete RFC that would benefit from this, but the latter is currently just aspirational. +* Instead of `ident`, reserve only `[a-z]+` or `[a-z]`. However, reserving only `[a-z]` would force future language extensions to use exclusively pithy single-letter syntax, even for features that may not be common enough to warrant such abbreviated syntax. Reserving identifiers in this space provides more flexibility for future language design, without impacting Rust programs. +* Instead of `ident`, reserve only `[a-zA-Z_][a-zA-Z0-9_]*`, the set of ASCII-only identifiers. This would cover the space future Rust language design extensions are likely to use. However, the explanation of the reserved space would require presenting a distinct concept separate from the definition of identifiers. In addition, reserving only ASCII identifiers seems unlikely to provide a benefit to future Rust programs. * Instead of `ident`, reserve prefixes that permit any sequence of identifier continuation characters. This would allow things like preceding digits, e.g. `4#foo`. -* In addition to adding reserved prefixes to string literals, add them to numeric literals as well: `ident#1234`, `ident#56.78`. # Unresolved questions [unresolved-questions]: #unresolved-questions -* Is the automatic migration possible to implement? I'm unclear if rustfmt, and hence rustfix, is capable of peering inside of macro invocations. +* None. # Prior art [prior-art]: #prior-art * [C: Reserved names](https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html) * [Python: Reserved classes of identifiers](https://docs.python.org/3/reference/lexical_analysis.html#reserved-classes-of-identifiers) +* [Ada: Based literals](archive.adaic.com/standards/83lrm/html/lrm-02-04.html#2.4.2) +* [Emacs Calc: Integers](https://www.gnu.org/software/emacs/manual/html_mono/calc.html#Integers) + From 135ecb2668fc8cc95a7e9aeae5b63b322976c41c Mon Sep 17 00:00:00 2001 From: bstrie <865233+bstrie@users.noreply.github.com> Date: Tue, 13 Apr 2021 20:40:47 -0400 Subject: [PATCH 6/8] Incorporate feedback, round 2 --- text/0000-reserved_prefixes.md | 71 ++++++++++++++-------------------- 1 file changed, 29 insertions(+), 42 deletions(-) diff --git a/text/0000-reserved_prefixes.md b/text/0000-reserved_prefixes.md index fe83e77af2b..6fa1fb082c8 100644 --- a/text/0000-reserved_prefixes.md +++ b/text/0000-reserved_prefixes.md @@ -55,18 +55,14 @@ This would be a breaking change, which is why RFC 3098 is currently aiming to be The notion of reserving "syntactic space" as an aid to backwards-compatibility is an idea that has precedence from other languages. [C reserves large swathes of the identifier space](https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html) for its own use, most notably identifiers that begin with `_` or `__`. Likewise, Python reserves all identifiers of the form `__foo__` for special use by the language. -In contrast to Python or C, reserving syntax via `#` rather than `_` is much less of an imposition on ordinary users, because `#` is not a valid character in Rust identifiers. The only contexts in which this change would be observable is within macros: `foo!(bar#qux)` would now fail to lex (a.k.a. tokenize). As such, the above code would produce the following compilation error (wording TBD) when upgrading to the 2021 edition: +In contrast to Python or C, reserving syntax via `#` rather than `_` is much less of an imposition on ordinary users, because `#` is not a valid character in Rust identifiers. The only contexts in which this change would be observable is within macros: `foo!(bar#qux)` would now pass one token to `foo!` rather than three. As such, the above code would produce the following on the 2021 edition: ``` -error: unknown prefix on identifier: a# - --> tokens.rs:7:7 - | -7 | demo!(a#foo); - | ^^ help: try using whitespace here: `a # foo` - | - = note: prefixed identifiers are reserved for future use +one token +one token +one token ``` -Note that this syntactic reservation is whitespace-sensitive: any whitespace to either side of the intervening `#` will allow this code to compile. This provides a simple migration path for anyone who would be impacted by this change; they would need only change their macro invocations from `foo!(bar#qux)` to any of `foo!(bar # qux)`, `foo!(bar# qux)`, or `foo!(bar #qux)`. It is possible to automate this mechanical migration via rustfix. +Note that this syntactic reservation is whitespace-sensitive: any whitespace to either side of the intervening `#` will cause three tokens to be produced rather than one. This provides a simple migration path for anyone who would be impacted by this change; they would need only change their macro invocations from `foo!(bar#qux)` to any of `foo!(bar # qux)`, `foo!(bar# qux)`, or `foo!(bar #qux)`. It is possible to automate this mechanical migration via rustfix. Rather than try to guess what prefixes it might be useful to reserve, this RFC reserves *all* [identifiers](https://doc.rust-lang.org/reference/identifiers.html) directly preceding a `#`. This has the following benefits: @@ -95,28 +91,14 @@ two tokens four tokens ``` -Following the 2021 edition, these would become compiler errors. Once again, whitespace could be (automatically) inserted to mitigate any breakage. +Following the 2021 edition, these would each be lexed as one token. Once again, whitespace could be (automatically) inserted to mitigate any breakage. The motivation here, aside from the symmetry with prefixed identifiers and [literal suffixes](https://doc.rust-lang.org/reference/tokens.html#suffixes), would be to leave open the design space for new literal prefixes along the lines of the existing `b"` and `r"` prefixes. Some hypothetical examples (not necessarily planned features or planned syntax): format string literals `f"`, `String` literals `s"`, `CString` literals `c"`, `OsString` literals `o"`, UTF-16 literals `w"`, user-overloadable string literals `x"`, etc. -# Guide-level explanation -When designing DSLs via macros that take token trees as inputs, be aware that certain syntactic productions which have no meaning in Rust are nonetheless forbidden by the grammar, as they represent "reserved space" for future language development. In particular, anything of the form `#`, `""`, `''`, and `#` is reserved for exclusive use by the language; these are called *reserved prefixes*. - -Unless a prefix has been assigned a specific meaning by the language (e.g. `r#async`, `b"foo"`), Rust will fail to tokenize when encountering any code that attempts to make use of such prefixes. Note that these prefixes rely on the absence of whitespace, so a macro invocation can use ` # ` (note the spaces) as a way to consume individual tokens adjacent to a `#`. - -Putting it all together, this means that the following are valid macro invocations: - -* `foo!(r#async)`, -* `foo!(b'x')` -* `foo!(bar # qux)`, -* `foo!(bar #123)` -* `foo!(bar# "qux")` +There is one subtle note to this reservation: because raw string literals and string literals tokenize differently, any prefix ending in `r` will tokenize as a raw string literal would tokenize, and any prefix not ending in `r` will tokenize as a non-raw string literal would tokenize. This is considered acceptable in that it is assumed that new prefixes on these literals will be "compositional" in nature, in the same sense that `b` and `r` on string literals compose today, and thus it will be natural and intentional to compose any such prefix with `r` in order to achieve raw string semantics when desired. However, any hypothetical *non*-compositional prefix would need to be chosen carefully in order to achieve its desired tokenization -...but the following are invalid macro invocations: - -* `foo!(bar#async)` -* `foo!(bar#123)` -* `foo!(bar"qux")` +# Guide-level explanation +When designing DSLs via macros that take token trees as inputs, be aware that certain syntactic productions which have no defined meaning are nonetheless understood by the Rust grammar, as they represent "reserved space" for potential future language development. In particular, anything of the form `#`, `""`, `''`, and `#` is reserved for future use by the language; these are called *reserved prefixes*. Macros that accept token trees may consume such prefixes, although note that all of the aforementioned forms will produce only one token tree rather than the two or three that you might otherwise expect. Note that these prefixes rely on the absence of whitespace, so a macro invocation can use e.g. ` # ` (note the spaces) as a way to consume individual tokens adjacent to a `#`. # Reference-level explanation [reference-level-explanation]: #reference-level-explanation @@ -125,37 +107,42 @@ New tokenizing rules are introduced: > RESERVED_IDENTIFIER : IDENTIFIER_OR_KEYWORDExcept `r` `#` IDENTIFIER_OR_KEYWORD > -> RESERVED_CHAR_LITERAL : IDENTIFIER_OR_KEYWORD BYTE_LITERAL | IDENTIFIER_OR_KEYWORDExcept `b` CHAR_LITERAL -> -> RESERVED_STRING_LITERAL : IDENTIFIER_OR_KEYWORD RAW_BYTE_STRING_LITERAL | IDENTIFIER_OR_KEYWORD BYTE_STRING_LITERAL | IDENTIFIER_OR_KEYWORDExcept `b` RAW_STRING_LITERAL | IDENTIFIER_OR_KEYWORDExcept `b`, `r`, `br` STRING_LITERAL +> RESERVED_BYTE_LITERAL : IDENTIFIER_OR_KEYWORD BYTE_LITERAL +> +> RESERVED_CHAR_LITERAL : IDENTIFIER_OR_KEYWORDExcept `b` CHAR_LITERAL +> +> RESERVED_RAW_BYTE_STRING_LITERAL : IDENTIFIER_OR_KEYWORD RAW_BYTE_STRING_LITERAL +> +> RESERVED_BYTE_STRING_LITERAL : IDENTIFIER_OR_KEYWORD BYTE_STRING_LITERAL +> +> RESERVED_RAW_STRING_LITERAL : IDENTIFIER_OR_KEYWORDExcept`b` RAW_STRING_LITERAL +> +> RESERVED_STRING_LITERAL : IDENTIFIER_OR_KEYWORDExcept `b`, `r`, `br` STRING_LITERAL > > RESERVED_NUMERIC_LITERAL : IDENTIFIER_OR_KEYWORD `#` (INTEGER_LITERAL | FLOAT_LITERAL) -When compiling under the Rust 2021 edition (as determined by the edition of the current crate), any instance of the above produces a tokenization error. - -The use of "identifier" in this document proactively refers to whatever definition of "identifier" is in use by Rust as of the 2021 edition. At the time of this writing, the `non_ascii_idents` feature is not yet stabilized, but is on track to be. If `non_ascii_idents` is stabilized before the 2021 edition, then the syntactic reservations that take place in the 2021 edition will include things like `über#foo`. However, if `non_ascii_idents` is *not* stabilized before the 2021 edition, then any subsequent stabilization of `non_ascii_idents` would need to take care to *not* expand the reservations in this RFC, and instead defer that task to the next edition. +When compiling under the Rust 2021 edition (as determined by the edition of the current crate), each of the above rules will produce a single token; for earlier editions these rules will be ignored. -An edition migration may be implemented that looks for `ident#ident`, `ident"string"`, etc. within macro calls and inserts whitespace to force proper tokenization. - -What follows are some examples of suggested error message templates: +Encountering any of the above tokens will result in an error in the parser. What follows are some examples of suggested error message templates. ``` error: unknown prefix on identifier: bar# --> file.rs:x:y | -1 | foo!(bar#qux); - | ^^^^ help: try using whitespace here: `bar # qux` +1 | bar#qux; | - = note: prefixed identifiers are reserved for future use error: unknown prefix on string literal: bar --> file.rs:x:y | -1 | foo!(bar"qux"); - | ^^^ help: try using whitespace here: `bar "qux"` +1 | bar"qux"; | - = note: prefixed string literals are reserved for future use ``` +The use of "identifier" in this document proactively refers to whatever definition of "identifier" is in use by Rust as of the 2021 edition. At the time of this writing, the `non_ascii_idents` feature is not yet stabilized, but is on track to be. If `non_ascii_idents` is stabilized before the 2021 edition, then the syntactic reservations that take place in the 2021 edition will include things like `über#foo`. However, if `non_ascii_idents` is *not* stabilized before the 2021 edition, then any subsequent stabilization of `non_ascii_idents` would need to take care to *not* expand the reservations in this RFC, and instead defer that task to the next edition. + +An edition migration may be implemented that looks for `ident#ident`, `ident"string"`, etc. within macro calls and inserts whitespace, in order to allow the invocation tokenize as it previously had. + + # Drawbacks [drawbacks]: #drawbacks From 920a7e88acf2d2758da563f806926633f07823c6 Mon Sep 17 00:00:00 2001 From: bstrie <865233+bstrie@users.noreply.github.com> Date: Mon, 19 Apr 2021 17:54:51 -0400 Subject: [PATCH 7/8] Incorporate feedback, round 3 --- text/0000-reserved_prefixes.md | 64 +++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/text/0000-reserved_prefixes.md b/text/0000-reserved_prefixes.md index 6fa1fb082c8..990b023b585 100644 --- a/text/0000-reserved_prefixes.md +++ b/text/0000-reserved_prefixes.md @@ -55,14 +55,18 @@ This would be a breaking change, which is why RFC 3098 is currently aiming to be The notion of reserving "syntactic space" as an aid to backwards-compatibility is an idea that has precedence from other languages. [C reserves large swathes of the identifier space](https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html) for its own use, most notably identifiers that begin with `_` or `__`. Likewise, Python reserves all identifiers of the form `__foo__` for special use by the language. -In contrast to Python or C, reserving syntax via `#` rather than `_` is much less of an imposition on ordinary users, because `#` is not a valid character in Rust identifiers. The only contexts in which this change would be observable is within macros: `foo!(bar#qux)` would now pass one token to `foo!` rather than three. As such, the above code would produce the following on the 2021 edition: +In contrast to Python or C, reserving syntax via `#` rather than `_` is much less of an imposition on ordinary users, because `#` is not a valid character in Rust identifiers. The only contexts in which this change would be observable is within macros: `foo!(bar#qux)` would now fail to lex (a.k.a. tokenize). As such, the above code would produce the following compilation error (wording TBD) when upgrading to the 2021 edition: ``` -one token -one token -one token +error: unknown prefix on identifier: a# + --> tokens.rs:7:7 + | +7 | demo!(a#foo); + | ^^ help: try using whitespace here: `a # foo` + | + = note: prefixed identifiers are reserved for future use ``` -Note that this syntactic reservation is whitespace-sensitive: any whitespace to either side of the intervening `#` will cause three tokens to be produced rather than one. This provides a simple migration path for anyone who would be impacted by this change; they would need only change their macro invocations from `foo!(bar#qux)` to any of `foo!(bar # qux)`, `foo!(bar# qux)`, or `foo!(bar #qux)`. It is possible to automate this mechanical migration via rustfix. +Note that this syntactic reservation is whitespace-sensitive: any whitespace to either side of the intervening `#` will allow this code to compile. This provides a simple migration path for anyone who would be impacted by this change; they would need only change their macro invocations from `foo!(bar#qux)` to any of `foo!(bar # qux)`, `foo!(bar# qux)`, or `foo!(bar #qux)`. It is possible to automate this mechanical migration via rustfix. Rather than try to guess what prefixes it might be useful to reserve, this RFC reserves *all* [identifiers](https://doc.rust-lang.org/reference/identifiers.html) directly preceding a `#`. This has the following benefits: @@ -91,14 +95,30 @@ two tokens four tokens ``` -Following the 2021 edition, these would each be lexed as one token. Once again, whitespace could be (automatically) inserted to mitigate any breakage. +Following the 2021 edition, these would become compiler errors. Once again, whitespace could be (automatically) inserted to mitigate any breakage. The motivation here, aside from the symmetry with prefixed identifiers and [literal suffixes](https://doc.rust-lang.org/reference/tokens.html#suffixes), would be to leave open the design space for new literal prefixes along the lines of the existing `b"` and `r"` prefixes. Some hypothetical examples (not necessarily planned features or planned syntax): format string literals `f"`, `String` literals `s"`, `CString` literals `c"`, `OsString` literals `o"`, UTF-16 literals `w"`, user-overloadable string literals `x"`, etc. There is one subtle note to this reservation: because raw string literals and string literals tokenize differently, any prefix ending in `r` will tokenize as a raw string literal would tokenize, and any prefix not ending in `r` will tokenize as a non-raw string literal would tokenize. This is considered acceptable in that it is assumed that new prefixes on these literals will be "compositional" in nature, in the same sense that `b` and `r` on string literals compose today, and thus it will be natural and intentional to compose any such prefix with `r` in order to achieve raw string semantics when desired. However, any hypothetical *non*-compositional prefix would need to be chosen carefully in order to achieve its desired tokenization # Guide-level explanation -When designing DSLs via macros that take token trees as inputs, be aware that certain syntactic productions which have no defined meaning are nonetheless understood by the Rust grammar, as they represent "reserved space" for potential future language development. In particular, anything of the form `#`, `""`, `''`, and `#` is reserved for future use by the language; these are called *reserved prefixes*. Macros that accept token trees may consume such prefixes, although note that all of the aforementioned forms will produce only one token tree rather than the two or three that you might otherwise expect. Note that these prefixes rely on the absence of whitespace, so a macro invocation can use e.g. ` # ` (note the spaces) as a way to consume individual tokens adjacent to a `#`. +When designing DSLs via macros that take token trees as inputs, be aware that certain syntactic productions which have no meaning in Rust are nonetheless forbidden by the grammar, as they represent "reserved space" for future language development. In particular, anything of the form `#`, `""`, `''`, and `#` is reserved for exclusive use by the language; these are called *reserved prefixes*. + +Unless a prefix has been assigned a specific meaning by the language (e.g. `r#async`, `b"foo"`), Rust will fail to tokenize when encountering any code that attempts to make use of such prefixes. Note that these prefixes rely on the absence of whitespace, so a macro invocation can use ` # ` (note the spaces) as a way to consume individual tokens adjacent to a `#`. + +Putting it all together, this means that the following are valid macro invocations: + +* `foo!(r#async)`, +* `foo!(b'x')` +* `foo!(bar # qux)`, +* `foo!(bar #123)` +* `foo!(bar# "qux")` + +...but the following are invalid macro invocations: + +* `foo!(bar#async)` +* `foo!(bar#123)` +* `foo!(bar"qux")` # Reference-level explanation [reference-level-explanation]: #reference-level-explanation @@ -121,28 +141,40 @@ New tokenizing rules are introduced: > > RESERVED_NUMERIC_LITERAL : IDENTIFIER_OR_KEYWORD `#` (INTEGER_LITERAL | FLOAT_LITERAL) -When compiling under the Rust 2021 edition (as determined by the edition of the current crate), each of the above rules will produce a single token; for earlier editions these rules will be ignored. +When compiling under the Rust 2021 edition (as determined by the edition of the current crate), any instance of the above produces a tokenization error. + +The use of "identifier" in this document proactively refers to whatever definition of "identifier" is in use by Rust as of the 2021 edition. At the time of this writing, the `non_ascii_idents` feature is not yet stabilized, but is on track to be. If `non_ascii_idents` is stabilized before the 2021 edition, then the syntactic reservations that take place in the 2021 edition will include things like `über#foo`. However, if `non_ascii_idents` is *not* stabilized before the 2021 edition, then any subsequent stabilization of `non_ascii_idents` would need to take care to *not* expand the reservations in this RFC, and instead defer that task to the next edition. + +An edition migration may be implemented that looks for `ident#ident`, `ident"string"`, etc. within macro calls and inserts whitespace to force proper tokenization. -Encountering any of the above tokens will result in an error in the parser. What follows are some examples of suggested error message templates. +What follows are some examples of suggested error message templates: ``` error: unknown prefix on identifier: bar# --> file.rs:x:y | 1 | bar#qux; + | ^^^^ | - +``` +``` +error: unknown prefix on identifier: bar# + --> file.rs:x:y + | +1 | foo!(bar#qux); + | ^^^^ help: try using whitespace here: `bar # qux` + | + = note: prefixed identifiers are reserved for future use +``` +``` error: unknown prefix on string literal: bar --> file.rs:x:y | -1 | bar"qux"; +1 | foo!(bar"qux"); + | ^^^ help: try using whitespace here: `bar "qux"` | + = note: prefixed string literals are reserved for future use ``` -The use of "identifier" in this document proactively refers to whatever definition of "identifier" is in use by Rust as of the 2021 edition. At the time of this writing, the `non_ascii_idents` feature is not yet stabilized, but is on track to be. If `non_ascii_idents` is stabilized before the 2021 edition, then the syntactic reservations that take place in the 2021 edition will include things like `über#foo`. However, if `non_ascii_idents` is *not* stabilized before the 2021 edition, then any subsequent stabilization of `non_ascii_idents` would need to take care to *not* expand the reservations in this RFC, and instead defer that task to the next edition. - -An edition migration may be implemented that looks for `ident#ident`, `ident"string"`, etc. within macro calls and inserts whitespace, in order to allow the invocation tokenize as it previously had. - - # Drawbacks [drawbacks]: #drawbacks From ac7ad20398a3bdce68e66f66670666903cbc656c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 6 May 2021 06:00:59 -0400 Subject: [PATCH 8/8] RFC 3101: link to PR, tracking issue, add unresolved question --- ...{0000-reserved_prefixes.md => 3101-reserved_prefixes.md} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename text/{0000-reserved_prefixes.md => 3101-reserved_prefixes.md} (97%) diff --git a/text/0000-reserved_prefixes.md b/text/3101-reserved_prefixes.md similarity index 97% rename from text/0000-reserved_prefixes.md rename to text/3101-reserved_prefixes.md index 990b023b585..bc98e53b02d 100644 --- a/text/0000-reserved_prefixes.md +++ b/text/3101-reserved_prefixes.md @@ -1,8 +1,8 @@ - Feature Name: reserved_prefixes - Start Date: 2021-03-31 -- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) -- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) +- RFC PR: [rust-lang/rfcs#3101](https://github.com/rust-lang/rfcs/pull/3101) +- Rust Issue: [rust-lang/rust#84978](https://github.com/rust-lang/rust/issues/84978) # Summary [summary]: #summary @@ -191,7 +191,7 @@ error: unknown prefix on string literal: bar # Unresolved questions [unresolved-questions]: #unresolved-questions -* None. +* How to manage the API `proc_macro::TokenStream::from_str`, which does not take any edition information? ([raised here](https://github.com/rust-lang/rfcs/pull/3101#issuecomment-832686934)) # Prior art [prior-art]: #prior-art