about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-08-31 23:39:16 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-09-05 04:53:16 +0000
commit9b3bc7a9e9e35537823bc2a10fc078c1222ee7fd (patch)
tree1698bab31e5af0348bbb99f1a2def0b9262be3c0
parent234d68b7d35687999c36bc39ffd414bca7373a48 (diff)
downloadrust-9b3bc7a9e9e35537823bc2a10fc078c1222ee7fd.tar.gz
rust-9b3bc7a9e9e35537823bc2a10fc078c1222ee7fd.zip
Remove `syntax::config::strip_unconfigured`, add `syntax::config::features`.
-rw-r--r--src/librustc_driver/driver.rs20
-rw-r--r--src/libsyntax/config.rs63
-rw-r--r--src/libsyntax/ext/expand.rs5
3 files changed, 41 insertions, 47 deletions
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 065ef9e0ce1..8ed5b579ffc 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -551,7 +551,7 @@ pub struct ExpansionResult<'a> {
 /// Returns `None` if we're aborting after handling -W help.
 pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
                                            cstore: &CStore,
-                                           mut krate: ast::Crate,
+                                           krate: ast::Crate,
                                            registry: Option<Registry>,
                                            crate_name: &'a str,
                                            addl_plugins: Option<Vec<String>>,
@@ -562,21 +562,9 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
 {
     let time_passes = sess.time_passes();
 
-    // strip before anything else because crate metadata may use #[cfg_attr]
-    // and so macros can depend on configuration variables, such as
-    //
-    //   #[macro_use] #[cfg(foo)]
-    //   mod bar { macro_rules! baz!(() => {{}}) }
-    //
-    // baz! should not use this definition unless foo is enabled.
-
-    krate = time(time_passes, "configuration", || {
-        let (krate, features) =
-            syntax::config::strip_unconfigured_items(krate, &sess.parse_sess, sess.opts.test);
-        // these need to be set "early" so that expansion sees `quote` if enabled.
-        *sess.features.borrow_mut() = features;
-        krate
-    });
+    let (mut krate, features) = syntax::config::features(krate, &sess.parse_sess, sess.opts.test);
+    // these need to be set "early" so that expansion sees `quote` if enabled.
+    *sess.features.borrow_mut() = features;
 
     *sess.crate_types.borrow_mut() = collect_crate_types(sess, &krate.attrs);
     *sess.crate_disambiguator.borrow_mut() =
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 69a97917652..7f6395997ab 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -10,7 +10,6 @@
 
 use attr::HasAttrs;
 use feature_gate::{emit_feature_err, EXPLAIN_STMT_ATTR_SYNTAX, Features, get_features, GateIssue};
-use fold::Folder;
 use {fold, attr};
 use ast;
 use codemap::{Spanned, respan};
@@ -27,6 +26,40 @@ pub struct StripUnconfigured<'a> {
     pub features: Option<&'a Features>,
 }
 
+// `cfg_attr`-process the crate's attributes and compute the crate's features.
+pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool)
+                -> (ast::Crate, Features) {
+    let features;
+    {
+        let mut strip_unconfigured = StripUnconfigured {
+            config: &krate.config.clone(),
+            should_test: should_test,
+            sess: sess,
+            features: None,
+        };
+
+        let unconfigured_attrs = krate.attrs.clone();
+        let err_count = sess.span_diagnostic.err_count();
+        if let Some(attrs) = strip_unconfigured.configure(krate.attrs) {
+            krate.attrs = attrs;
+        } else { // the entire crate is unconfigured
+            krate.attrs = Vec::new();
+            krate.module.items = Vec::new();
+            return (krate, Features::new());
+        }
+
+        features = get_features(&sess.span_diagnostic, &krate.attrs);
+
+        // Avoid reconfiguring malformed `cfg_attr`s
+        if err_count == sess.span_diagnostic.err_count() {
+            strip_unconfigured.features = Some(&features);
+            strip_unconfigured.configure(unconfigured_attrs);
+        }
+    }
+
+    (krate, features)
+}
+
 impl<'a> StripUnconfigured<'a> {
     fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
         let node = self.process_cfg_attrs(node);
@@ -125,34 +158,6 @@ impl<'a> StripUnconfigured<'a> {
     }
 }
 
-// Support conditional compilation by transforming the AST, stripping out
-// any items that do not belong in the current configuration
-pub fn strip_unconfigured_items(mut krate: ast::Crate, sess: &ParseSess, should_test: bool)
-                                -> (ast::Crate, Features) {
-    let features;
-    {
-        let mut strip_unconfigured = StripUnconfigured {
-            config: &krate.config.clone(),
-            should_test: should_test,
-            sess: sess,
-            features: None,
-        };
-
-        let err_count = sess.span_diagnostic.err_count();
-        let krate_attrs = strip_unconfigured.configure(krate.attrs.clone()).unwrap_or_default();
-        features = get_features(&sess.span_diagnostic, &krate_attrs);
-        if err_count < sess.span_diagnostic.err_count() {
-            krate.attrs = krate_attrs.clone(); // Avoid reconfiguring malformed `cfg_attr`s
-        }
-
-        strip_unconfigured.features = Some(&features);
-        krate = strip_unconfigured.fold_crate(krate);
-        krate.attrs = krate_attrs;
-    }
-
-    (krate, features)
-}
-
 impl<'a> fold::Folder for StripUnconfigured<'a> {
     fn fold_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod {
         ast::ForeignMod {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 6f8af66632f..92d053fd21b 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -719,8 +719,9 @@ pub fn expand_crate_with_expander(expander: &mut MacroExpander,
     }
 
     let items = SmallVector::many(c.module.items);
-    expander.load_macros(&items);
-    c.module.items = items.into();
+    let configured = items.fold_with(&mut expander.strip_unconfigured());
+    expander.load_macros(&configured);
+    c.module.items = configured.into();
 
     let err_count = expander.cx.parse_sess.span_diagnostic.err_count();
     let mut ret = expander.fold_crate(c);