1
Fork 0

Refactor away WithAttrs trait

This commit is contained in:
Jeffrey Seyfried 2016-06-10 22:59:33 +00:00
parent 5bf7970ac7
commit 683e480ffe
2 changed files with 15 additions and 39 deletions

View file

@ -889,21 +889,6 @@ pub trait HasAttrs: Sized {
fn map_attrs<F: FnOnce(Vec<ast::Attribute>) -> Vec<ast::Attribute>>(self, f: F) -> Self; fn map_attrs<F: FnOnce(Vec<ast::Attribute>) -> Vec<ast::Attribute>>(self, f: F) -> Self;
} }
/// A cheap way to add Attributes to an AST node.
pub trait WithAttrs {
// FIXME: Could be extended to anything IntoIter<Item=Attribute>
fn with_attrs(self, attrs: ThinAttributes) -> Self;
}
impl<T: HasAttrs> WithAttrs for T {
fn with_attrs(self, attrs: ThinAttributes) -> Self {
self.map_attrs(|mut orig_attrs| {
orig_attrs.extend(attrs.into_attr_vec());
orig_attrs
})
}
}
impl HasAttrs for Vec<Attribute> { impl HasAttrs for Vec<Attribute> {
fn attrs(&self) -> &[Attribute] { fn attrs(&self) -> &[Attribute] {
&self &self

View file

@ -14,9 +14,8 @@ use ast::{MacStmtStyle, Mrk, Stmt, StmtKind, ItemKind};
use ast::TokenTree; use ast::TokenTree;
use ast; use ast;
use ext::mtwt; use ext::mtwt;
use ext::build::AstBuilder;
use attr; use attr;
use attr::{AttrMetaMethods, WithAttrs, ThinAttributesExt}; use attr::{AttrMetaMethods, 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 config::StripUnconfigured;
@ -87,19 +86,18 @@ impl MacroGenerable for Option<P<ast::Expr>> {
} }
} }
pub fn expand_expr(expr: ast::Expr, fld: &mut MacroExpander) -> P<ast::Expr> { pub fn expand_expr(mut expr: ast::Expr, fld: &mut MacroExpander) -> P<ast::Expr> {
match expr.node { match expr.node {
// expr_mac should really be expr_ext or something; it's the // expr_mac should really be expr_ext or something; it's the
// entry-point for all syntax extensions. // entry-point for all syntax extensions.
ast::ExprKind::Mac(mac) => { ast::ExprKind::Mac(mac) => {
expand_mac_invoc(mac, None, expr.attrs.into_attr_vec(), expr.span, fld) return expand_mac_invoc(mac, None, expr.attrs.into_attr_vec(), expr.span, fld);
} }
ast::ExprKind::While(cond, body, opt_ident) => { ast::ExprKind::While(cond, body, opt_ident) => {
let cond = fld.fold_expr(cond); let cond = fld.fold_expr(cond);
let (body, opt_ident) = expand_loop_block(body, opt_ident, fld); let (body, opt_ident) = expand_loop_block(body, opt_ident, fld);
fld.cx.expr(expr.span, ast::ExprKind::While(cond, body, opt_ident)) expr.node = ast::ExprKind::While(cond, body, opt_ident);
.with_attrs(fold_thin_attrs(expr.attrs, fld))
} }
ast::ExprKind::WhileLet(pat, cond, body, opt_ident) => { ast::ExprKind::WhileLet(pat, cond, body, opt_ident) => {
@ -116,14 +114,12 @@ pub fn expand_expr(expr: ast::Expr, fld: &mut MacroExpander) -> P<ast::Expr> {
}); });
assert!(rewritten_pats.len() == 1); assert!(rewritten_pats.len() == 1);
let wl = ast::ExprKind::WhileLet(rewritten_pats.remove(0), cond, body, opt_ident); expr.node = ast::ExprKind::WhileLet(rewritten_pats.remove(0), cond, body, opt_ident);
fld.cx.expr(expr.span, wl).with_attrs(fold_thin_attrs(expr.attrs, fld))
} }
ast::ExprKind::Loop(loop_block, opt_ident) => { ast::ExprKind::Loop(loop_block, opt_ident) => {
let (loop_block, opt_ident) = expand_loop_block(loop_block, opt_ident, fld); let (loop_block, opt_ident) = expand_loop_block(loop_block, opt_ident, fld);
fld.cx.expr(expr.span, ast::ExprKind::Loop(loop_block, opt_ident)) expr.node = ast::ExprKind::Loop(loop_block, opt_ident);
.with_attrs(fold_thin_attrs(expr.attrs, fld))
} }
ast::ExprKind::ForLoop(pat, head, body, opt_ident) => { ast::ExprKind::ForLoop(pat, head, body, opt_ident) => {
@ -140,8 +136,7 @@ pub fn expand_expr(expr: ast::Expr, fld: &mut MacroExpander) -> P<ast::Expr> {
assert!(rewritten_pats.len() == 1); assert!(rewritten_pats.len() == 1);
let head = fld.fold_expr(head); let head = fld.fold_expr(head);
let fl = ast::ExprKind::ForLoop(rewritten_pats.remove(0), head, body, opt_ident); expr.node = ast::ExprKind::ForLoop(rewritten_pats.remove(0), head, body, opt_ident);
fld.cx.expr(expr.span, fl).with_attrs(fold_thin_attrs(expr.attrs, fld))
} }
ast::ExprKind::IfLet(pat, sub_expr, body, else_opt) => { ast::ExprKind::IfLet(pat, sub_expr, body, else_opt) => {
@ -159,25 +154,21 @@ pub fn expand_expr(expr: ast::Expr, fld: &mut MacroExpander) -> P<ast::Expr> {
let else_opt = else_opt.map(|else_opt| fld.fold_expr(else_opt)); let else_opt = else_opt.map(|else_opt| fld.fold_expr(else_opt));
let sub_expr = fld.fold_expr(sub_expr); let sub_expr = fld.fold_expr(sub_expr);
let il = ast::ExprKind::IfLet(rewritten_pats.remove(0), sub_expr, body, else_opt); expr.node = ast::ExprKind::IfLet(rewritten_pats.remove(0), sub_expr, body, else_opt);
fld.cx.expr(expr.span, il).with_attrs(fold_thin_attrs(expr.attrs, fld))
} }
ast::ExprKind::Closure(capture_clause, fn_decl, block, fn_decl_span) => { ast::ExprKind::Closure(capture_clause, fn_decl, block, fn_decl_span) => {
let (rewritten_fn_decl, rewritten_block) let (rewritten_fn_decl, rewritten_block)
= expand_and_rename_fn_decl_and_block(fn_decl, block, fld); = expand_and_rename_fn_decl_and_block(fn_decl, block, fld);
let new_node = ast::ExprKind::Closure(capture_clause, expr.node = ast::ExprKind::Closure(capture_clause,
rewritten_fn_decl, rewritten_fn_decl,
rewritten_block, rewritten_block,
fn_decl_span); fn_decl_span);
P(ast::Expr{ id: expr.id,
node: new_node,
span: expr.span,
attrs: fold_thin_attrs(expr.attrs, fld) })
} }
_ => P(noop_fold_expr(expr, fld)), _ => expr = noop_fold_expr(expr, fld),
} };
P(expr)
} }
/// Expand a macro invocation. Returns the result of expansion. /// Expand a macro invocation. Returns the result of expansion.