diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2018-08-04 00:25:45 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2018-08-06 23:21:18 +0300 |
| commit | f60d96a4773db747aef75014ef6b41b39ae92372 (patch) | |
| tree | 1d90abf7907b1f9a687d6a4687b56cd86b917f79 /src/libsyntax | |
| parent | c84562e019e3061c79879487ace098a652d19490 (diff) | |
| download | rust-f60d96a4773db747aef75014ef6b41b39ae92372.tar.gz rust-f60d96a4773db747aef75014ef6b41b39ae92372.zip | |
Support custom attributes when macro modularization is enabled
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 22 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 47 |
3 files changed, 27 insertions, 54 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 1bc5cb93c11..de391ee4219 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -589,7 +589,7 @@ 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, + NonMacroAttr { mark_used: bool }, /// A syntax extension that is attached to an item and creates new items /// based upon it. @@ -670,7 +670,7 @@ impl SyntaxExtension { SyntaxExtension::IdentTT(..) | SyntaxExtension::ProcMacro { .. } => MacroKind::Bang, - SyntaxExtension::NonMacroAttr | + SyntaxExtension::NonMacroAttr { .. } | SyntaxExtension::MultiDecorator(..) | SyntaxExtension::MultiModifier(..) | SyntaxExtension::AttrProcMacro(..) => @@ -700,7 +700,7 @@ impl SyntaxExtension { SyntaxExtension::AttrProcMacro(.., edition) | SyntaxExtension::ProcMacroDerive(.., edition) => edition, // Unstable legacy stuff - SyntaxExtension::NonMacroAttr | + SyntaxExtension::NonMacroAttr { .. } | SyntaxExtension::IdentTT(..) | SyntaxExtension::MultiDecorator(..) | SyntaxExtension::MultiModifier(..) | @@ -739,6 +739,12 @@ pub enum Determinacy { Undetermined, } +impl Determinacy { + pub fn determined(determined: bool) -> Determinacy { + if determined { Determinacy::Determined } else { Determinacy::Undetermined } + } +} + pub struct DummyResolver; impl Resolver for DummyResolver { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 7148f3c00f2..72e0abfea8b 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -244,12 +244,12 @@ impl Invocation { } } - pub fn path_span(&self) -> Span { + pub fn path(&self) -> Option<&Path> { 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, + InvocationKind::Bang { ref mac, .. } => Some(&mac.node.path), + InvocationKind::Attr { attr: Some(ref attr), .. } => Some(&attr.path), + InvocationKind::Attr { attr: None, .. } => None, + InvocationKind::Derive { ref path, .. } => Some(path), } } } @@ -548,7 +548,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> { _ => unreachable!(), }; - attr::mark_used(&attr); + if let NonMacroAttr { mark_used: false } = *ext {} else { + attr::mark_used(&attr); + } invoc.expansion_data.mark.set_expn_info(ExpnInfo { call_site: attr.span, def_site: None, @@ -560,7 +562,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }); match *ext { - NonMacroAttr => { + 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))) @@ -810,7 +812,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } MultiDecorator(..) | MultiModifier(..) | - AttrProcMacro(..) | SyntaxExtension::NonMacroAttr => { + AttrProcMacro(..) | SyntaxExtension::NonMacroAttr { .. } => { self.cx.span_err(path.span, &format!("`{}` can only be used in attributes", path)); self.cx.trace_macros_diag(); @@ -1487,7 +1489,8 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { }; if attr.is_some() || !traits.is_empty() { - if !self.cx.ecfg.macros_in_extern_enabled() { + if !self.cx.ecfg.macros_in_extern_enabled() && + !self.cx.ecfg.custom_attribute_enabled() { if let Some(ref attr) = attr { emit_feature_err(&self.cx.parse_sess, "macros_in_extern", attr.span, GateIssue::Language, explain); @@ -1668,6 +1671,7 @@ impl<'feat> ExpansionConfig<'feat> { fn enable_custom_derive = custom_derive, fn enable_format_args_nl = format_args_nl, fn macros_in_extern_enabled = macros_in_extern, + fn custom_attribute_enabled = custom_attribute, fn proc_macro_mod = proc_macro_mod, fn proc_macro_gen = proc_macro_gen, fn proc_macro_expr = proc_macro_expr, diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 193e560893f..3f4ee834256 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -32,7 +32,7 @@ use attr; use codemap::Spanned; use edition::{ALL_EDITIONS, Edition}; use syntax_pos::{Span, DUMMY_SP}; -use errors::{DiagnosticBuilder, Handler, FatalError}; +use errors::{DiagnosticBuilder, Handler}; use visit::{self, FnKind, Visitor}; use parse::ParseSess; use symbol::{keywords, Symbol}; @@ -83,8 +83,10 @@ macro_rules! declare_features { } 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 + // The `decl_macro`, `tool_attributes` and `custom_attributes` + // features imply `use_extern_macros`. + self.use_extern_macros || self.decl_macro || + self.tool_attributes || self.custom_attribute } } }; @@ -1898,9 +1900,6 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], } let mut features = Features::new(); - - let mut feature_checker = FeatureChecker::default(); - let mut edition_enabled_features = FxHashMap(); for &(name, .., f_edition, set) in ACTIVE_FEATURES.iter() { @@ -1989,45 +1988,9 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], } } - feature_checker.check(span_handler); - features } -/// A collector for mutually exclusive and interdependent features and their flag spans. -#[derive(Default)] -struct FeatureChecker { - use_extern_macros: Option<Span>, - custom_attribute: Option<Span>, -} - -impl FeatureChecker { - // If this method turns out to be a hotspot due to branching, - // 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 self.use_extern_macros is None, set to Some(span) - self.use_extern_macros = self.use_extern_macros.or(Some(span)); - } - - if features.custom_attribute { - self.custom_attribute = self.custom_attribute.or(Some(span)); - } - } - - fn check(self, handler: &Handler) { - if let (Some(pm_span), Some(ca_span)) = (self.use_extern_macros, self.custom_attribute) { - handler.struct_span_err(pm_span, "Cannot use `#![feature(use_extern_macros)]` and \ - `#![feature(custom_attribute)] at the same time") - .span_note(ca_span, "`#![feature(custom_attribute)]` declared here") - .emit(); - - FatalError.raise(); - } - } -} - pub fn check_crate(krate: &ast::Crate, sess: &ParseSess, features: &Features, |
