Remove syntax::config::strip_unconfigured, add syntax::config::features.

This commit is contained in:
Jeffrey Seyfried 2016-08-31 23:39:16 +00:00
parent 234d68b7d3
commit 9b3bc7a9e9
3 changed files with 41 additions and 47 deletions

View file

@ -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() =

View file

@ -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 {

View file

@ -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);