1
Fork 0

Moved and refactored ThinAttributes

This commit is contained in:
Marvin Löbel 2015-11-15 17:17:50 +01:00
parent 2a8f358de7
commit f0beba0217
11 changed files with 143 additions and 139 deletions

View file

@ -41,7 +41,8 @@ use syntax::ast_util::{self, IdVisitingOperation};
use syntax::attr::{self, AttrMetaMethods}; use syntax::attr::{self, AttrMetaMethods};
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::parse::token::InternedString; use syntax::parse::token::InternedString;
use syntax::ast::{self, ThinAttributesExt}; use syntax::ast;
use syntax::attr::ThinAttributesExt;
use rustc_front::hir; use rustc_front::hir;
use rustc_front::util; use rustc_front::util;
use rustc_front::intravisit as hir_visit; use rustc_front::intravisit as hir_visit;
@ -674,7 +675,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
} }
fn visit_expr(&mut self, e: &hir::Expr) { fn visit_expr(&mut self, e: &hir::Expr) {
self.with_lint_attrs(e.attrs.as_attrs(), |cx| { self.with_lint_attrs(e.attrs.as_attr_slice(), |cx| {
run_lints!(cx, check_expr, late_passes, e); run_lints!(cx, check_expr, late_passes, e);
hir_visit::walk_expr(cx, e); hir_visit::walk_expr(cx, e);
}) })
@ -737,7 +738,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
} }
fn visit_local(&mut self, l: &hir::Local) { fn visit_local(&mut self, l: &hir::Local) {
self.with_lint_attrs(l.attrs.as_attrs(), |cx| { self.with_lint_attrs(l.attrs.as_attr_slice(), |cx| {
run_lints!(cx, check_local, late_passes, l); run_lints!(cx, check_local, late_passes, l);
hir_visit::walk_local(cx, l); hir_visit::walk_local(cx, l);
}) })

View file

@ -13,7 +13,8 @@
use hir::*; use hir::*;
use syntax::ast::{Ident, Name, NodeId, DUMMY_NODE_ID, Attribute, Attribute_, MetaItem}; use syntax::ast::{Ident, Name, NodeId, DUMMY_NODE_ID, Attribute, Attribute_, MetaItem};
use syntax::ast::{MetaWord, MetaList, MetaNameValue, ThinAttributesExt}; use syntax::ast::{MetaWord, MetaList, MetaNameValue};
use syntax::attr::ThinAttributesExt;
use hir; use hir;
use syntax::codemap::{respan, Span, Spanned}; use syntax::codemap::{respan, Span, Spanned};
use syntax::owned_slice::OwnedSlice; use syntax::owned_slice::OwnedSlice;
@ -508,7 +509,7 @@ pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> {
pat: fld.fold_pat(pat), pat: fld.fold_pat(pat),
init: init.map(|e| fld.fold_expr(e)), init: init.map(|e| fld.fold_expr(e)),
span: fld.new_span(span), span: fld.new_span(span),
attrs: attrs.map_opt_attrs(|attrs| fold_attrs(attrs, fld)), attrs: attrs.map_thin_attrs(|attrs| fold_attrs(attrs, fld)),
} }
}) })
} }
@ -1172,7 +1173,7 @@ pub fn noop_fold_expr<T: Folder>(Expr { id, node, span, attrs }: Expr, folder: &
} }
}, },
span: folder.new_span(span), span: folder.new_span(span),
attrs: attrs.map_opt_attrs(|attrs| fold_attrs(attrs, folder)), attrs: attrs.map_thin_attrs(|attrs| fold_attrs(attrs, folder)),
} }
} }

View file

@ -41,7 +41,7 @@ use syntax::codemap::{self, Span, Spanned, DUMMY_SP, ExpnId};
use syntax::abi::Abi; use syntax::abi::Abi;
use syntax::ast::{Name, Ident, NodeId, DUMMY_NODE_ID, TokenTree, AsmDialect}; use syntax::ast::{Name, Ident, NodeId, DUMMY_NODE_ID, TokenTree, AsmDialect};
use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, CrateConfig}; use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, CrateConfig};
use syntax::ast::ThinAttributes; use syntax::attr::ThinAttributes;
use syntax::owned_slice::OwnedSlice; use syntax::owned_slice::OwnedSlice;
use syntax::parse::token::InternedString; use syntax::parse::token::InternedString;
use syntax::ptr::P; use syntax::ptr::P;

View file

@ -66,6 +66,7 @@ use hir;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::collections::HashMap; use std::collections::HashMap;
use syntax::ast::*; use syntax::ast::*;
use syntax::attr::{ThinAttributes, ThinAttributesExt};
use syntax::ptr::P; use syntax::ptr::P;
use syntax::codemap::{respan, Spanned, Span}; use syntax::codemap::{respan, Spanned, Span};
use syntax::owned_slice::OwnedSlice; use syntax::owned_slice::OwnedSlice;
@ -1219,8 +1220,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
// merge attributes into the inner expression. // merge attributes into the inner expression.
return lower_expr(lctx, ex).map(|mut ex| { return lower_expr(lctx, ex).map(|mut ex| {
ex.attrs.update(|attrs| { ex.attrs.update(|attrs| {
// FIXME: Badly named attrs.prepend(e.attrs.clone())
attrs.prepend_outer(e.attrs.clone())
}); });
ex ex
}); });

View file

@ -45,6 +45,7 @@ pub use self::ViewPath_::*;
pub use self::Visibility::*; pub use self::Visibility::*;
pub use self::PathParameters::*; pub use self::PathParameters::*;
use attr::ThinAttributes;
use codemap::{Span, Spanned, DUMMY_SP, ExpnId}; use codemap::{Span, Spanned, DUMMY_SP, ExpnId};
use abi::Abi; use abi::Abi;
use ast_util; use ast_util;
@ -1952,98 +1953,6 @@ pub struct MacroDef {
pub body: Vec<TokenTree>, pub body: Vec<TokenTree>,
} }
/// A list of attributes, behind a optional box as
/// a space optimization.
pub type ThinAttributes = Option<Box<Vec<Attribute>>>;
pub trait ThinAttributesExt {
fn map_opt_attrs<F>(self, f: F) -> Self
where F: FnOnce(Vec<Attribute>) -> Vec<Attribute>;
fn prepend_outer(mut self, attrs: Self) -> Self;
fn append_inner(mut self, attrs: Self) -> Self;
fn update<F>(&mut self, f: F)
where Self: Sized,
F: FnOnce(Self) -> Self;
fn as_attrs(&self) -> &[Attribute];
fn into_attrs(self) -> Vec<Attribute>;
}
// FIXME: Rename inner/outer
// FIXME: Rename opt_attrs
impl ThinAttributesExt for ThinAttributes {
fn map_opt_attrs<F>(self, f: F) -> Self
where F: FnOnce(Vec<Attribute>) -> Vec<Attribute> {
// This is kinda complicated... Ensure the function is
// always called, and that None inputs or results are
// correctly handled.
if let Some(mut b) = self {
use std::mem::replace;
let vec = replace(&mut *b, Vec::new());
let vec = f(vec);
if vec.len() == 0 {
None
} else {
replace(&mut*b, vec);
Some(b)
}
} else {
f(Vec::new()).into_opt_attrs()
}
}
fn prepend_outer(self, attrs: ThinAttributes) -> Self {
attrs.map_opt_attrs(|mut attrs| {
attrs.extend(self.into_attrs());
attrs
})
}
fn append_inner(self, attrs: ThinAttributes) -> Self {
self.map_opt_attrs(|mut self_| {
self_.extend(attrs.into_attrs());
self_
})
}
fn update<F>(&mut self, f: F)
where Self: Sized,
F: FnOnce(ThinAttributes) -> ThinAttributes
{
let self_ = f(self.take());
*self = self_;
}
fn as_attrs(&self) -> &[Attribute] {
match *self {
Some(ref b) => b,
None => &[],
}
}
fn into_attrs(self) -> Vec<Attribute> {
match self {
Some(b) => *b,
None => Vec::new(),
}
}
}
pub trait AttributesExt {
fn into_opt_attrs(self) -> ThinAttributes;
}
impl AttributesExt for Vec<Attribute> {
fn into_opt_attrs(self) -> ThinAttributes {
if self.len() == 0 {
None
} else {
Some(Box::new(self))
}
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serialize; use serialize;

View file

@ -16,8 +16,8 @@ pub use self::IntType::*;
use ast; use ast;
use ast::{AttrId, Attribute, Attribute_, MetaItem, MetaWord, MetaNameValue, MetaList}; use ast::{AttrId, Attribute, Attribute_, MetaItem, MetaWord, MetaNameValue, MetaList};
use ast::{Stmt, StmtDecl, StmtExpr, StmtMac, StmtSemi, DeclItem, DeclLocal, ThinAttributes}; use ast::{Stmt, StmtDecl, StmtExpr, StmtMac, StmtSemi, DeclItem, DeclLocal};
use ast::{Expr, ThinAttributesExt, Item, Local, Decl}; use ast::{Expr, Item, Local, Decl};
use codemap::{Span, Spanned, spanned, dummy_spanned}; use codemap::{Span, Spanned, spanned, dummy_spanned};
use codemap::BytePos; use codemap::BytePos;
use diagnostic::SpanHandler; use diagnostic::SpanHandler;
@ -723,6 +723,96 @@ impl IntType {
} }
} }
/// A list of attributes, behind a optional box as
/// a space optimization.
pub type ThinAttributes = Option<Box<Vec<Attribute>>>;
pub trait ThinAttributesExt {
fn map_thin_attrs<F>(self, f: F) -> Self
where F: FnOnce(Vec<Attribute>) -> Vec<Attribute>;
fn prepend(mut self, attrs: Self) -> Self;
fn append(mut self, attrs: Self) -> Self;
fn update<F>(&mut self, f: F)
where Self: Sized,
F: FnOnce(Self) -> Self;
fn as_attr_slice(&self) -> &[Attribute];
fn into_attr_vec(self) -> Vec<Attribute>;
}
impl ThinAttributesExt for ThinAttributes {
fn map_thin_attrs<F>(self, f: F) -> Self
where F: FnOnce(Vec<Attribute>) -> Vec<Attribute> {
// This is kinda complicated... Ensure the function is
// always called, and that None inputs or results are
// correctly handled.
if let Some(mut b) = self {
use std::mem::replace;
let vec = replace(&mut *b, Vec::new());
let vec = f(vec);
if vec.len() == 0 {
None
} else {
replace(&mut*b, vec);
Some(b)
}
} else {
f(Vec::new()).into_thin_attrs()
}
}
fn prepend(self, attrs: ThinAttributes) -> Self {
attrs.map_thin_attrs(|mut attrs| {
attrs.extend(self.into_attr_vec());
attrs
})
}
fn append(self, attrs: ThinAttributes) -> Self {
self.map_thin_attrs(|mut self_| {
self_.extend(attrs.into_attr_vec());
self_
})
}
fn update<F>(&mut self, f: F)
where Self: Sized,
F: FnOnce(ThinAttributes) -> ThinAttributes
{
let self_ = f(self.take());
*self = self_;
}
fn as_attr_slice(&self) -> &[Attribute] {
match *self {
Some(ref b) => b,
None => &[],
}
}
fn into_attr_vec(self) -> Vec<Attribute> {
match self {
Some(b) => *b,
None => Vec::new(),
}
}
}
pub trait AttributesExt {
fn into_thin_attrs(self) -> ThinAttributes;
}
impl AttributesExt for Vec<Attribute> {
fn into_thin_attrs(self) -> ThinAttributes {
if self.len() == 0 {
None
} else {
Some(Box::new(self))
}
}
}
/// A cheap way to add Attributes to an AST node. /// A cheap way to add Attributes to an AST node.
pub trait WithAttrs { pub trait WithAttrs {
// FIXME: Could be extended to anything IntoIter<Item=Attribute> // FIXME: Could be extended to anything IntoIter<Item=Attribute>
@ -732,7 +822,7 @@ pub trait WithAttrs {
impl WithAttrs for P<Expr> { impl WithAttrs for P<Expr> {
fn with_attrs(self, attrs: ThinAttributes) -> Self { fn with_attrs(self, attrs: ThinAttributes) -> Self {
self.map(|mut e| { self.map(|mut e| {
e.attrs.update(|a| a.append_inner(attrs)); e.attrs.update(|a| a.append(attrs));
e e
}) })
} }
@ -741,7 +831,7 @@ impl WithAttrs for P<Expr> {
impl WithAttrs for P<Item> { impl WithAttrs for P<Item> {
fn with_attrs(self, attrs: ThinAttributes) -> Self { fn with_attrs(self, attrs: ThinAttributes) -> Self {
self.map(|Item { ident, attrs: mut ats, id, node, vis, span }| { self.map(|Item { ident, attrs: mut ats, id, node, vis, span }| {
ats.extend(attrs.into_attrs()); ats.extend(attrs.into_attr_vec());
Item { Item {
ident: ident, ident: ident,
attrs: ats, attrs: ats,
@ -757,7 +847,7 @@ impl WithAttrs for P<Item> {
impl WithAttrs for P<Local> { impl WithAttrs for P<Local> {
fn with_attrs(self, attrs: ThinAttributes) -> Self { fn with_attrs(self, attrs: ThinAttributes) -> Self {
self.map(|Local { pat, ty, init, id, span, attrs: mut ats }| { self.map(|Local { pat, ty, init, id, span, attrs: mut ats }| {
ats.update(|a| a.append_inner(attrs)); ats.update(|a| a.append(attrs));
Local { Local {
pat: pat, pat: pat,
ty: ty, ty: ty,
@ -794,7 +884,7 @@ impl WithAttrs for P<Stmt> {
StmtExpr(expr, id) => StmtExpr(expr.with_attrs(attrs), id), StmtExpr(expr, id) => StmtExpr(expr.with_attrs(attrs), id),
StmtSemi(expr, id) => StmtSemi(expr.with_attrs(attrs), id), StmtSemi(expr, id) => StmtSemi(expr.with_attrs(attrs), id),
StmtMac(mac, style, mut ats) => { StmtMac(mac, style, mut ats) => {
ats.update(|a| a.append_inner(attrs)); ats.update(|a| a.append(attrs));
StmtMac(mac, style, ats) StmtMac(mac, style, ats)
} }
}, },

View file

@ -54,7 +54,7 @@ impl<'a, F> fold::Folder for Context<'a, F> where F: FnMut(&[ast::Attribute]) ->
// Anything else is always required, and thus has to error out // Anything else is always required, and thus has to error out
// in case of a cfg attr. // in case of a cfg attr.
// //
// NB: This intentionally not part of the fold_expr() function // NB: This is intentionally not part of the fold_expr() function
// in order for fold_opt_expr() to be able to avoid this check // in order for fold_opt_expr() to be able to avoid this check
if let Some(attr) = expr.attrs().iter().find(|a| is_cfg(a)) { if let Some(attr) = expr.attrs().iter().find(|a| is_cfg(a)) {
self.diagnostic.span_err(attr.span, self.diagnostic.span_err(attr.span,

View file

@ -20,6 +20,7 @@
use ast::*; use ast::*;
use ast; use ast;
use attr::ThinAttributesExt;
use ast_util; use ast_util;
use codemap::{respan, Span, Spanned}; use codemap::{respan, Span, Spanned};
use owned_slice::OwnedSlice; use owned_slice::OwnedSlice;
@ -522,7 +523,7 @@ pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> {
pat: fld.fold_pat(pat), pat: fld.fold_pat(pat),
init: init.map(|e| fld.fold_expr(e)), init: init.map(|e| fld.fold_expr(e)),
span: fld.new_span(span), span: fld.new_span(span),
attrs: attrs.map_opt_attrs(|v| fold_attrs(v, fld)), attrs: attrs.map_thin_attrs(|v| fold_attrs(v, fld)),
}) })
} }
@ -1339,7 +1340,7 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
ExprParen(ex) => ExprParen(folder.fold_expr(ex)) ExprParen(ex) => ExprParen(folder.fold_expr(ex))
}, },
span: folder.new_span(span), span: folder.new_span(span),
attrs: attrs.map_opt_attrs(|v| fold_attrs(v, folder)), attrs: attrs.map_thin_attrs(|v| fold_attrs(v, folder)),
} }
} }
@ -1388,7 +1389,7 @@ pub fn noop_fold_stmt<T: Folder>(Spanned {node, span}: Stmt, folder: &mut T)
StmtMac(mac, semi, attrs) => SmallVector::one(P(Spanned { StmtMac(mac, semi, attrs) => SmallVector::one(P(Spanned {
node: StmtMac(mac.map(|m| folder.fold_mac(m)), node: StmtMac(mac.map(|m| folder.fold_mac(m)),
semi, semi,
attrs.map_opt_attrs(|v| fold_attrs(v, folder))), attrs.map_thin_attrs(|v| fold_attrs(v, folder))),
span: span span: span
})) }))
} }

View file

@ -56,7 +56,7 @@ use ast::TypeTraitItem;
use ast::{UnnamedField, UnsafeBlock}; use ast::{UnnamedField, UnsafeBlock};
use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
use ast::{Visibility, WhereClause}; use ast::{Visibility, WhereClause};
use ast::{ThinAttributes, ThinAttributesExt, AttributesExt}; use attr::{ThinAttributes, ThinAttributesExt, AttributesExt};
use ast; use ast;
use ast_util::{self, ident_to_path}; use ast_util::{self, ident_to_path};
use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap}; use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap};
@ -2053,8 +2053,8 @@ impl<'a> Parser<'a> {
try!(self.bump()); try!(self.bump());
let attrs = try!(self.parse_inner_attributes()) let attrs = try!(self.parse_inner_attributes())
.into_opt_attrs() .into_thin_attrs()
.prepend_outer(attrs); .prepend(attrs);
// (e) is parenthesized e // (e) is parenthesized e
// (e,) is a tuple with only one field, e // (e,) is a tuple with only one field, e
@ -2102,8 +2102,8 @@ impl<'a> Parser<'a> {
try!(self.bump()); try!(self.bump());
let inner_attrs = try!(self.parse_inner_attributes()) let inner_attrs = try!(self.parse_inner_attributes())
.into_opt_attrs(); .into_thin_attrs();
attrs.update(|attrs| attrs.append_inner(inner_attrs)); attrs.update(|attrs| attrs.append(inner_attrs));
if self.check(&token::CloseDelim(token::Bracket)) { if self.check(&token::CloseDelim(token::Bracket)) {
// Empty vector. // Empty vector.
@ -2257,9 +2257,9 @@ impl<'a> Parser<'a> {
let mut fields = Vec::new(); let mut fields = Vec::new();
let mut base = None; let mut base = None;
let attrs = attrs.append_inner( let attrs = attrs.append(
try!(self.parse_inner_attributes()) try!(self.parse_inner_attributes())
.into_opt_attrs()); .into_thin_attrs());
while self.token != token::CloseDelim(token::Brace) { while self.token != token::CloseDelim(token::Brace) {
if try!(self.eat(&token::DotDot) ){ if try!(self.eat(&token::DotDot) ){
@ -2300,7 +2300,7 @@ impl<'a> Parser<'a> {
if let Some(attrs) = already_parsed_attrs { if let Some(attrs) = already_parsed_attrs {
Ok(attrs) Ok(attrs)
} else { } else {
self.parse_outer_attributes().map(|a| a.into_opt_attrs()) self.parse_outer_attributes().map(|a| a.into_thin_attrs())
} }
} }
@ -2312,8 +2312,8 @@ impl<'a> Parser<'a> {
let outer_attrs = attrs; let outer_attrs = attrs;
try!(self.expect(&token::OpenDelim(token::Brace))); try!(self.expect(&token::OpenDelim(token::Brace)));
let inner_attrs = try!(self.parse_inner_attributes()).into_opt_attrs(); let inner_attrs = try!(self.parse_inner_attributes()).into_thin_attrs();
let attrs = outer_attrs.append_inner(inner_attrs); let attrs = outer_attrs.append(inner_attrs);
let blk = try!(self.parse_block_tail(lo, blk_mode)); let blk = try!(self.parse_block_tail(lo, blk_mode));
return Ok(self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk), attrs)); return Ok(self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk), attrs));
@ -2339,12 +2339,12 @@ impl<'a> Parser<'a> {
self.parse_dot_or_call_expr_with_(e0) self.parse_dot_or_call_expr_with_(e0)
.map(|expr| .map(|expr|
expr.map(|mut expr| { expr.map(|mut expr| {
expr.attrs.update(|a| a.prepend_outer(attrs)); expr.attrs.update(|a| a.prepend(attrs));
match expr.node { match expr.node {
ExprIf(..) | ExprIfLet(..) => { ExprIf(..) | ExprIfLet(..) => {
if !expr.attrs.as_attrs().is_empty() { if !expr.attrs.as_attr_slice().is_empty() {
// Just point to the first attribute in there... // Just point to the first attribute in there...
let span = expr.attrs.as_attrs()[0].span; let span = expr.attrs.as_attr_slice()[0].span;
self.span_err(span, self.span_err(span,
"attributes are not yet allowed on `if` \ "attributes are not yet allowed on `if` \
@ -3012,7 +3012,7 @@ impl<'a> Parser<'a> {
try!(self.expect_keyword(keywords::In)); try!(self.expect_keyword(keywords::In));
let expr = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None)); let expr = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None));
let (iattrs, loop_block) = try!(self.parse_inner_attrs_and_block()); let (iattrs, loop_block) = try!(self.parse_inner_attrs_and_block());
let attrs = attrs.append_inner(iattrs.into_opt_attrs()); let attrs = attrs.append(iattrs.into_thin_attrs());
let hi = self.last_span.hi; let hi = self.last_span.hi;
@ -3030,7 +3030,7 @@ impl<'a> Parser<'a> {
} }
let cond = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None)); let cond = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None));
let (iattrs, body) = try!(self.parse_inner_attrs_and_block()); let (iattrs, body) = try!(self.parse_inner_attrs_and_block());
let attrs = attrs.append_inner(iattrs.into_opt_attrs()); let attrs = attrs.append(iattrs.into_thin_attrs());
let hi = body.span.hi; let hi = body.span.hi;
return Ok(self.mk_expr(span_lo, hi, ExprWhile(cond, body, opt_ident), return Ok(self.mk_expr(span_lo, hi, ExprWhile(cond, body, opt_ident),
attrs)); attrs));
@ -3045,7 +3045,7 @@ impl<'a> Parser<'a> {
try!(self.expect(&token::Eq)); try!(self.expect(&token::Eq));
let expr = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None)); let expr = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None));
let (iattrs, body) = try!(self.parse_inner_attrs_and_block()); let (iattrs, body) = try!(self.parse_inner_attrs_and_block());
let attrs = attrs.append_inner(iattrs.into_opt_attrs()); let attrs = attrs.append(iattrs.into_thin_attrs());
let hi = body.span.hi; let hi = body.span.hi;
return Ok(self.mk_expr(span_lo, hi, ExprWhileLet(pat, expr, body, opt_ident), attrs)); return Ok(self.mk_expr(span_lo, hi, ExprWhileLet(pat, expr, body, opt_ident), attrs));
} }
@ -3055,7 +3055,7 @@ impl<'a> Parser<'a> {
span_lo: BytePos, span_lo: BytePos,
attrs: ThinAttributes) -> PResult<P<Expr>> { attrs: ThinAttributes) -> PResult<P<Expr>> {
let (iattrs, body) = try!(self.parse_inner_attrs_and_block()); let (iattrs, body) = try!(self.parse_inner_attrs_and_block());
let attrs = attrs.append_inner(iattrs.into_opt_attrs()); let attrs = attrs.append(iattrs.into_thin_attrs());
let hi = body.span.hi; let hi = body.span.hi;
Ok(self.mk_expr(span_lo, hi, ExprLoop(body, opt_ident), attrs)) Ok(self.mk_expr(span_lo, hi, ExprLoop(body, opt_ident), attrs))
} }
@ -3072,8 +3072,8 @@ impl<'a> Parser<'a> {
} }
return Err(e) return Err(e)
} }
let attrs = attrs.append_inner( let attrs = attrs.append(
try!(self.parse_inner_attributes()).into_opt_attrs()); try!(self.parse_inner_attributes()).into_thin_attrs());
let mut arms: Vec<Arm> = Vec::new(); let mut arms: Vec<Arm> = Vec::new();
while self.token != token::CloseDelim(token::Brace) { while self.token != token::CloseDelim(token::Brace) {
arms.push(try!(self.parse_arm())); arms.push(try!(self.parse_arm()));
@ -3596,7 +3596,7 @@ impl<'a> Parser<'a> {
Ok(Some(if self.check_keyword(keywords::Let) { Ok(Some(if self.check_keyword(keywords::Let) {
try!(self.expect_keyword(keywords::Let)); try!(self.expect_keyword(keywords::Let));
let decl = try!(self.parse_let(attrs.into_opt_attrs())); let decl = try!(self.parse_let(attrs.into_thin_attrs()));
let hi = decl.span.hi; let hi = decl.span.hi;
let stmt = StmtDecl(decl, ast::DUMMY_NODE_ID); let stmt = StmtDecl(decl, ast::DUMMY_NODE_ID);
spanned(lo, hi, stmt) spanned(lo, hi, stmt)
@ -3654,7 +3654,7 @@ impl<'a> Parser<'a> {
hi, hi,
Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT })), Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT })),
style, style,
attrs.into_opt_attrs()); attrs.into_thin_attrs());
spanned(lo, hi, stmt) spanned(lo, hi, stmt)
} else { } else {
// if it has a special ident, it's definitely an item // if it has a special ident, it's definitely an item
@ -3708,7 +3708,7 @@ impl<'a> Parser<'a> {
// Remainder are line-expr stmts. // Remainder are line-expr stmts.
let e = try!(self.parse_expr_res( let e = try!(self.parse_expr_res(
Restrictions::RESTRICTION_STMT_EXPR, Some(attrs.into_opt_attrs()))); Restrictions::RESTRICTION_STMT_EXPR, Some(attrs.into_thin_attrs())));
let hi = e.span.hi; let hi = e.span.hi;
let stmt = StmtExpr(e, ast::DUMMY_NODE_ID); let stmt = StmtExpr(e, ast::DUMMY_NODE_ID);
spanned(lo, hi, stmt) spanned(lo, hi, stmt)

View file

@ -13,7 +13,8 @@ pub use self::AnnNode::*;
use abi; use abi;
use ast::{self, TokenTree}; use ast::{self, TokenTree};
use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
use ast::{ThinAttributesExt, Attribute}; use ast::Attribute;
use attr::ThinAttributesExt;
use ast_util; use ast_util;
use util::parser::AssocOp; use util::parser::AssocOp;
use attr; use attr;
@ -1638,7 +1639,7 @@ impl<'a> State<'a> {
} }
ast::StmtMac(ref mac, style, ref attrs) => { ast::StmtMac(ref mac, style, ref attrs) => {
try!(self.space_if_not_bol()); try!(self.space_if_not_bol());
try!(self.print_outer_attributes(attrs.as_attrs())); try!(self.print_outer_attributes(attrs.as_attr_slice()));
let delim = match style { let delim = match style {
ast::MacStmtWithBraces => token::Brace, ast::MacStmtWithBraces => token::Brace,
_ => token::Paren _ => token::Paren
@ -1983,7 +1984,7 @@ impl<'a> State<'a> {
is_inline: bool) -> io::Result<()> { is_inline: bool) -> io::Result<()> {
try!(self.maybe_print_comment(expr.span.lo)); try!(self.maybe_print_comment(expr.span.lo));
let attrs = expr.attrs.as_attrs(); let attrs = expr.attrs.as_attr_slice();
if is_inline { if is_inline {
try!(self.print_outer_attributes_inline(attrs)); try!(self.print_outer_attributes_inline(attrs));
} else { } else {
@ -2124,7 +2125,7 @@ impl<'a> State<'a> {
ast::ExprBlock(ref blk) => { ast::ExprBlock(ref blk) => {
try!(self.print_block_unclosed_with_attrs( try!(self.print_block_unclosed_with_attrs(
&**blk, &**blk,
i_expr.attrs.as_attrs())); i_expr.attrs.as_attr_slice()));
} }
_ => { _ => {
// this is a bare expression // this is a bare expression
@ -2303,7 +2304,7 @@ impl<'a> State<'a> {
try!(self.maybe_print_comment(decl.span.lo)); try!(self.maybe_print_comment(decl.span.lo));
match decl.node { match decl.node {
ast::DeclLocal(ref loc) => { ast::DeclLocal(ref loc) => {
try!(self.print_outer_attributes(loc.attrs.as_attrs())); try!(self.print_outer_attributes(loc.attrs.as_attr_slice()));
try!(self.space_if_not_bol()); try!(self.space_if_not_bol());
try!(self.ibox(INDENT_UNIT)); try!(self.ibox(INDENT_UNIT));
try!(self.word_nbsp("let")); try!(self.word_nbsp("let"));

View file

@ -25,6 +25,7 @@
use abi::Abi; use abi::Abi;
use ast::*; use ast::*;
use attr::ThinAttributesExt;
use codemap::Span; use codemap::Span;
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
@ -630,7 +631,7 @@ pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) {
} }
StmtMac(ref mac, _, ref attrs) => { StmtMac(ref mac, _, ref attrs) => {
visitor.visit_mac(mac); visitor.visit_mac(mac);
for attr in attrs.as_attrs() { for attr in attrs.as_attr_slice() {
visitor.visit_attribute(attr); visitor.visit_attribute(attr);
} }
} }