]> git.lizzy.rs Git - rust.git/blobdiff - src/libsyntax_pos/symbol.rs
Various minor/cosmetic improvements to code
[rust.git] / src / libsyntax_pos / symbol.rs
index 741877bb4c88fdc94e99d6678edcb7208c9e659a..05c53878e70042cbcdc306c69b7f99d8c80b4a51 100644 (file)
@@ -9,20 +9,21 @@
 // except according to those terms.
 
 //! An "interner" is a data structure that associates values with usize tags and
-//! allows bidirectional lookup; i.e. given a value, one can easily find the
+//! allows bidirectional lookup; i.e., given a value, one can easily find the
 //! type, and vice versa.
 
-use hygiene::SyntaxContext;
-use {Span, DUMMY_SP, GLOBALS};
-
-use rustc_data_structures::fx::FxHashMap;
 use arena::DroplessArena;
+use rustc_data_structures::fx::FxHashMap;
 use serialize::{Decodable, Decoder, Encodable, Encoder};
+
 use std::fmt;
 use std::str;
 use std::cmp::{PartialEq, Ordering, PartialOrd, Ord};
 use std::hash::{Hash, Hasher};
 
+use hygiene::SyntaxContext;
+use {Span, DUMMY_SP, GLOBALS};
+
 #[derive(Copy, Clone, Eq)]
 pub struct Ident {
     pub name: Symbol,
@@ -34,6 +35,7 @@ impl Ident {
     pub const fn new(name: Symbol, span: Span) -> Ident {
         Ident { name, span }
     }
+
     #[inline]
     pub const fn with_empty_ctxt(name: Symbol) -> Ident {
         Ident::new(name, DUMMY_SP)
@@ -60,7 +62,7 @@ pub fn without_first_quote(self) -> Ident {
 
     /// "Normalize" ident for use in comparisons using "item hygiene".
     /// Identifiers with same string value become same if they came from the same "modern" macro
-    /// (e.g. `macro` item, but not `macro_rules` item) and stay different if they came from
+    /// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
     /// different "modern" macros.
     /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
     pub fn modern(self) -> Ident {
@@ -69,7 +71,7 @@ pub fn modern(self) -> Ident {
 
     /// "Normalize" ident for use in comparisons using "local variable hygiene".
     /// Identifiers with same string value become same if they came from the same non-transparent
-    /// macro (e.g. `macro` or `macro_rules!` items) and stay different if they came from different
+    /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different
     /// non-transparent macros.
     /// Technically, this operation strips all transparent marks from ident's syntactic context.
     pub fn modern_and_legacy(self) -> Ident {
@@ -80,6 +82,10 @@ pub fn gensym(self) -> Ident {
         Ident::new(self.name.gensymed(), self.span)
     }
 
+    pub fn gensym_if_underscore(self) -> Ident {
+        if self.name == keywords::Underscore.name() { self.gensym() } else { self }
+    }
+
     pub fn as_str(self) -> LocalInternedString {
         self.name.as_str()
     }
@@ -118,7 +124,7 @@ impl Encodable for Ident {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
         if self.span.ctxt().modern() == SyntaxContext::empty() {
             s.emit_str(&self.as_str())
-        } else { // FIXME(jseyfried) intercrate hygiene
+        } else { // FIXME(jseyfried): intercrate hygiene
             let mut string = "#".to_owned();
             string.push_str(&self.as_str());
             s.emit_str(&string)
@@ -131,7 +137,7 @@ fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
         let string = d.read_str()?;
         Ok(if !string.starts_with('#') {
             Ident::from_str(&string)
-        } else { // FIXME(jseyfried) intercrate hygiene
+        } else { // FIXME(jseyfried): intercrate hygiene
             Ident::with_empty_ctxt(Symbol::gensym(&string[1..]))
         })
     }
@@ -142,7 +148,7 @@ fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
 pub struct Symbol(u32);
 
 // The interner is pointed to by a thread local value which is only set on the main thread
-// with parallelization is disabled. So we don't allow Symbol to transfer between threads
+// with parallelization is disabled. So we don't allow `Symbol` to transfer between threads
 // to avoid panics and other errors, even though it would be memory safe to do so.
 #[cfg(not(parallel_queries))]
 impl !Send for Symbol { }
@@ -159,7 +165,7 @@ pub fn interned(self) -> Self {
         with_interner(|interner| interner.interned(self))
     }
 
-    /// gensym's a new usize, using the current interner.
+    /// Gensyms a new usize, using the current interner.
     pub fn gensym(string: &str) -> Self {
         with_interner(|interner| interner.gensym(string))
     }
@@ -222,7 +228,7 @@ fn eq(&self, other: &T) -> bool {
     }
 }
 
-// The &'static strs in this type actually point into the arena
+// The `&'static str`s in this type actually point into the arena.
 #[derive(Default)]
 pub struct Interner {
     arena: DroplessArena,
@@ -236,7 +242,7 @@ fn prefill(init: &[&str]) -> Self {
         let mut this = Interner::default();
         for &string in init {
             if string == "" {
-                // We can't allocate empty strings in the arena, so handle this here
+                // We can't allocate empty strings in the arena, so handle this here.
                 let name = Symbol(this.strings.len() as u32);
                 this.names.insert("", name);
                 this.strings.push("");
@@ -254,12 +260,13 @@ pub fn intern(&mut self, string: &str) -> Symbol {
 
         let name = Symbol(self.strings.len() as u32);
 
-        // from_utf8_unchecked is safe since we just allocated a &str which is known to be utf8
+        // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
+        // UTF-8.
         let string: &str = unsafe {
             str::from_utf8_unchecked(self.arena.alloc_slice(string.as_bytes()))
         };
-        // It is safe to extend the arena allocation to 'static because we only access
-        // these while the arena is still alive
+        // It is safe to extend the arena allocation to `'static` because we only access
+        // these while the arena is still alive.
         let string: &'static str =  unsafe {
             &*(string as *const str)
         };
@@ -340,7 +347,7 @@ pub fn fresh() -> Self {
     }
 }}
 
-// NB: leaving holes in the ident table is bad! a different ident will get
+// N.B., leaving holes in the ident table is bad! a different ident will get
 // interned with the id from the hole, but it will be between the min and max
 // of the reserved words, and thus tagged as "reserved".
 // After modifying this list adjust `is_special`, `is_used_keyword`/`is_unused_keyword`,
@@ -349,11 +356,11 @@ pub fn fresh() -> Self {
     // Special reserved identifiers used internally for elided lifetimes,
     // unnamed method parameters, crate root module, error recovery etc.
     (0,  Invalid,            "")
-    (1,  CrateRoot,          "{{root}}")
+    (1,  PathRoot,           "{{root}}")
     (2,  DollarCrate,        "$crate")
     (3,  Underscore,         "_")
 
-    // Keywords used in the language.
+    // Keywords that are used in stable Rust.
     (4,  As,                 "as")
     (5,  Box,                "box")
     (6,  Break,              "break")
@@ -378,8 +385,8 @@ pub fn fresh() -> Self {
     (25, Pub,                "pub")
     (26, Ref,                "ref")
     (27, Return,             "return")
-    (28, SelfValue,          "self")
-    (29, SelfType,           "Self")
+    (28, SelfLower,          "self")
+    (29, SelfUpper,          "Self")
     (30, Static,             "static")
     (31, Struct,             "struct")
     (32, Super,              "super")
@@ -391,7 +398,7 @@ pub fn fresh() -> Self {
     (38, Where,              "where")
     (39, While,              "while")
 
-    // Keywords reserved for future use.
+    // Keywords that are used in unstable Rust or reserved for future use.
     (40, Abstract,           "abstract")
     (41, Become,             "become")
     (42, Do,                 "do")
@@ -404,9 +411,11 @@ pub fn fresh() -> Self {
     (49, Virtual,            "virtual")
     (50, Yield,              "yield")
 
-    // Edition-specific keywords reserved for future use.
-    (51, Async,              "async") // >= 2018 Edition only
-    (52, Dyn,                "dyn") // >= 2018 Edition only
+    // Edition-specific keywords that are used in stable Rust.
+    (51, Dyn,                "dyn") // >= 2018 Edition only
+
+    // Edition-specific keywords that are used in unstable Rust or reserved for future use.
+    (52, Async,              "async") // >= 2018 Edition only
     (53, Try,                "try") // >= 2018 Edition only
 
     // Special lifetime names
@@ -417,18 +426,22 @@ pub fn fresh() -> Self {
     (56, Auto,               "auto")
     (57, Catch,              "catch")
     (58, Default,            "default")
-    (59, Union,              "union")
-    (60, Existential,        "existential")
+    (59, Existential,        "existential")
+    (60, Union,              "union")
 }
 
 impl Symbol {
+    fn is_used_keyword_2018(self) -> bool {
+        self == keywords::Dyn.name()
+    }
+
     fn is_unused_keyword_2018(self) -> bool {
         self >= keywords::Async.name() && self <= keywords::Try.name()
     }
 }
 
 impl Ident {
-    // Returns true for reserved identifiers used internally for elided lifetimes,
+    // Returns `true` for reserved identifiers used internally for elided lifetimes,
     // unnamed method parameters, crate root module, error recovery etc.
     pub fn is_special(self) -> bool {
         self.name <= keywords::Underscore.name()
@@ -436,7 +449,9 @@ pub fn is_special(self) -> bool {
 
     /// Returns `true` if the token is a keyword used in the language.
     pub fn is_used_keyword(self) -> bool {
-        self.name >= keywords::As.name() && self.name <= keywords::While.name()
+        // Note: `span.edition()` is relatively expensive, don't call it unless necessary.
+        self.name >= keywords::As.name() && self.name <= keywords::While.name() ||
+        self.name.is_used_keyword_2018() && self.span.rust_2018()
     }
 
     /// Returns `true` if the token is a keyword reserved for possible future use.
@@ -454,18 +469,18 @@ pub fn is_reserved(self) -> bool {
     /// A keyword or reserved identifier that can be used as a path segment.
     pub fn is_path_segment_keyword(self) -> bool {
         self.name == keywords::Super.name() ||
-        self.name == keywords::SelfValue.name() ||
-        self.name == keywords::SelfType.name() ||
+        self.name == keywords::SelfLower.name() ||
+        self.name == keywords::SelfUpper.name() ||
         self.name == keywords::Extern.name() ||
         self.name == keywords::Crate.name() ||
-        self.name == keywords::CrateRoot.name() ||
+        self.name == keywords::PathRoot.name() ||
         self.name == keywords::DollarCrate.name()
     }
 
     // We see this identifier in a normal identifier position, like variable name or a type.
     // How was it written originally? Did it use the raw form? Let's try to guess.
     pub fn is_raw_guess(self) -> bool {
-        self.name != keywords::Invalid.name() &&
+        self.name != keywords::Invalid.name() && self.name != keywords::Underscore.name() &&
         self.is_reserved() && !self.is_path_segment_keyword()
     }
 }
@@ -479,8 +494,8 @@ fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
 /// Represents a string stored in the interner. Because the interner outlives any thread
 /// which uses this type, we can safely treat `string` which points to interner data,
 /// as an immortal string, as long as this type never crosses between threads.
-// FIXME: Ensure that the interner outlives any thread which uses LocalInternedString,
-//        by creating a new thread right after constructing the interner
+// FIXME: ensure that the interner outlives any thread which uses `LocalInternedString`,
+// by creating a new thread right after constructing the interner.
 #[derive(Clone, Copy, Hash, PartialOrd, Eq, Ord)]
 pub struct LocalInternedString {
     string: &'static str,
@@ -569,7 +584,7 @@ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
     }
 }
 
-/// Represents a string stored in the string interner
+/// Represents a string stored in the string interner.
 #[derive(Clone, Copy, Eq)]
 pub struct InternedString {
     symbol: Symbol,