about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-07-23 02:52:51 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-08-01 12:08:41 +0300
commitc3e54217e855a2492d9b707eb3fb7cdb6702d45a (patch)
tree8ec77f793c09069edeaefd2e32a29e39488952b8 /src/libsyntax
parentc63bb1d6a7e7ede79ddc5ddf41087668266824ea (diff)
downloadrust-c3e54217e855a2492d9b707eb3fb7cdb6702d45a.tar.gz
rust-c3e54217e855a2492d9b707eb3fb7cdb6702d45a.zip
resolve: Implement prelude search for macro paths
resolve/expansion: Implement tool attributes
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/attr/mod.rs15
-rw-r--r--src/libsyntax/ext/base.rs5
-rw-r--r--src/libsyntax/ext/expand.rs24
-rw-r--r--src/libsyntax/feature_gate.rs38
4 files changed, 41 insertions, 41 deletions
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index 137b94230a3..938fd2767c9 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -89,17 +89,8 @@ pub fn is_known(attr: &Attribute) -> bool {
     })
 }
 
-const RUST_KNOWN_TOOL: &[&str] = &["clippy", "rustfmt"];
-const RUST_KNOWN_LINT_TOOL: &[&str] = &["clippy"];
-
-pub fn is_known_tool(attr: &Attribute) -> bool {
-    let tool_name =
-        attr.path.segments.iter().next().expect("empty path in attribute").ident.name;
-    RUST_KNOWN_TOOL.contains(&tool_name.as_str().as_ref())
-}
-
 pub fn is_known_lint_tool(m_item: Ident) -> bool {
-    RUST_KNOWN_LINT_TOOL.contains(&m_item.as_str().as_ref())
+    ["clippy"].contains(&m_item.as_str().as_ref())
 }
 
 impl NestedMetaItem {
@@ -245,10 +236,6 @@ impl Attribute {
     pub fn is_value_str(&self) -> bool {
         self.value_str().is_some()
     }
-
-    pub fn is_scoped(&self) -> bool {
-        self.path.segments.len() > 1
-    }
 }
 
 impl MetaItem {
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index b55c4f99206..8450daa3f7c 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -588,6 +588,9 @@ impl MacroKind {
 
 /// An enum representing the different kinds of syntax extensions.
 pub enum SyntaxExtension {
+    /// A trivial "extension" that does nothing, only keeps the attribute and marks it as known.
+    NonMacroAttr,
+
     /// A syntax extension that is attached to an item and creates new items
     /// based upon it.
     ///
@@ -667,6 +670,7 @@ impl SyntaxExtension {
             SyntaxExtension::IdentTT(..) |
             SyntaxExtension::ProcMacro { .. } =>
                 MacroKind::Bang,
+            SyntaxExtension::NonMacroAttr |
             SyntaxExtension::MultiDecorator(..) |
             SyntaxExtension::MultiModifier(..) |
             SyntaxExtension::AttrProcMacro(..) =>
@@ -696,6 +700,7 @@ impl SyntaxExtension {
             SyntaxExtension::AttrProcMacro(.., edition) |
             SyntaxExtension::ProcMacroDerive(.., edition) => edition,
             // Unstable legacy stuff
+            SyntaxExtension::NonMacroAttr |
             SyntaxExtension::IdentTT(..) |
             SyntaxExtension::MultiDecorator(..) |
             SyntaxExtension::MultiModifier(..) |
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 9f8909e1626..1fd77045a45 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -36,7 +36,7 @@ use visit::{self, Visitor};
 use std::collections::HashMap;
 use std::fs::File;
 use std::io::Read;
-use std::mem;
+use std::{iter, mem};
 use std::rc::Rc;
 use std::path::PathBuf;
 
@@ -243,6 +243,15 @@ impl Invocation {
         }
     }
 
+    pub fn path_span(&self) -> Span {
+        match self.kind {
+            InvocationKind::Bang { ref mac, .. } => mac.node.path.span,
+            InvocationKind::Attr { attr: Some(ref attr), .. } => attr.path.span,
+            InvocationKind::Attr { attr: None, .. } => DUMMY_SP,
+            InvocationKind::Derive { ref path, .. } => path.span,
+        }
+    }
+
     pub fn attr_id(&self) -> Option<ast::AttrId> {
         match self.kind {
             InvocationKind::Attr { attr: Some(ref attr), .. } => Some(attr.id),
@@ -566,6 +575,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         });
 
         match *ext {
+            NonMacroAttr => {
+                attr::mark_known(&attr);
+                let item = item.map_attrs(|mut attrs| { attrs.push(attr); attrs });
+                Some(invoc.fragment_kind.expect_from_annotatables(iter::once(item)))
+            }
             MultiModifier(ref mac) => {
                 let meta = attr.parse_meta(self.cx.parse_sess)
                                .map_err(|mut e| { e.emit(); }).ok()?;
@@ -810,7 +824,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 }
             }
 
-            MultiDecorator(..) | MultiModifier(..) | AttrProcMacro(..) => {
+            MultiDecorator(..) | MultiModifier(..) |
+            AttrProcMacro(..) | SyntaxExtension::NonMacroAttr => {
                 self.cx.span_err(path.span,
                                  &format!("`{}` can only be used in attributes", path));
                 self.cx.trace_macros_diag();
@@ -1612,13 +1627,16 @@ impl<'feat> ExpansionConfig<'feat> {
         fn enable_allow_internal_unstable = allow_internal_unstable,
         fn enable_custom_derive = custom_derive,
         fn enable_format_args_nl = format_args_nl,
-        fn use_extern_macros_enabled = use_extern_macros,
         fn macros_in_extern_enabled = macros_in_extern,
         fn proc_macro_mod = proc_macro_mod,
         fn proc_macro_gen = proc_macro_gen,
         fn proc_macro_expr = proc_macro_expr,
         fn proc_macro_non_items = proc_macro_non_items,
     }
+
+    pub fn use_extern_macros_enabled(&self) -> bool {
+        self.features.map_or(false, |features| features.use_extern_macros())
+    }
 }
 
 // A Marker adds the given mark to the syntax context.
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 40fb2c69e57..747cf3f1654 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -80,6 +80,11 @@ macro_rules! declare_features {
             {
                 $(f(stringify!($feature), self.$feature);)+
             }
+
+            pub fn use_extern_macros(&self) -> bool {
+                // The `decl_macro` and `tool_attributes` features imply `use_extern_macros`.
+                self.use_extern_macros || self.decl_macro || self.tool_attributes
+            }
         }
     };
 
@@ -689,6 +694,10 @@ pub fn deprecated_attributes() -> Vec<&'static (&'static str, AttributeType, Att
     BUILTIN_ATTRIBUTES.iter().filter(|a| a.2.is_deprecated()).collect()
 }
 
+pub fn is_builtin_attr_name(name: ast::Name) -> bool {
+    BUILTIN_ATTRIBUTES.iter().any(|&(builtin_name, _, _)| name == builtin_name)
+}
+
 pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
     BUILTIN_ATTRIBUTES.iter().any(|&(builtin_name, _, _)| attr.check_name(builtin_name)) ||
     attr.name().as_str().starts_with("rustc_")
@@ -1198,28 +1207,9 @@ impl<'a> Context<'a> {
             // before the plugin attributes are registered
             // so we skip this then
             if !is_macro {
-                if attr.is_scoped() {
-                    gate_feature!(self, tool_attributes, attr.span,
-                                  &format!("scoped attribute `{}` is experimental", attr.path));
-                    if attr::is_known_tool(attr) {
-                        attr::mark_used(attr);
-                    } else {
-                        span_err!(
-                            self.parse_sess.span_diagnostic,
-                            attr.span,
-                            E0694,
-                            "an unknown tool name found in scoped attribute: `{}`.",
-                            attr.path
-                        );
-                    }
-                } else {
-                    gate_feature!(self, custom_attribute, attr.span,
-                                  &format!("The attribute `{}` is currently \
-                                            unknown to the compiler and \
-                                            may have meaning \
-                                            added to it in the future",
-                                           attr.path));
-                }
+                let msg = format!("The attribute `{}` is currently unknown to the compiler and \
+                                   may have meaning added to it in the future", attr.path);
+                gate_feature!(self, custom_attribute, attr.span, &msg);
             }
         }
     }
@@ -1529,7 +1519,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
             }
         }
 
-        if self.context.features.use_extern_macros && attr::is_known(attr) {
+        if self.context.features.use_extern_macros() && attr::is_known(attr) {
             return
         }
 
@@ -2004,7 +1994,7 @@ impl FeatureChecker {
     // the branching can be eliminated by modifying `set!()` to set these spans
     // only for the features that need to be checked for mutual exclusion.
     fn collect(&mut self, features: &Features, span: Span) {
-        if features.use_extern_macros {
+        if features.use_extern_macros() {
             // If self.use_extern_macros is None, set to Some(span)
             self.use_extern_macros = self.use_extern_macros.or(Some(span));
         }