From 9b3bc7a9e9e35537823bc2a10fc078c1222ee7fd Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Wed, 31 Aug 2016 23:39:16 +0000 Subject: [PATCH] Remove `syntax::config::strip_unconfigured`, add `syntax::config::features`. --- src/librustc_driver/driver.rs | 20 +++-------- src/libsyntax/config.rs | 63 +++++++++++++++++++---------------- src/libsyntax/ext/expand.rs | 5 +-- 3 files changed, 41 insertions(+), 47 deletions(-) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 065ef9e0ce15..8ed5b579ffc3 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, crate_name: &'a str, addl_plugins: Option>, @@ -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 69a979176521..7f6395997abe 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(&mut self, node: T) -> Option { 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 6f8af66632f0..92d053fd21b0 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);