about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-11-08 09:01:33 +0000
committerbors <bors@rust-lang.org>2014-11-08 09:01:33 +0000
commitebc625ad3eaa2ee630c6c8203106826ad23abc98 (patch)
tree27b1d977d7431350799c5d8e1a35a85eb346c27a
parentafd657e20724f6a9093e34818c4923aa8601cafb (diff)
parent3dbd32854f6bdee94c98c5e3e5da58fb79d79fd9 (diff)
downloadrust-ebc625ad3eaa2ee630c6c8203106826ad23abc98.tar.gz
rust-ebc625ad3eaa2ee630c6c8203106826ad23abc98.zip
auto merge of #18634 : alexcrichton/rust/cfg-attr-crate-level, r=sfackler
This commit implements processing these two attributes at the crate level as
well as at the item level. When #[cfg] is applied at the crate level, then the
entire crate will be omitted if the cfg doesn't match. The #[cfg_attr] attribute
is processed as usual in that the attribute is included or not depending on
whether the cfg matches.

This was spurred on by motivations of #18585 where #[cfg_attr] annotations will
be applied at the crate-level.

cc #18585
-rw-r--r--src/librustc/driver/driver.rs10
-rw-r--r--src/libsyntax/config.rs23
-rw-r--r--src/libsyntax/fold.rs37
-rw-r--r--src/libsyntax/test.rs9
-rw-r--r--src/test/auxiliary/stability_cfg1.rs12
-rw-r--r--src/test/auxiliary/stability_cfg2.rs15
-rw-r--r--src/test/compile-fail/cfg-in-crate-1.rs13
-rw-r--r--src/test/compile-fail/lint-stability.rs5
-rw-r--r--src/test/run-make/graphviz-flowgraph/f03.dot-expected.dot8
-rw-r--r--src/test/run-make/graphviz-flowgraph/f03.rs2
-rw-r--r--src/test/run-pass/cfg-in-crate-1.rs16
11 files changed, 127 insertions, 23 deletions
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index d347f113af3..299ae9eb41d 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -212,11 +212,6 @@ pub fn phase_2_configure_and_expand(sess: &Session,
         *ty == config::CrateTypeExecutable
     });
 
-    krate = time(time_passes, "crate injection", krate, |krate|
-                 syntax::std_inject::maybe_inject_crates_ref(krate,
-                                                             sess.opts.alt_std_name.clone(),
-                                                             any_exe));
-
     // strip before expansion to allow macros to depend on
     // configuration variables e.g/ in
     //
@@ -228,6 +223,11 @@ pub fn phase_2_configure_and_expand(sess: &Session,
     krate = time(time_passes, "configuration 1", krate, |krate|
                  syntax::config::strip_unconfigured_items(sess.diagnostic(), krate));
 
+    krate = time(time_passes, "crate injection", krate, |krate|
+                 syntax::std_inject::maybe_inject_crates_ref(krate,
+                                                             sess.opts.alt_std_name.clone(),
+                                                             any_exe));
+
     let mut addl_plugins = Some(addl_plugins);
     let Plugins { macros, registrars }
         = time(time_passes, "plugin loading", (), |_|
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 72c62a173fc..257bfd69f43 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -15,6 +15,8 @@ use {ast, fold, attr};
 use codemap::Spanned;
 use ptr::P;
 
+use util::small_vector::SmallVector;
+
 /// A folder that strips out items that do not belong in the current
 /// configuration.
 struct Context<'a> {
@@ -47,6 +49,9 @@ impl<'a> fold::Folder for Context<'a> {
     fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
         fold::noop_fold_mac(mac, self)
     }
+    fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
+        fold_item(self, item)
+    }
 }
 
 pub fn strip_items(krate: ast::Crate,
@@ -72,13 +77,9 @@ fn fold_mod(cx: &mut Context, ast::Mod {inner, view_items, items}: ast::Mod) ->
         view_items: view_items.into_iter().filter_map(|a| {
             filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
         }).collect(),
-        items: items.into_iter().filter_map(|a| {
-            if item_in_cfg(cx, &*a) {
-                Some(cx.fold_item(a))
-            } else {
-                None
-            }
-        }).flat_map(|x| x.into_iter()).collect()
+        items: items.into_iter().flat_map(|a| {
+            cx.fold_item(a).into_iter()
+        }).collect()
     }
 }
 
@@ -104,6 +105,14 @@ fn fold_foreign_mod(cx: &mut Context, ast::ForeignMod {abi, view_items, items}:
     }
 }
 
+fn fold_item(cx: &mut Context, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
+    if item_in_cfg(cx, &*item) {
+        SmallVector::one(item.map(|i| cx.fold_item_simple(i)))
+    } else {
+        SmallVector::zero()
+    }
+}
+
 fn fold_item_underscore(cx: &mut Context, item: ast::Item_) -> ast::Item_ {
     let item = match item {
         ast::ItemImpl(a, b, c, impl_items) => {
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 2074a6bfab9..d977f2b99cc 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -1061,12 +1061,41 @@ pub fn noop_fold_mod<T: Folder>(Mod {inner, view_items, items}: Mod, folder: &mu
 
 pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, config, exported_macros, span}: Crate,
                                   folder: &mut T) -> Crate {
+    let config = folder.fold_meta_items(config);
+
+    let mut items = folder.fold_item(P(ast::Item {
+        ident: token::special_idents::invalid,
+        attrs: attrs,
+        id: ast::DUMMY_NODE_ID,
+        vis: ast::Public,
+        span: span,
+        node: ast::ItemMod(module),
+    })).into_iter();
+
+    let (module, attrs, span) = match items.next() {
+        Some(item) => {
+            assert!(items.next().is_none(),
+                    "a crate cannot expand to more than one item");
+            item.and_then(|ast::Item { attrs, span, node, .. }| {
+                match node {
+                    ast::ItemMod(m) => (m, attrs, span),
+                    _ => panic!("fold converted a module to not a module"),
+                }
+            })
+        }
+        None => (ast::Mod {
+            inner: span,
+            view_items: Vec::new(),
+            items: Vec::new(),
+        }, Vec::new(), span)
+    };
+
     Crate {
-        module: folder.fold_mod(module),
-        attrs: attrs.move_map(|x| folder.fold_attribute(x)),
-        config: folder.fold_meta_items(config),
+        module: module,
+        attrs: attrs,
+        config: config,
         exported_macros: exported_macros,
-        span: folder.new_span(span)
+        span: span,
     }
 }
 
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index a7db8e800a9..29637e88dd5 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -108,7 +108,10 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
     }
 
     fn fold_item(&mut self, i: P<ast::Item>) -> SmallVector<P<ast::Item>> {
-        self.cx.path.push(i.ident);
+        let ident = i.ident;
+        if ident.name != token::special_idents::invalid.name {
+            self.cx.path.push(ident);
+        }
         debug!("current path: {}",
                ast_util::path_name_i(self.cx.path.as_slice()));
 
@@ -143,7 +146,9 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
             ast::ItemMod(..) => fold::noop_fold_item(i, self),
             _ => SmallVector::one(i),
         };
-        self.cx.path.pop();
+        if ident.name != token::special_idents::invalid.name {
+            self.cx.path.pop();
+        }
         res
     }
 
diff --git a/src/test/auxiliary/stability_cfg1.rs b/src/test/auxiliary/stability_cfg1.rs
new file mode 100644
index 00000000000..6b2e8e7758f
--- /dev/null
+++ b/src/test/auxiliary/stability_cfg1.rs
@@ -0,0 +1,12 @@
+// Copyright 2014 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.
+
+#![cfg_attr(foo, experimental)]
+#![cfg_attr(not(foo), stable)]
diff --git a/src/test/auxiliary/stability_cfg2.rs b/src/test/auxiliary/stability_cfg2.rs
new file mode 100644
index 00000000000..3387b319abf
--- /dev/null
+++ b/src/test/auxiliary/stability_cfg2.rs
@@ -0,0 +1,15 @@
+// Copyright 2014 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.
+
+// compile-flags:--cfg foo
+
+#![cfg_attr(foo, experimental)]
+#![cfg_attr(not(foo), stable)]
+
diff --git a/src/test/compile-fail/cfg-in-crate-1.rs b/src/test/compile-fail/cfg-in-crate-1.rs
new file mode 100644
index 00000000000..94ae8d89b4f
--- /dev/null
+++ b/src/test/compile-fail/cfg-in-crate-1.rs
@@ -0,0 +1,13 @@
+// Copyright 2014 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.
+
+// error-pattern:main function not found
+
+#![cfg(bar)]
diff --git a/src/test/compile-fail/lint-stability.rs b/src/test/compile-fail/lint-stability.rs
index 2074d007502..483a3b6d667 100644
--- a/src/test/compile-fail/lint-stability.rs
+++ b/src/test/compile-fail/lint-stability.rs
@@ -10,6 +10,8 @@
 
 // aux-build:lint_stability.rs
 // aux-build:inherited_stability.rs
+// aux-build:stability_cfg1.rs
+// aux-build:stability_cfg2.rs
 
 #![feature(globs, phase)]
 #![deny(unstable)]
@@ -18,6 +20,9 @@
 #![allow(dead_code)]
 
 mod cross_crate {
+    extern crate stability_cfg1;
+    extern crate stability_cfg2; //~ ERROR: use of experimental item
+
     #[phase(plugin, link)]
     extern crate lint_stability; //~ ERROR: use of unmarked item
     use self::lint_stability::*;
diff --git a/src/test/run-make/graphviz-flowgraph/f03.dot-expected.dot b/src/test/run-make/graphviz-flowgraph/f03.dot-expected.dot
index e60d349ad14..1986c27ad43 100644
--- a/src/test/run-make/graphviz-flowgraph/f03.dot-expected.dot
+++ b/src/test/run-make/graphviz-flowgraph/f03.dot-expected.dot
@@ -2,10 +2,10 @@ digraph block {
     N0[label="entry"];
     N1[label="exit"];
     N2[label="expr 3i"];
-    N3[label="expr 33i"];
-    N4[label="expr 3i + 33i"];
-    N5[label="stmt 3i + 33i;"];
-    N6[label="block { 3i + 33i; }"];
+    N3[label="expr 4"];
+    N4[label="expr 3i + 4"];
+    N5[label="stmt 3i + 4;"];
+    N6[label="block { 3i + 4; }"];
     N0 -> N2;
     N2 -> N3;
     N3 -> N4;
diff --git a/src/test/run-make/graphviz-flowgraph/f03.rs b/src/test/run-make/graphviz-flowgraph/f03.rs
index 1007225f2f2..051409a49b1 100644
--- a/src/test/run-make/graphviz-flowgraph/f03.rs
+++ b/src/test/run-make/graphviz-flowgraph/f03.rs
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 pub fn expr_add_3() {
-    3i + 33i;
+    3i + 4;
 }
diff --git a/src/test/run-pass/cfg-in-crate-1.rs b/src/test/run-pass/cfg-in-crate-1.rs
new file mode 100644
index 00000000000..06f679b7fca
--- /dev/null
+++ b/src/test/run-pass/cfg-in-crate-1.rs
@@ -0,0 +1,16 @@
+// Copyright 2014 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.
+
+// compile-flags: --cfg bar -D warnings
+// ignore-pretty
+
+#![cfg(bar)]
+
+fn main() {}