summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2019-04-03 02:43:49 +0200
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2019-04-15 07:23:01 +0200
commit10855a36b53d33aa2e4f8b98107ee54a0cca5e9c (patch)
treeeb06422719e2b2f7098d8b658f2ebd835eb04bb2 /src/libsyntax
parenta55f6be4286991437659acb8506466e8d637ac51 (diff)
downloadrust-10855a36b53d33aa2e4f8b98107ee54a0cca5e9c.tar.gz
rust-10855a36b53d33aa2e4f8b98107ee54a0cca5e9c.zip
Use a proc macro to declare preallocated symbols
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs6
-rw-r--r--src/libsyntax/attr/mod.rs21
-rw-r--r--src/libsyntax/feature_gate.rs28
3 files changed, 41 insertions, 14 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index cf909e30e32..c015e9b06ac 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -68,6 +68,12 @@ pub struct Path {
     pub segments: Vec<PathSegment>,
 }
 
+impl PartialEq<Symbol> for Path {
+    fn eq(&self, symbol: &Symbol) -> bool {
+        self.segments.len() == 1 && self.segments[0].ident.name.interned() == *symbol
+    }
+}
+
 impl<'a> PartialEq<&'a str> for Path {
     fn eq(&self, string: &&'a str) -> bool {
         self.segments.len() == 1 && self.segments[0].ident.name == *string
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index c0bd5c79b1d..f34bbc9f35d 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -85,6 +85,11 @@ impl NestedMetaItem {
         self.meta_item().map_or(false, |meta_item| meta_item.check_name(name))
     }
 
+    /// Returns `true` if this list item is a MetaItem with a name of `name`.
+    pub fn check_name_symbol(&self, name: Symbol) -> bool {
+        self.meta_item().map_or(false, |meta_item| meta_item.check_name_symbol(name))
+    }
+
     /// For a single-segment meta-item returns its name, otherwise returns `None`.
     pub fn ident(&self) -> Option<Ident> {
         self.meta_item().and_then(|meta_item| meta_item.ident())
@@ -159,6 +164,18 @@ impl Attribute {
         matches
     }
 
+    /// Returns `true` if the attribute's path matches the argument. If it matches, then the
+    /// attribute is marked as used.
+    ///
+    /// To check the attribute name without marking it used, use the `path` field directly.
+    pub fn check_name_symbol(&self, name: Symbol) -> bool {
+        let matches = self.path == name;
+        if matches {
+            mark_used(self);
+        }
+        matches
+    }
+
     /// For a single-segment attribute returns its name, otherwise returns `None`.
     pub fn ident(&self) -> Option<Ident> {
         if self.path.segments.len() == 1 {
@@ -248,6 +265,10 @@ impl MetaItem {
         self.path == name
     }
 
+    pub fn check_name_symbol(&self, name: Symbol) -> bool {
+        self.path == name
+    }
+
     pub fn is_value_str(&self) -> bool {
         self.value_str().is_some()
     }
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index f77593ed02a..b3e5d808a47 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -28,7 +28,7 @@ use crate::tokenstream::TokenTree;
 use errors::{DiagnosticBuilder, Handler};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_target::spec::abi::Abi;
-use syntax_pos::{Span, DUMMY_SP};
+use syntax_pos::{Span, DUMMY_SP, symbols};
 use log::debug;
 
 use std::env;
@@ -1366,7 +1366,7 @@ impl<'a> Context<'a> {
                     }
                 } else if n == "doc" {
                     if let Some(content) = attr.meta_item_list() {
-                        if content.iter().any(|c| c.check_name("include")) {
+                        if content.iter().any(|c| c.check_name_symbol(symbols::include)) {
                             gate_feature!(self, external_doc, attr.span,
                                 "#[doc(include = \"...\")] is experimental"
                             );
@@ -1667,25 +1667,25 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
         // check for gated attributes
         self.context.check_attribute(attr, false);
 
-        if attr.check_name("doc") {
+        if attr.check_name_symbol(symbols::doc) {
             if let Some(content) = attr.meta_item_list() {
-                if content.len() == 1 && content[0].check_name("cfg") {
+                if content.len() == 1 && content[0].check_name_symbol(symbols::cfg) {
                     gate_feature_post!(&self, doc_cfg, attr.span,
                         "#[doc(cfg(...))] is experimental"
                     );
-                } else if content.iter().any(|c| c.check_name("masked")) {
+                } else if content.iter().any(|c| c.check_name_symbol(symbols::masked)) {
                     gate_feature_post!(&self, doc_masked, attr.span,
                         "#[doc(masked)] is experimental"
                     );
-                } else if content.iter().any(|c| c.check_name("spotlight")) {
+                } else if content.iter().any(|c| c.check_name_symbol(symbols::spotlight)) {
                     gate_feature_post!(&self, doc_spotlight, attr.span,
                         "#[doc(spotlight)] is experimental"
                     );
-                } else if content.iter().any(|c| c.check_name("alias")) {
+                } else if content.iter().any(|c| c.check_name_symbol(symbols::alias)) {
                     gate_feature_post!(&self, doc_alias, attr.span,
                         "#[doc(alias = \"...\")] is experimental"
                     );
-                } else if content.iter().any(|c| c.check_name("keyword")) {
+                } else if content.iter().any(|c| c.check_name_symbol(symbols::keyword)) {
                     gate_feature_post!(&self, doc_keyword, attr.span,
                         "#[doc(keyword = \"...\")] is experimental"
                     );
@@ -1693,7 +1693,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
             }
         }
 
-        match BUILTIN_ATTRIBUTES.iter().find(|(name, ..)| attr.path == name) {
+        match BUILTIN_ATTRIBUTES.iter().find(|(name, ..)| attr.path == *name) {
             Some(&(name, _, template, _)) => self.check_builtin_attribute(attr, name, template),
             None => if let Some(TokenTree::Token(_, token::Eq)) = attr.tokens.trees().next() {
                 // All key-value attributes are restricted to meta-item syntax.
@@ -1748,7 +1748,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
             ast::ItemKind::Struct(..) => {
                 for attr in attr::filter_by_name(&i.attrs[..], "repr") {
                     for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
-                        if item.check_name("simd") {
+                        if item.check_name_symbol(symbols::simd) {
                             gate_feature_post!(&self, repr_simd, attr.span,
                                                "SIMD types are experimental and possibly buggy");
                         }
@@ -1759,7 +1759,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
             ast::ItemKind::Enum(..) => {
                 for attr in attr::filter_by_name(&i.attrs[..], "repr") {
                     for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
-                        if item.check_name("align") {
+                        if item.check_name_symbol(symbols::align) {
                             gate_feature_post!(&self, repr_align_enum, attr.span,
                                                "`#[repr(align(x))]` on enums is experimental");
                         }
@@ -2083,7 +2083,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
     // Process the edition umbrella feature-gates first, to ensure
     // `edition_enabled_features` is completed before it's queried.
     for attr in krate_attrs {
-        if !attr.check_name("feature") {
+        if !attr.check_name_symbol(symbols::feature) {
             continue
         }
 
@@ -2128,7 +2128,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
     }
 
     for attr in krate_attrs {
-        if !attr.check_name("feature") {
+        if !attr.check_name_symbol(symbols::feature) {
             continue
         }
 
@@ -2258,7 +2258,7 @@ fn maybe_stage_features(span_handler: &Handler, krate: &ast::Crate,
     };
     if !allow_features {
         for attr in &krate.attrs {
-            if attr.check_name("feature") {
+            if attr.check_name_symbol(symbols::feature) {
                 let release_channel = option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)");
                 span_err!(span_handler, attr.span, E0554,
                           "#![feature] may not be used on the {} release channel",