diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2018-07-23 02:52:51 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2018-08-01 12:08:41 +0300 |
| commit | c3e54217e855a2492d9b707eb3fb7cdb6702d45a (patch) | |
| tree | 8ec77f793c09069edeaefd2e32a29e39488952b8 /src/libsyntax | |
| parent | c63bb1d6a7e7ede79ddc5ddf41087668266824ea (diff) | |
| download | rust-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.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 5 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 24 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 38 |
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)); } |
