about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-09-28 23:38:52 +0000
committerbors <bors@rust-lang.org>2017-09-28 23:38:52 +0000
commit46ef6208f8a3dd0629a9d6c592c2a980e52c9bee (patch)
tree30759c75386c4fb2dc2e3b082674312c95e7de4b
parent3c96d40d326b64f6a50f4a902051fe71c4acdc92 (diff)
parent0f97b6b73c647604ad08e475b68058f52c4951c4 (diff)
downloadrust-46ef6208f8a3dd0629a9d6c592c2a980e52c9bee.tar.gz
rust-46ef6208f8a3dd0629a9d6c592c2a980e52c9bee.zip
Auto merge of #44528 - tmnilsson:attr_proc_macro_cfg_process, r=jseyfried
Apply attr proc macros before cfg processing

Fixes #39336.
r? @jseyfried
-rw-r--r--src/libsyntax/ext/expand.rs39
-rw-r--r--src/test/run-pass-fulldeps/proc-macro/attr-cfg.rs39
-rw-r--r--src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-cfg.rs32
-rw-r--r--src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-attr-cfg.rs23
-rw-r--r--src/test/run-pass-fulldeps/proc-macro/derive-attr-cfg.rs27
5 files changed, 146 insertions, 14 deletions
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 68ddfdc404a..6e7a8203b61 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -308,7 +308,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                         err.emit();
                     }
 
-                    let item = item
+                    let item = self.fully_configure(item)
                         .map_attrs(|mut attrs| { attrs.retain(|a| a.path != "derive"); attrs });
                     let item_with_markers =
                         add_derived_markers(&mut self.cx, item.span(), &traits, item.clone());
@@ -400,6 +400,27 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         result
     }
 
+    fn fully_configure(&mut self, item: Annotatable) -> Annotatable {
+        let mut cfg = StripUnconfigured {
+            should_test: self.cx.ecfg.should_test,
+            sess: self.cx.parse_sess,
+            features: self.cx.ecfg.features,
+        };
+        // Since the item itself has already been configured by the InvocationCollector,
+        // we know that fold result vector will contain exactly one element
+        match item {
+            Annotatable::Item(item) => {
+                Annotatable::Item(cfg.fold_item(item).pop().unwrap())
+            }
+            Annotatable::TraitItem(item) => {
+                Annotatable::TraitItem(item.map(|item| cfg.fold_trait_item(item).pop().unwrap()))
+            }
+            Annotatable::ImplItem(item) => {
+                Annotatable::ImplItem(item.map(|item| cfg.fold_impl_item(item).pop().unwrap()))
+            }
+        }
+    }
+
     fn expand_invoc(&mut self, invoc: Invocation, ext: Rc<SyntaxExtension>) -> Expansion {
         let result = match invoc.kind {
             InvocationKind::Bang { .. } => self.expand_bang_invoc(invoc, ext),
@@ -740,15 +761,6 @@ struct InvocationCollector<'a, 'b: 'a> {
     monotonic: bool,
 }
 
-macro_rules! fully_configure {
-    ($this:ident, $node:ident, $noop_fold:ident) => {
-        match $noop_fold($node, &mut $this.cfg).pop() {
-            Some(node) => node,
-            None => return SmallVector::new(),
-        }
-    }
-}
-
 impl<'a, 'b> InvocationCollector<'a, 'b> {
     fn collect(&mut self, expansion_kind: ExpansionKind, kind: InvocationKind) -> Expansion {
         let mark = Mark::fresh(self.cx.current_expansion.mark);
@@ -900,7 +912,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
 
         let (attr, traits, mut item) = self.classify_item(item);
         if attr.is_some() || !traits.is_empty() {
-            let item = Annotatable::Item(fully_configure!(self, item, noop_fold_item));
+            let item = Annotatable::Item(item);
             return self.collect_attr(attr, traits, item, ExpansionKind::Items).make_items();
         }
 
@@ -974,8 +986,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
 
         let (attr, traits, item) = self.classify_item(item);
         if attr.is_some() || !traits.is_empty() {
-            let item =
-                Annotatable::TraitItem(P(fully_configure!(self, item, noop_fold_trait_item)));
+            let item = Annotatable::TraitItem(P(item));
             return self.collect_attr(attr, traits, item, ExpansionKind::TraitItems)
                 .make_trait_items()
         }
@@ -995,7 +1006,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
 
         let (attr, traits, item) = self.classify_item(item);
         if attr.is_some() || !traits.is_empty() {
-            let item = Annotatable::ImplItem(P(fully_configure!(self, item, noop_fold_impl_item)));
+            let item = Annotatable::ImplItem(P(item));
             return self.collect_attr(attr, traits, item, ExpansionKind::ImplItems)
                 .make_impl_items();
         }
diff --git a/src/test/run-pass-fulldeps/proc-macro/attr-cfg.rs b/src/test/run-pass-fulldeps/proc-macro/attr-cfg.rs
new file mode 100644
index 00000000000..5a28d756df5
--- /dev/null
+++ b/src/test/run-pass-fulldeps/proc-macro/attr-cfg.rs
@@ -0,0 +1,39 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:attr-cfg.rs
+// ignore-stage1
+// revisions: foo bar
+
+#![feature(proc_macro)]
+
+extern crate attr_cfg;
+use attr_cfg::attr_cfg;
+
+#[attr_cfg]
+fn outer() -> u8 {
+    #[cfg(foo)]
+    fn inner() -> u8 { 1 }
+
+    #[cfg(bar)]
+    fn inner() -> u8 { 2 }
+
+    inner()
+}
+
+#[cfg(foo)]
+fn main() {
+    assert_eq!(outer(), 1);
+}
+
+#[cfg(bar)]
+fn main() {
+    assert_eq!(outer(), 2);
+}
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-cfg.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-cfg.rs
new file mode 100644
index 00000000000..9145c46cfc7
--- /dev/null
+++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/attr-cfg.rs
@@ -0,0 +1,32 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// no-prefer-dynamic
+#![feature(proc_macro)]
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro_attribute]
+pub fn attr_cfg(args: TokenStream, input: TokenStream) -> TokenStream {
+    let input_str = input.to_string();
+
+    assert_eq!(input_str, "fn outer() -> u8 {
+    #[cfg(foo)]
+    fn inner() -> u8 { 1 }
+    #[cfg(bar)]
+    fn inner() -> u8 { 2 }
+    inner()
+}");
+
+    input
+}
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-attr-cfg.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-attr-cfg.rs
new file mode 100644
index 00000000000..787a4a470e2
--- /dev/null
+++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-attr-cfg.rs
@@ -0,0 +1,23 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// no-prefer-dynamic
+#![feature(proc_macro)]
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro_derive(Foo, attributes(foo))]
+pub fn derive(input: TokenStream) -> TokenStream {
+    assert!(!input.to_string().contains("#[cfg(any())]"));
+    "".parse().unwrap()
+}
diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-attr-cfg.rs b/src/test/run-pass-fulldeps/proc-macro/derive-attr-cfg.rs
new file mode 100644
index 00000000000..b94c45248da
--- /dev/null
+++ b/src/test/run-pass-fulldeps/proc-macro/derive-attr-cfg.rs
@@ -0,0 +1,27 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:derive-attr-cfg.rs
+// ignore-stage1
+
+#![feature(proc_macro)]
+
+extern crate derive_attr_cfg;
+use derive_attr_cfg::Foo;
+
+#[derive(Foo)]
+#[foo]
+struct S {
+    #[cfg(any())]
+    x: i32
+}
+
+fn main() {
+}