Strip unconfigured items during macro expansion
This commit is contained in:
parent
25c733360b
commit
1aa34e0b5f
3 changed files with 45 additions and 17 deletions
|
@ -720,16 +720,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
|
||||||
ret
|
ret
|
||||||
});
|
});
|
||||||
|
|
||||||
// JBC: make CFG processing part of expansion to avoid this problem:
|
|
||||||
|
|
||||||
// strip again, in case expansion added anything with a #[cfg].
|
|
||||||
krate = sess.track_errors(|| {
|
krate = sess.track_errors(|| {
|
||||||
let krate = time(time_passes, "configuration 2", || {
|
|
||||||
syntax::config::strip_unconfigured_items(sess.diagnostic(),
|
|
||||||
krate,
|
|
||||||
&mut feature_gated_cfgs)
|
|
||||||
});
|
|
||||||
|
|
||||||
time(time_passes, "gated configuration checking", || {
|
time(time_passes, "gated configuration checking", || {
|
||||||
let features = sess.features.borrow();
|
let features = sess.features.borrow();
|
||||||
feature_gated_cfgs.sort();
|
feature_gated_cfgs.sort();
|
||||||
|
|
|
@ -38,6 +38,16 @@ pub struct StripUnconfigured<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> StripUnconfigured<'a> {
|
impl<'a> StripUnconfigured<'a> {
|
||||||
|
pub fn new(config: &'a ast::CrateConfig,
|
||||||
|
diagnostic: &'a Handler,
|
||||||
|
feature_gated_cfgs: &'a mut Vec<GatedCfgAttr>)
|
||||||
|
-> Self {
|
||||||
|
StripUnconfigured {
|
||||||
|
config: config,
|
||||||
|
diag: CfgDiagReal { diag: diagnostic, feature_gated_cfgs: feature_gated_cfgs },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
|
fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
|
||||||
if !attr.check_name("cfg_attr") {
|
if !attr.check_name("cfg_attr") {
|
||||||
return Some(attr);
|
return Some(attr);
|
||||||
|
@ -121,13 +131,8 @@ pub fn strip_unconfigured_items(diagnostic: &Handler, krate: ast::Crate,
|
||||||
feature_gated_cfgs: &mut Vec<GatedCfgAttr>)
|
feature_gated_cfgs: &mut Vec<GatedCfgAttr>)
|
||||||
-> ast::Crate
|
-> ast::Crate
|
||||||
{
|
{
|
||||||
StripUnconfigured {
|
let config = &krate.config.clone();
|
||||||
config: &krate.config.clone(),
|
StripUnconfigured::new(config, diagnostic, feature_gated_cfgs).fold_crate(krate)
|
||||||
diag: CfgDiagReal {
|
|
||||||
diag: diagnostic,
|
|
||||||
feature_gated_cfgs: feature_gated_cfgs,
|
|
||||||
},
|
|
||||||
}.fold_crate(krate)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: CfgFolder> fold::Folder for T {
|
impl<T: CfgFolder> fold::Folder for T {
|
||||||
|
|
|
@ -19,6 +19,7 @@ use attr;
|
||||||
use attr::{AttrMetaMethods, WithAttrs, ThinAttributesExt};
|
use attr::{AttrMetaMethods, WithAttrs, ThinAttributesExt};
|
||||||
use codemap;
|
use codemap;
|
||||||
use codemap::{Span, Spanned, ExpnInfo, ExpnId, NameAndSpan, MacroBang, MacroAttribute};
|
use codemap::{Span, Spanned, ExpnInfo, ExpnId, NameAndSpan, MacroBang, MacroAttribute};
|
||||||
|
use config::StripUnconfigured;
|
||||||
use ext::base::*;
|
use ext::base::*;
|
||||||
use feature_gate::{self, Features};
|
use feature_gate::{self, Features};
|
||||||
use fold;
|
use fold;
|
||||||
|
@ -76,6 +77,17 @@ impl_macro_generable! {
|
||||||
"statement", .make_stmts, lift .fold_stmt, |_span| SmallVector::zero();
|
"statement", .make_stmts, lift .fold_stmt, |_span| SmallVector::zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MacroGenerable for Option<P<ast::Expr>> {
|
||||||
|
fn kind_name() -> &'static str { "expression" }
|
||||||
|
fn dummy(_span: Span) -> Self { None }
|
||||||
|
fn make_with<'a>(result: Box<MacResult + 'a>) -> Option<Self> {
|
||||||
|
result.make_expr().map(Some)
|
||||||
|
}
|
||||||
|
fn fold_with<F: Folder>(self, folder: &mut F) -> Self {
|
||||||
|
self.and_then(|expr| folder.fold_opt_expr(expr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
|
pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
|
||||||
return e.and_then(|ast::Expr {id, node, span, attrs}| match node {
|
return e.and_then(|ast::Expr {id, node, span, attrs}| match node {
|
||||||
|
|
||||||
|
@ -322,7 +334,8 @@ fn expand_mac_invoc<T>(mac: ast::Mac, ident: Option<Ident>, attrs: Vec<ast::Attr
|
||||||
};
|
};
|
||||||
|
|
||||||
let marked = expanded.fold_with(&mut Marker { mark: mark, expn_id: Some(fld.cx.backtrace()) });
|
let marked = expanded.fold_with(&mut Marker { mark: mark, expn_id: Some(fld.cx.backtrace()) });
|
||||||
let fully_expanded = marked.fold_with(fld);
|
let configured = marked.fold_with(&mut fld.strip_unconfigured());
|
||||||
|
let fully_expanded = configured.fold_with(fld);
|
||||||
fld.cx.bt_pop();
|
fld.cx.bt_pop();
|
||||||
fully_expanded
|
fully_expanded
|
||||||
}
|
}
|
||||||
|
@ -987,6 +1000,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
pub fn new(cx: &'a mut ExtCtxt<'b>) -> MacroExpander<'a, 'b> {
|
pub fn new(cx: &'a mut ExtCtxt<'b>) -> MacroExpander<'a, 'b> {
|
||||||
MacroExpander { cx: cx }
|
MacroExpander { cx: cx }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn strip_unconfigured(&mut self) -> StripUnconfigured {
|
||||||
|
StripUnconfigured::new(&self.cx.cfg,
|
||||||
|
&self.cx.parse_sess.span_diagnostic,
|
||||||
|
self.cx.feature_gated_cfgs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
|
impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
|
||||||
|
@ -999,6 +1018,19 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
|
||||||
expand_expr(expr, self)
|
expand_expr(expr, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fold_opt_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
|
||||||
|
match expr.node {
|
||||||
|
ast::ExprKind::Mac(_) => {}
|
||||||
|
_ => return Some(expand_expr(expr, self)),
|
||||||
|
}
|
||||||
|
|
||||||
|
expr.and_then(|ast::Expr {node, span, attrs, ..}| match node {
|
||||||
|
ast::ExprKind::Mac(mac) =>
|
||||||
|
expand_mac_invoc(mac, None, attrs.into_attr_vec(), span, self),
|
||||||
|
_ => unreachable!(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn fold_pat(&mut self, pat: P<ast::Pat>) -> P<ast::Pat> {
|
fn fold_pat(&mut self, pat: P<ast::Pat>) -> P<ast::Pat> {
|
||||||
expand_pat(pat, self)
|
expand_pat(pat, self)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue