diff --git a/src/doc/grammar.md b/src/doc/grammar.md index 3aa89cba0314a..a6e705fc6526a 100644 --- a/src/doc/grammar.md +++ b/src/doc/grammar.md @@ -108,7 +108,7 @@ the following form: gated. This is expected to improve soon. - The first character has property `XID_start` -- The remaining characters have property `XID_continue` +- The remaining characters have property `XID_continue` or is a superscript that does _not_ occur in the set of [keywords](#keywords). @@ -281,7 +281,7 @@ type_path_tail : '<' type_expr [ ',' type_expr ] + '>' ## Macros ```antlr -expr_macro_rules : "macro_rules" '!' ident '(' macro_rule * ')' ';' +expr_macro_rules : "macro_rules" '!' ident '(' macro_rule * ')' ';' | "macro_rules" '!' ident '{' macro_rule * '}' ; macro_rule : '(' matcher * ')' "=>" '(' transcriber * ')' ';' ; matcher : '(' matcher * ')' | '[' matcher * ']' diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 7ca89cfd0c9cc..3578adbff2f27 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -402,7 +402,7 @@ impl<'a> Parser<'a> { let end; loop { match self.cur.clone().next() { - Some((_, c)) if c.is_xid_continue() => { + Some((_, c)) if c.is_xid_continue() || c.is_superscript() => { self.cur.next(); } Some((pos, _)) => { end = pos; break } diff --git a/src/librustc_unicode/char.rs b/src/librustc_unicode/char.rs index 2596620d39d3d..e6d7386058b8a 100644 --- a/src/librustc_unicode/char.rs +++ b/src/librustc_unicode/char.rs @@ -373,6 +373,14 @@ impl char { #[inline] pub fn is_xid_continue(self) -> bool { derived_property::XID_Continue(self) } + /// Returns whether the specified `char` is a superscript character in the + /// ['Superscripts and Subscripts' unicode block] + /// (https://en.wikipedia.org/wiki/Superscripts_and_Subscripts) + #[unstable(feature = "unicode", + reason = "mainly needed for compiler internals")] + #[inline] + pub fn is_superscript(self) -> bool { derived_property::Superscript(self) } + /// Indicates whether a character is in lowercase. /// /// This is defined according to the terms of the Unicode Derived Core diff --git a/src/librustc_unicode/tables.rs b/src/librustc_unicode/tables.rs index ed1df9882062e..6754c749c2912 100644 --- a/src/librustc_unicode/tables.rs +++ b/src/librustc_unicode/tables.rs @@ -1147,6 +1147,14 @@ pub mod derived_property { super::bsearch_range_table(c, XID_Start_table) } + pub const Superscript_table: &'static [(char, char)] = &[ + ('\u{b2}', '\u{b3}'), ('\u{b9}', '\u{b9}'), ('\u{2070}', '\u{2071}'), + ('\u{2074}', '\u{207f}') + ]; + + pub fn Superscript(c: char) -> bool { + super::bsearch_range_table(c, Superscript_table) + } } pub mod property { diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 507bd9de2a11a..fb188217dc2a2 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1396,7 +1396,7 @@ fn ident_continue(c: Option) -> bool { || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_' - || (c > '\x7f' && c.is_xid_continue()) + || (c > '\x7f' && (c.is_xid_continue() || c.is_superscript())) } #[cfg(test)] diff --git a/src/test/run-pass/unicode-superscripts.rs b/src/test/run-pass/unicode-superscripts.rs new file mode 100644 index 0000000000000..f98746088d56a --- /dev/null +++ b/src/test/run-pass/unicode-superscripts.rs @@ -0,0 +1,25 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(unused_variables)] +#![feature(non_ascii_idents)] + +pub fn main() { + let σ⁰ = 2; + let σ¹ = 2; + let σ² = 1; + let σ³ = 2; + let σ⁴ = 2; + let σ⁵ = 2; + let σ⁶ = 2; + let σ⁷ = 2; + let σ⁸ = 2; + let σ⁹ = 2; +}