Re-fold expanded items in expand_mac_invoc

This commit is contained in:
Jeffrey Seyfried
2016-05-20 23:35:56 +00:00
parent 2e7afd7367
commit 8ee93b73d1

View File

@@ -93,18 +93,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
// Assert that we drop any macro attributes on the floor here // Assert that we drop any macro attributes on the floor here
drop(attrs); drop(attrs);
let expanded_expr = match expand_mac_invoc(mac, span, fld) { expand_mac_invoc(mac, span, fld)
Some(expr) => expr,
None => {
return DummyResult::raw_expr(span);
}
};
// Keep going, outside-in.
let fully_expanded = fld.fold_expr(expanded_expr);
fld.cx.bt_pop();
fully_expanded
} }
ast::ExprKind::InPlace(placer, value_expr) => { ast::ExprKind::InPlace(placer, value_expr) => {
@@ -215,8 +204,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
} }
/// Expand a (not-ident-style) macro invocation. Returns the result of expansion. /// Expand a (not-ident-style) macro invocation. Returns the result of expansion.
fn expand_mac_invoc<T: MacroGenerable>(mac: ast::Mac, span: Span, fld: &mut MacroExpander) fn expand_mac_invoc<T: MacroGenerable>(mac: ast::Mac, span: Span, fld: &mut MacroExpander) -> T {
-> Option<T> {
// it would almost certainly be cleaner to pass the whole // it would almost certainly be cleaner to pass the whole
// macro invocation in, rather than pulling it apart and // macro invocation in, rather than pulling it apart and
// marking the tts and the ctxt separately. This also goes // marking the tts and the ctxt separately. This also goes
@@ -229,7 +217,7 @@ fn expand_mac_invoc<T: MacroGenerable>(mac: ast::Mac, span: Span, fld: &mut Macr
"expected macro name without module \ "expected macro name without module \
separators"); separators");
// let compilation continue // let compilation continue
return None; return T::dummy(span);
} }
let extname = pth.segments[0].identifier.name; let extname = pth.segments[0].identifier.name;
match fld.cx.syntax_env.find(extname) { match fld.cx.syntax_env.find(extname) {
@@ -242,7 +230,7 @@ fn expand_mac_invoc<T: MacroGenerable>(mac: ast::Mac, span: Span, fld: &mut Macr
err.emit(); err.emit();
// let compilation continue // let compilation continue
None T::dummy(span)
} }
Some(rc) => match *rc { Some(rc) => match *rc {
NormalTT(ref expandfun, exp_span, allow_internal_unstable) => { NormalTT(ref expandfun, exp_span, allow_internal_unstable) => {
@@ -275,17 +263,20 @@ fn expand_mac_invoc<T: MacroGenerable>(mac: ast::Mac, span: Span, fld: &mut Macr
let msg = format!("non-{kind} macro in {kind} position: {name}", let msg = format!("non-{kind} macro in {kind} position: {name}",
name = extname, kind = T::kind_name()); name = extname, kind = T::kind_name());
fld.cx.span_err(pth.span, &msg); fld.cx.span_err(pth.span, &msg);
return None; return T::dummy(span);
} }
}; };
Some(parsed.fold_with(&mut Marker { mark: fm })) let marked = parsed.fold_with(&mut Marker { mark: fm });
let fully_expanded = marked.fold_with(fld);
fld.cx.bt_pop();
fully_expanded
} }
_ => { _ => {
fld.cx.span_err( fld.cx.span_err(
pth.span, pth.span,
&format!("'{}' is not a tt-style macro", &format!("'{}' is not a tt-style macro",
extname)); extname));
None T::dummy(span)
} }
} }
} }
@@ -543,21 +534,9 @@ fn expand_stmt(stmt: Stmt, fld: &mut MacroExpander) -> SmallVector<Stmt> {
// Assert that we drop any macro attributes on the floor here // Assert that we drop any macro attributes on the floor here
drop(attrs); drop(attrs);
let maybe_new_items: Option<SmallVector<ast::Stmt>> = let mut fully_expanded: SmallVector<ast::Stmt> =
expand_mac_invoc(mac.unwrap(), stmt.span, fld); expand_mac_invoc(mac.unwrap(), stmt.span, fld);
let mut fully_expanded = match maybe_new_items {
Some(stmts) => {
// Keep going, outside-in.
let new_items = stmts.into_iter().flat_map(|s| {
fld.fold_stmt(s).into_iter()
}).collect();
fld.cx.bt_pop();
new_items
}
None => SmallVector::zero()
};
// If this is a macro invocation with a semicolon, then apply that // If this is a macro invocation with a semicolon, then apply that
// semicolon to the final statement produced by expansion. // semicolon to the final statement produced by expansion.
if style == MacStmtStyle::Semicolon { if style == MacStmtStyle::Semicolon {
@@ -1096,21 +1075,7 @@ fn expand_impl_item(ii: ast::ImplItem, fld: &mut MacroExpander)
}), }),
ast::ImplItemKind::Macro(mac) => { ast::ImplItemKind::Macro(mac) => {
check_attributes(&ii.attrs, fld); check_attributes(&ii.attrs, fld);
expand_mac_invoc(mac, ii.span, fld)
let maybe_new_items: Option<SmallVector<ast::ImplItem>> =
expand_mac_invoc(mac, ii.span, fld);
match maybe_new_items {
Some(impl_items) => {
// expand again if necessary
let new_items = impl_items.into_iter().flat_map(|ii| {
expand_impl_item(ii, fld).into_iter()
}).collect();
fld.cx.bt_pop();
new_items
}
None => SmallVector::zero()
}
} }
_ => fold::noop_fold_impl_item(ii, fld) _ => fold::noop_fold_impl_item(ii, fld)
} }
@@ -1154,22 +1119,7 @@ pub fn expand_type(t: P<ast::Ty>, fld: &mut MacroExpander) -> P<ast::Ty> {
let t = match t.node.clone() { let t = match t.node.clone() {
ast::TyKind::Mac(mac) => { ast::TyKind::Mac(mac) => {
if fld.cx.ecfg.features.unwrap().type_macros { if fld.cx.ecfg.features.unwrap().type_macros {
let expanded_ty = match expand_mac_invoc(mac, t.span, fld) { expand_mac_invoc(mac, t.span, fld)
Some(ty) => ty,
None => {
return DummyResult::raw_ty(t.span);
}
};
// Keep going, outside-in.
let fully_expanded = fld.fold_ty(expanded_ty);
fld.cx.bt_pop();
fully_expanded.map(|t| ast::Ty {
id: ast::DUMMY_NODE_ID,
node: t.node,
span: t.span,
})
} else { } else {
feature_gate::emit_feature_err( feature_gate::emit_feature_err(
&fld.cx.parse_sess.span_diagnostic, &fld.cx.parse_sess.span_diagnostic,