syntax: fix fallout from using ptr::P.

This commit is contained in:
Eduard Burtescu 2014-09-13 19:06:01 +03:00
parent d6fb338d01
commit ccd8498afb
45 changed files with 1534 additions and 1693 deletions

View file

@ -22,7 +22,7 @@
//! for the `Code` associated with a particular NodeId. //! for the `Code` associated with a particular NodeId.
use abi; use abi;
use ast::{P, Block, FnDecl, NodeId}; use ast::{Block, FnDecl, NodeId};
use ast; use ast;
use ast_map::{Node}; use ast_map::{Node};
use ast_map; use ast_map;
@ -39,7 +39,7 @@ use visit;
/// - The default implementation for a trait method. /// - The default implementation for a trait method.
/// ///
/// To construct one, use the `Code::from_node` function. /// To construct one, use the `Code::from_node` function.
pub struct FnLikeNode { node: ast_map::Node } pub struct FnLikeNode<'a> { node: ast_map::Node<'a> }
/// MaybeFnLike wraps a method that indicates if an object /// MaybeFnLike wraps a method that indicates if an object
/// corresponds to some FnLikeNode. /// corresponds to some FnLikeNode.
@ -47,8 +47,8 @@ pub trait MaybeFnLike { fn is_fn_like(&self) -> bool; }
/// Components shared by fn-like things (fn items, methods, closures). /// Components shared by fn-like things (fn items, methods, closures).
pub struct FnParts<'a> { pub struct FnParts<'a> {
pub decl: P<FnDecl>, pub decl: &'a FnDecl,
pub body: P<Block>, pub body: &'a Block,
pub kind: visit::FnKind<'a>, pub kind: visit::FnKind<'a>,
pub span: Span, pub span: Span,
pub id: NodeId, pub id: NodeId,
@ -78,12 +78,12 @@ impl MaybeFnLike for ast::Expr {
/// Carries either an FnLikeNode or a Block, as these are the two /// Carries either an FnLikeNode or a Block, as these are the two
/// constructs that correspond to "code" (as in, something from which /// constructs that correspond to "code" (as in, something from which
/// we can construct a control-flow graph). /// we can construct a control-flow graph).
pub enum Code { pub enum Code<'a> {
FnLikeCode(FnLikeNode), FnLikeCode(FnLikeNode<'a>),
BlockCode(P<Block>), BlockCode(&'a Block),
} }
impl Code { impl<'a> Code<'a> {
pub fn id(&self) -> ast::NodeId { pub fn id(&self) -> ast::NodeId {
match *self { match *self {
FnLikeCode(node) => node.id(), FnLikeCode(node) => node.id(),
@ -115,32 +115,32 @@ impl Code {
/// use when implementing FnLikeNode operations. /// use when implementing FnLikeNode operations.
struct ItemFnParts<'a> { struct ItemFnParts<'a> {
ident: ast::Ident, ident: ast::Ident,
decl: P<ast::FnDecl>, decl: &'a ast::FnDecl,
style: ast::FnStyle, style: ast::FnStyle,
abi: abi::Abi, abi: abi::Abi,
generics: &'a ast::Generics, generics: &'a ast::Generics,
body: P<Block>, body: &'a Block,
id: ast::NodeId, id: ast::NodeId,
span: Span span: Span
} }
/// These are all the components one can extract from a closure expr /// These are all the components one can extract from a closure expr
/// for use when implementing FnLikeNode operations. /// for use when implementing FnLikeNode operations.
struct ClosureParts { struct ClosureParts<'a> {
decl: P<FnDecl>, decl: &'a FnDecl,
body: P<Block>, body: &'a Block,
id: NodeId, id: NodeId,
span: Span span: Span
} }
impl ClosureParts { impl<'a> ClosureParts<'a> {
fn new(d: P<FnDecl>, b: P<Block>, id: NodeId, s: Span) -> ClosureParts { fn new(d: &'a FnDecl, b: &'a Block, id: NodeId, s: Span) -> ClosureParts<'a> {
ClosureParts { decl: d, body: b, id: id, span: s } ClosureParts { decl: d, body: b, id: id, span: s }
} }
} }
impl FnLikeNode { impl<'a> FnLikeNode<'a> {
pub fn to_fn_parts<'a>(&'a self) -> FnParts<'a> { pub fn to_fn_parts(self) -> FnParts<'a> {
FnParts { FnParts {
decl: self.decl(), decl: self.decl(),
body: self.body(), body: self.body(),
@ -150,31 +150,31 @@ impl FnLikeNode {
} }
} }
pub fn body<'a>(&'a self) -> P<Block> { pub fn body(self) -> &'a Block {
self.handle(|i: ItemFnParts| i.body, self.handle(|i: ItemFnParts<'a>| &*i.body,
|m: &'a ast::Method| m.pe_body(), |m: &'a ast::Method| m.pe_body(),
|c: ClosureParts| c.body) |c: ClosureParts<'a>| c.body)
} }
pub fn decl<'a>(&'a self) -> P<FnDecl> { pub fn decl(self) -> &'a FnDecl {
self.handle(|i: ItemFnParts| i.decl, self.handle(|i: ItemFnParts<'a>| &*i.decl,
|m: &'a ast::Method| m.pe_fn_decl(), |m: &'a ast::Method| m.pe_fn_decl(),
|c: ClosureParts| c.decl) |c: ClosureParts<'a>| c.decl)
} }
pub fn span<'a>(&'a self) -> Span { pub fn span(self) -> Span {
self.handle(|i: ItemFnParts| i.span, self.handle(|i: ItemFnParts| i.span,
|m: &'a ast::Method| m.span, |m: &'a ast::Method| m.span,
|c: ClosureParts| c.span) |c: ClosureParts| c.span)
} }
pub fn id<'a>(&'a self) -> NodeId { pub fn id(self) -> NodeId {
self.handle(|i: ItemFnParts| i.id, self.handle(|i: ItemFnParts| i.id,
|m: &'a ast::Method| m.id, |m: &'a ast::Method| m.id,
|c: ClosureParts| c.id) |c: ClosureParts| c.id)
} }
pub fn kind<'a>(&'a self) -> visit::FnKind<'a> { pub fn kind(self) -> visit::FnKind<'a> {
let item = |p: ItemFnParts<'a>| -> visit::FnKind<'a> { let item = |p: ItemFnParts<'a>| -> visit::FnKind<'a> {
visit::FkItemFn(p.ident, p.generics, p.style, p.abi) visit::FkItemFn(p.ident, p.generics, p.style, p.abi)
}; };
@ -187,33 +187,33 @@ impl FnLikeNode {
self.handle(item, method, closure) self.handle(item, method, closure)
} }
fn handle<'a, A>(&'a self, fn handle<A>(self,
item_fn: |ItemFnParts<'a>| -> A, item_fn: |ItemFnParts<'a>| -> A,
method: |&'a ast::Method| -> A, method: |&'a ast::Method| -> A,
closure: |ClosureParts| -> A) -> A { closure: |ClosureParts<'a>| -> A) -> A {
match self.node { match self.node {
ast_map::NodeItem(ref i) => match i.node { ast_map::NodeItem(i) => match i.node {
ast::ItemFn(decl, style, abi, ref generics, block) => ast::ItemFn(ref decl, style, abi, ref generics, ref block) =>
item_fn(ItemFnParts{ item_fn(ItemFnParts{
ident: i.ident, decl: decl, style: style, body: block, ident: i.ident, decl: &**decl, style: style, body: &**block,
generics: generics, abi: abi, id: i.id, span: i.span generics: generics, abi: abi, id: i.id, span: i.span
}), }),
_ => fail!("item FnLikeNode that is not fn-like"), _ => fail!("item FnLikeNode that is not fn-like"),
}, },
ast_map::NodeTraitItem(ref t) => match **t { ast_map::NodeTraitItem(t) => match *t {
ast::ProvidedMethod(ref m) => method(&**m), ast::ProvidedMethod(ref m) => method(&**m),
_ => fail!("trait method FnLikeNode that is not fn-like"), _ => fail!("trait method FnLikeNode that is not fn-like"),
}, },
ast_map::NodeImplItem(ref ii) => { ast_map::NodeImplItem(ii) => {
match **ii { match *ii {
ast::MethodImplItem(ref m) => method(&**m), ast::MethodImplItem(ref m) => method(&**m),
} }
} }
ast_map::NodeExpr(ref e) => match e.node { ast_map::NodeExpr(e) => match e.node {
ast::ExprFnBlock(_, ref decl, ref block) => ast::ExprFnBlock(_, ref decl, ref block) =>
closure(ClosureParts::new(*decl, *block, e.id, e.span)), closure(ClosureParts::new(&**decl, &**block, e.id, e.span)),
ast::ExprProc(ref decl, ref block) => ast::ExprProc(ref decl, ref block) =>
closure(ClosureParts::new(*decl, *block, e.id, e.span)), closure(ClosureParts::new(&**decl, &**block, e.id, e.span)),
_ => fail!("expr FnLikeNode that is not fn-like"), _ => fail!("expr FnLikeNode that is not fn-like"),
}, },
_ => fail!("other FnLikeNode that is not fn-like"), _ => fail!("other FnLikeNode that is not fn-like"),

View file

@ -19,12 +19,12 @@ use codemap::Span;
use owned_slice::OwnedSlice; use owned_slice::OwnedSlice;
use parse::token; use parse::token;
use print::pprust; use print::pprust;
use ptr::P;
use visit::Visitor; use visit::Visitor;
use visit; use visit;
use std::cell::Cell; use std::cell::Cell;
use std::cmp; use std::cmp;
use std::gc::{Gc, GC};
use std::u32; use std::u32;
pub fn path_name_i(idents: &[Ident]) -> String { pub fn path_name_i(idents: &[Ident]) -> String {
@ -98,7 +98,7 @@ pub fn unop_to_string(op: UnOp) -> &'static str {
} }
} }
pub fn is_path(e: Gc<Expr>) -> bool { pub fn is_path(e: P<Expr>) -> bool {
return match e.node { ExprPath(_) => true, _ => false }; return match e.node { ExprPath(_) => true, _ => false };
} }
@ -166,21 +166,6 @@ pub fn float_ty_to_string(t: FloatTy) -> String {
} }
} }
pub fn is_call_expr(e: Gc<Expr>) -> bool {
match e.node { ExprCall(..) => true, _ => false }
}
pub fn block_from_expr(e: Gc<Expr>) -> P<Block> {
P(Block {
view_items: Vec::new(),
stmts: Vec::new(),
expr: Some(e),
id: e.id,
rules: DefaultBlock,
span: e.span
})
}
// convert a span and an identifier to the corresponding // convert a span and an identifier to the corresponding
// 1-segment path // 1-segment path
pub fn ident_to_path(s: Span, identifier: Ident) -> Path { pub fn ident_to_path(s: Span, identifier: Ident) -> Path {
@ -197,10 +182,12 @@ pub fn ident_to_path(s: Span, identifier: Ident) -> Path {
} }
} }
pub fn ident_to_pat(id: NodeId, s: Span, i: Ident) -> Gc<Pat> { pub fn ident_to_pat(id: NodeId, s: Span, i: Ident) -> P<Pat> {
box(GC) ast::Pat { id: id, P(Pat {
node: PatIdent(BindByValue(MutImmutable), codemap::Spanned{span:s, node:i}, None), id: id,
span: s } node: PatIdent(BindByValue(MutImmutable), codemap::Spanned{span:s, node:i}, None),
span: s
})
} }
pub fn name_to_dummy_lifetime(name: Name) -> Lifetime { pub fn name_to_dummy_lifetime(name: Name) -> Lifetime {
@ -226,57 +213,6 @@ pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
token::gensym_ident(pretty.as_slice()) token::gensym_ident(pretty.as_slice())
} }
pub fn trait_method_to_ty_method(method: &Method) -> TypeMethod {
match method.node {
MethDecl(ident,
ref generics,
abi,
explicit_self,
fn_style,
decl,
_,
vis) => {
TypeMethod {
ident: ident,
attrs: method.attrs.clone(),
fn_style: fn_style,
decl: decl,
generics: generics.clone(),
explicit_self: explicit_self,
id: method.id,
span: method.span,
vis: vis,
abi: abi,
}
},
MethMac(_) => fail!("expected non-macro method declaration")
}
}
/// extract a TypeMethod from a TraitItem. if the TraitItem is
/// a default, pull out the useful fields to make a TypeMethod
//
// NB: to be used only after expansion is complete, and macros are gone.
pub fn trait_item_to_ty_method(method: &TraitItem) -> TypeMethod {
match *method {
RequiredMethod(ref m) => (*m).clone(),
ProvidedMethod(ref m) => trait_method_to_ty_method(&**m),
}
}
pub fn split_trait_methods(trait_methods: &[TraitItem])
-> (Vec<TypeMethod> , Vec<Gc<Method>> ) {
let mut reqd = Vec::new();
let mut provd = Vec::new();
for trt_method in trait_methods.iter() {
match *trt_method {
RequiredMethod(ref tm) => reqd.push((*tm).clone()),
ProvidedMethod(m) => provd.push(m)
}
};
(reqd, provd)
}
pub fn struct_field_visibility(field: ast::StructField) -> Visibility { pub fn struct_field_visibility(field: ast::StructField) -> Visibility {
match field.node.kind { match field.node.kind {
ast::NamedField(_, v) | ast::UnnamedField(v) => v ast::NamedField(_, v) | ast::UnnamedField(v) => v
@ -603,13 +539,6 @@ pub fn compute_id_range_for_fn_body(fk: visit::FnKind,
visitor.result.get() visitor.result.get()
} }
pub fn is_item_impl(item: Gc<ast::Item>) -> bool {
match item.node {
ItemImpl(..) => true,
_ => false
}
}
pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool { pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool {
if !it(pat) { if !it(pat) {
return false; return false;
@ -678,7 +607,7 @@ pub fn struct_def_is_tuple_like(struct_def: &ast::StructDef) -> bool {
/// Returns true if the given pattern consists solely of an identifier /// Returns true if the given pattern consists solely of an identifier
/// and false otherwise. /// and false otherwise.
pub fn pat_is_ident(pat: Gc<ast::Pat>) -> bool { pub fn pat_is_ident(pat: P<ast::Pat>) -> bool {
match pat.node { match pat.node {
ast::PatIdent(..) => true, ast::PatIdent(..) => true,
_ => false, _ => false,
@ -713,28 +642,13 @@ pub fn segments_name_eq(a : &[ast::PathSegment], b : &[ast::PathSegment]) -> boo
} }
/// Returns true if this literal is a string and false otherwise. /// Returns true if this literal is a string and false otherwise.
pub fn lit_is_str(lit: Gc<Lit>) -> bool { pub fn lit_is_str(lit: &Lit) -> bool {
match lit.node { match lit.node {
LitStr(..) => true, LitStr(..) => true,
_ => false, _ => false,
} }
} }
pub fn get_inner_tys(ty: P<Ty>) -> Vec<P<Ty>> {
match ty.node {
ast::TyRptr(_, mut_ty) | ast::TyPtr(mut_ty) => {
vec!(mut_ty.ty)
}
ast::TyBox(ty)
| ast::TyVec(ty)
| ast::TyUniq(ty)
| ast::TyFixedLengthVec(ty, _) => vec!(ty),
ast::TyTup(ref tys) => tys.clone(),
ast::TyParen(ty) => get_inner_tys(ty),
_ => Vec::new()
}
}
/// Returns true if the static with the given mutability and attributes /// Returns true if the static with the given mutability and attributes
/// has a significant address and false otherwise. /// has a significant address and false otherwise.
pub fn static_has_significant_address(mutbl: ast::Mutability, pub fn static_has_significant_address(mutbl: ast::Mutability,
@ -757,13 +671,13 @@ pub trait PostExpansionMethod {
fn pe_abi(&self) -> Abi; fn pe_abi(&self) -> Abi;
fn pe_explicit_self<'a>(&'a self) -> &'a ast::ExplicitSelf; fn pe_explicit_self<'a>(&'a self) -> &'a ast::ExplicitSelf;
fn pe_fn_style(&self) -> ast::FnStyle; fn pe_fn_style(&self) -> ast::FnStyle;
fn pe_fn_decl(&self) -> P<ast::FnDecl>; fn pe_fn_decl<'a>(&'a self) -> &'a ast::FnDecl;
fn pe_body(&self) -> P<ast::Block>; fn pe_body<'a>(&'a self) -> &'a ast::Block;
fn pe_vis(&self) -> ast::Visibility; fn pe_vis(&self) -> ast::Visibility;
} }
macro_rules! mf_method{ macro_rules! mf_method{
($meth_name:ident, $field_ty:ty, $field_pat:pat, $result:ident) => { ($meth_name:ident, $field_ty:ty, $field_pat:pat, $result:expr) => {
fn $meth_name<'a>(&'a self) -> $field_ty { fn $meth_name<'a>(&'a self) -> $field_ty {
match self.node { match self.node {
$field_pat => $result, $field_pat => $result,
@ -784,8 +698,8 @@ impl PostExpansionMethod for Method {
mf_method!(pe_explicit_self,&'a ast::ExplicitSelf, mf_method!(pe_explicit_self,&'a ast::ExplicitSelf,
MethDecl(_,_,_,ref explicit_self,_,_,_,_),explicit_self) MethDecl(_,_,_,ref explicit_self,_,_,_,_),explicit_self)
mf_method!(pe_fn_style,ast::FnStyle,MethDecl(_,_,_,_,fn_style,_,_,_),fn_style) mf_method!(pe_fn_style,ast::FnStyle,MethDecl(_,_,_,_,fn_style,_,_,_),fn_style)
mf_method!(pe_fn_decl,P<ast::FnDecl>,MethDecl(_,_,_,_,_,decl,_,_),decl) mf_method!(pe_fn_decl,&'a ast::FnDecl,MethDecl(_,_,_,_,_,ref decl,_,_),&**decl)
mf_method!(pe_body,P<ast::Block>,MethDecl(_,_,_,_,_,_,body,_),body) mf_method!(pe_body,&'a ast::Block,MethDecl(_,_,_,_,_,_,ref body,_),&**body)
mf_method!(pe_vis,ast::Visibility,MethDecl(_,_,_,_,_,_,_,vis),vis) mf_method!(pe_vis,ast::Visibility,MethDecl(_,_,_,_,_,_,_,vis),vis)
} }

View file

@ -18,10 +18,10 @@ use diagnostic::SpanHandler;
use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
use parse::token::InternedString; use parse::token::InternedString;
use parse::token; use parse::token;
use ptr::P;
use std::collections::HashSet; use std::collections::HashSet;
use std::collections::BitvSet; use std::collections::BitvSet;
use std::gc::{Gc, GC};
local_data_key!(used_attrs: BitvSet) local_data_key!(used_attrs: BitvSet)
@ -50,7 +50,7 @@ pub trait AttrMetaMethods {
/// containing a string, otherwise None. /// containing a string, otherwise None.
fn value_str(&self) -> Option<InternedString>; fn value_str(&self) -> Option<InternedString>;
/// Gets a list of inner meta items from a list MetaItem type. /// Gets a list of inner meta items from a list MetaItem type.
fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<MetaItem>]>; fn meta_item_list<'a>(&'a self) -> Option<&'a [P<MetaItem>]>;
} }
impl AttrMetaMethods for Attribute { impl AttrMetaMethods for Attribute {
@ -65,7 +65,7 @@ impl AttrMetaMethods for Attribute {
fn value_str(&self) -> Option<InternedString> { fn value_str(&self) -> Option<InternedString> {
self.meta().value_str() self.meta().value_str()
} }
fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<MetaItem>]> { fn meta_item_list<'a>(&'a self) -> Option<&'a [P<MetaItem>]> {
self.node.value.meta_item_list() self.node.value.meta_item_list()
} }
} }
@ -91,7 +91,7 @@ impl AttrMetaMethods for MetaItem {
} }
} }
fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<MetaItem>]> { fn meta_item_list<'a>(&'a self) -> Option<&'a [P<MetaItem>]> {
match self.node { match self.node {
MetaList(_, ref l) => Some(l.as_slice()), MetaList(_, ref l) => Some(l.as_slice()),
_ => None _ => None
@ -100,30 +100,30 @@ impl AttrMetaMethods for MetaItem {
} }
// Annoying, but required to get test_cfg to work // Annoying, but required to get test_cfg to work
impl AttrMetaMethods for Gc<MetaItem> { impl AttrMetaMethods for P<MetaItem> {
fn name(&self) -> InternedString { (**self).name() } fn name(&self) -> InternedString { (**self).name() }
fn value_str(&self) -> Option<InternedString> { (**self).value_str() } fn value_str(&self) -> Option<InternedString> { (**self).value_str() }
fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<MetaItem>]> { fn meta_item_list<'a>(&'a self) -> Option<&'a [P<MetaItem>]> {
(**self).meta_item_list() (**self).meta_item_list()
} }
} }
pub trait AttributeMethods { pub trait AttributeMethods {
fn meta(&self) -> Gc<MetaItem>; fn meta<'a>(&'a self) -> &'a MetaItem;
fn desugar_doc(&self) -> Attribute; fn with_desugared_doc<T>(&self, f: |&Attribute| -> T) -> T;
} }
impl AttributeMethods for Attribute { impl AttributeMethods for Attribute {
/// Extract the MetaItem from inside this Attribute. /// Extract the MetaItem from inside this Attribute.
fn meta(&self) -> Gc<MetaItem> { fn meta<'a>(&'a self) -> &'a MetaItem {
self.node.value &*self.node.value
} }
/// Convert self to a normal #[doc="foo"] comment, if it is a /// Convert self to a normal #[doc="foo"] comment, if it is a
/// comment like `///` or `/** */`. (Returns self unchanged for /// comment like `///` or `/** */`. (Returns self unchanged for
/// non-sugared doc attributes.) /// non-sugared doc attributes.)
fn desugar_doc(&self) -> Attribute { fn with_desugared_doc<T>(&self, f: |&Attribute| -> T) -> T {
if self.node.is_sugared_doc { if self.node.is_sugared_doc {
let comment = self.value_str().unwrap(); let comment = self.value_str().unwrap();
let meta = mk_name_value_item_str( let meta = mk_name_value_item_str(
@ -131,12 +131,12 @@ impl AttributeMethods for Attribute {
token::intern_and_get_ident(strip_doc_comment_decoration( token::intern_and_get_ident(strip_doc_comment_decoration(
comment.get()).as_slice())); comment.get()).as_slice()));
if self.node.style == ast::AttrOuter { if self.node.style == ast::AttrOuter {
mk_attr_outer(self.node.id, meta) f(&mk_attr_outer(self.node.id, meta))
} else { } else {
mk_attr_inner(self.node.id, meta) f(&mk_attr_inner(self.node.id, meta))
} }
} else { } else {
*self f(self)
} }
} }
} }
@ -144,23 +144,22 @@ impl AttributeMethods for Attribute {
/* Constructors */ /* Constructors */
pub fn mk_name_value_item_str(name: InternedString, value: InternedString) pub fn mk_name_value_item_str(name: InternedString, value: InternedString)
-> Gc<MetaItem> { -> P<MetaItem> {
let value_lit = dummy_spanned(ast::LitStr(value, ast::CookedStr)); let value_lit = dummy_spanned(ast::LitStr(value, ast::CookedStr));
mk_name_value_item(name, value_lit) mk_name_value_item(name, value_lit)
} }
pub fn mk_name_value_item(name: InternedString, value: ast::Lit) pub fn mk_name_value_item(name: InternedString, value: ast::Lit)
-> Gc<MetaItem> { -> P<MetaItem> {
box(GC) dummy_spanned(MetaNameValue(name, value)) P(dummy_spanned(MetaNameValue(name, value)))
} }
pub fn mk_list_item(name: InternedString, pub fn mk_list_item(name: InternedString, items: Vec<P<MetaItem>>) -> P<MetaItem> {
items: Vec<Gc<MetaItem>>) -> Gc<MetaItem> { P(dummy_spanned(MetaList(name, items)))
box(GC) dummy_spanned(MetaList(name, items))
} }
pub fn mk_word_item(name: InternedString) -> Gc<MetaItem> { pub fn mk_word_item(name: InternedString) -> P<MetaItem> {
box(GC) dummy_spanned(MetaWord(name)) P(dummy_spanned(MetaWord(name)))
} }
local_data_key!(next_attr_id: uint) local_data_key!(next_attr_id: uint)
@ -172,7 +171,7 @@ pub fn mk_attr_id() -> AttrId {
} }
/// Returns an inner attribute with the given value. /// Returns an inner attribute with the given value.
pub fn mk_attr_inner(id: AttrId, item: Gc<MetaItem>) -> Attribute { pub fn mk_attr_inner(id: AttrId, item: P<MetaItem>) -> Attribute {
dummy_spanned(Attribute_ { dummy_spanned(Attribute_ {
id: id, id: id,
style: ast::AttrInner, style: ast::AttrInner,
@ -182,7 +181,7 @@ pub fn mk_attr_inner(id: AttrId, item: Gc<MetaItem>) -> Attribute {
} }
/// Returns an outer attribute with the given value. /// Returns an outer attribute with the given value.
pub fn mk_attr_outer(id: AttrId, item: Gc<MetaItem>) -> Attribute { pub fn mk_attr_outer(id: AttrId, item: P<MetaItem>) -> Attribute {
dummy_spanned(Attribute_ { dummy_spanned(Attribute_ {
id: id, id: id,
style: ast::AttrOuter, style: ast::AttrOuter,
@ -199,8 +198,8 @@ pub fn mk_sugared_doc_attr(id: AttrId, text: InternedString, lo: BytePos,
let attr = Attribute_ { let attr = Attribute_ {
id: id, id: id,
style: style, style: style,
value: box(GC) spanned(lo, hi, MetaNameValue(InternedString::new("doc"), value: P(spanned(lo, hi, MetaNameValue(InternedString::new("doc"),
lit)), lit))),
is_sugared_doc: true is_sugared_doc: true
}; };
spanned(lo, hi, attr) spanned(lo, hi, attr)
@ -210,8 +209,7 @@ pub fn mk_sugared_doc_attr(id: AttrId, text: InternedString, lo: BytePos,
/// Check if `needle` occurs in `haystack` by a structural /// Check if `needle` occurs in `haystack` by a structural
/// comparison. This is slightly subtle, and relies on ignoring the /// comparison. This is slightly subtle, and relies on ignoring the
/// span included in the `==` comparison a plain MetaItem. /// span included in the `==` comparison a plain MetaItem.
pub fn contains(haystack: &[Gc<ast::MetaItem>], pub fn contains(haystack: &[P<MetaItem>], needle: &MetaItem) -> bool {
needle: Gc<ast::MetaItem>) -> bool {
debug!("attr::contains (name={})", needle.name()); debug!("attr::contains (name={})", needle.name());
haystack.iter().any(|item| { haystack.iter().any(|item| {
debug!(" testing: {}", item.name()); debug!(" testing: {}", item.name());
@ -234,7 +232,7 @@ pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str)
.and_then(|at| at.value_str()) .and_then(|at| at.value_str())
} }
pub fn last_meta_item_value_str_by_name(items: &[Gc<MetaItem>], name: &str) pub fn last_meta_item_value_str_by_name(items: &[P<MetaItem>], name: &str)
-> Option<InternedString> { -> Option<InternedString> {
items.iter() items.iter()
.rev() .rev()
@ -244,28 +242,25 @@ pub fn last_meta_item_value_str_by_name(items: &[Gc<MetaItem>], name: &str)
/* Higher-level applications */ /* Higher-level applications */
pub fn sort_meta_items(items: &[Gc<MetaItem>]) -> Vec<Gc<MetaItem>> { pub fn sort_meta_items(items: Vec<P<MetaItem>>) -> Vec<P<MetaItem>> {
// This is sort of stupid here, but we need to sort by // This is sort of stupid here, but we need to sort by
// human-readable strings. // human-readable strings.
let mut v = items.iter() let mut v = items.move_iter()
.map(|&mi| (mi.name(), mi)) .map(|mi| (mi.name(), mi))
.collect::<Vec<(InternedString, Gc<MetaItem>)> >(); .collect::<Vec<(InternedString, P<MetaItem>)>>();
v.sort_by(|&(ref a, _), &(ref b, _)| a.cmp(b)); v.sort_by(|&(ref a, _), &(ref b, _)| a.cmp(b));
// There doesn't seem to be a more optimal way to do this // There doesn't seem to be a more optimal way to do this
v.move_iter().map(|(_, m)| { v.move_iter().map(|(_, m)| m.map(|Spanned {node, span}| {
match m.node { Spanned {
MetaList(ref n, ref mis) => { node: match node {
box(GC) Spanned { MetaList(n, mis) => MetaList(n, sort_meta_items(mis)),
node: MetaList((*n).clone(), _ => node
sort_meta_items(mis.as_slice())), },
.. /*bad*/ (*m).clone() span: span
}
}
_ => m
} }
}).collect() })).collect()
} }
pub fn find_crate_name(attrs: &[Attribute]) -> Option<InternedString> { pub fn find_crate_name(attrs: &[Attribute]) -> Option<InternedString> {
@ -318,8 +313,8 @@ pub fn requests_inline(attrs: &[Attribute]) -> bool {
/// test_cfg(`[foo="a", bar]`, `[cfg(not(bar))]`) == false /// test_cfg(`[foo="a", bar]`, `[cfg(not(bar))]`) == false
/// test_cfg(`[foo="a", bar]`, `[cfg(bar, foo="a")]`) == true /// test_cfg(`[foo="a", bar]`, `[cfg(bar, foo="a")]`) == true
/// test_cfg(`[foo="a", bar]`, `[cfg(bar, foo="b")]`) == false /// test_cfg(`[foo="a", bar]`, `[cfg(bar, foo="b")]`) == false
pub fn test_cfg<AM: AttrMetaMethods, It: Iterator<AM>> pub fn test_cfg<'a, AM: AttrMetaMethods, It: Iterator<&'a AM>>
(cfg: &[Gc<MetaItem>], mut metas: It) -> bool { (cfg: &[P<MetaItem>], mut metas: It) -> bool {
// having no #[cfg(...)] attributes counts as matching. // having no #[cfg(...)] attributes counts as matching.
let mut no_cfgs = true; let mut no_cfgs = true;
@ -344,10 +339,10 @@ pub fn test_cfg<AM: AttrMetaMethods, It: Iterator<AM>>
// not match. // not match.
!not_cfgs.iter().all(|mi| { !not_cfgs.iter().all(|mi| {
debug!("cfg(not({}[...]))", mi.name()); debug!("cfg(not({}[...]))", mi.name());
contains(cfg, *mi) contains(cfg, &**mi)
}) })
} }
_ => contains(cfg, *cfg_mi) _ => contains(cfg, &**cfg_mi)
} }
}) })
} }
@ -397,7 +392,7 @@ pub fn find_stability_generic<'a,
}; };
return Some((Stability { return Some((Stability {
level: level, level: level,
text: attr.value_str() text: attr.value_str()
}, attr)); }, attr));
} }
@ -412,7 +407,7 @@ pub fn find_stability(attrs: &[Attribute]) -> Option<Stability> {
}) })
} }
pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[Gc<MetaItem>]) { pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[P<MetaItem>]) {
let mut set = HashSet::new(); let mut set = HashSet::new();
for meta in metas.iter() { for meta in metas.iter() {
let name = meta.name(); let name = meta.name();

View file

@ -543,10 +543,9 @@ fn print_macro_backtrace(w: &mut EmitterWriter,
Ok(()) Ok(())
} }
pub fn expect<T:Clone>(diag: &SpanHandler, opt: Option<T>, msg: || -> String) pub fn expect<T>(diag: &SpanHandler, opt: Option<T>, msg: || -> String) -> T {
-> T {
match opt { match opt {
Some(ref t) => (*t).clone(), Some(t) => t,
None => diag.handler().bug(msg().as_slice()), None => diag.handler().bug(msg().as_slice()),
} }
} }

View file

@ -10,13 +10,13 @@
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use std::gc::Gc;
use ast; use ast;
use ast::{Ident, Name, TokenTree}; use ast::{Ident, Name, TokenTree};
use codemap::Span; use codemap::Span;
use ext::base::{ExtCtxt, MacExpr, MacItem, MacResult}; use ext::base::{ExtCtxt, MacExpr, MacItem, MacResult};
use ext::build::AstBuilder; use ext::build::AstBuilder;
use parse::token; use parse::token;
use ptr::P;
local_data_key!(registered_diagnostics: RefCell<HashMap<Name, Option<Name>>>) local_data_key!(registered_diagnostics: RefCell<HashMap<Name, Option<Name>>>)
local_data_key!(used_diagnostics: RefCell<HashMap<Name, Span>>) local_data_key!(used_diagnostics: RefCell<HashMap<Name, Span>>)
@ -116,7 +116,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
let (count, expr) = with_used_diagnostics(|diagnostics_in_use| { let (count, expr) = with_used_diagnostics(|diagnostics_in_use| {
with_registered_diagnostics(|diagnostics| { with_registered_diagnostics(|diagnostics| {
let descriptions: Vec<Gc<ast::Expr>> = diagnostics let descriptions: Vec<P<ast::Expr>> = diagnostics
.iter().filter_map(|(code, description)| { .iter().filter_map(|(code, description)| {
if !diagnostics_in_use.contains_key(code) { if !diagnostics_in_use.contains_key(code) {
ecx.span_warn(span, format!( ecx.span_warn(span, format!(

View file

@ -18,8 +18,7 @@ use ext::base;
use ext::base::*; use ext::base::*;
use parse::token::InternedString; use parse::token::InternedString;
use parse::token; use parse::token;
use ptr::P;
use std::gc::GC;
enum State { enum State {
Asm, Asm,
@ -199,7 +198,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
} }
} }
MacExpr::new(box(GC) ast::Expr { MacExpr::new(P(ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprInlineAsm(ast::InlineAsm { node: ast::ExprInlineAsm(ast::InlineAsm {
asm: token::intern_and_get_ident(asm.get()), asm: token::intern_and_get_ident(asm.get()),
@ -212,5 +211,5 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
dialect: dialect dialect: dialect
}), }),
span: sp span: sp
}) }))
} }

View file

@ -18,6 +18,7 @@ use parse;
use parse::parser; use parse::parser;
use parse::token; use parse::token;
use parse::token::{InternedString, intern, str_to_ident}; use parse::token::{InternedString, intern, str_to_ident};
use ptr::P;
use util::small_vector::SmallVector; use util::small_vector::SmallVector;
use ext::mtwt; use ext::mtwt;
use fold::Folder; use fold::Folder;
@ -43,18 +44,18 @@ pub trait ItemDecorator {
fn expand(&self, fn expand(&self,
ecx: &mut ExtCtxt, ecx: &mut ExtCtxt,
sp: Span, sp: Span,
meta_item: Gc<ast::MetaItem>, meta_item: &ast::MetaItem,
item: Gc<ast::Item>, item: &ast::Item,
push: |Gc<ast::Item>|); push: |P<ast::Item>|);
} }
impl ItemDecorator for fn(&mut ExtCtxt, Span, Gc<ast::MetaItem>, Gc<ast::Item>, |Gc<ast::Item>|) { impl ItemDecorator for fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, |P<ast::Item>|) {
fn expand(&self, fn expand(&self,
ecx: &mut ExtCtxt, ecx: &mut ExtCtxt,
sp: Span, sp: Span,
meta_item: Gc<ast::MetaItem>, meta_item: &ast::MetaItem,
item: Gc<ast::Item>, item: &ast::Item,
push: |Gc<ast::Item>|) { push: |P<ast::Item>|) {
(*self)(ecx, sp, meta_item, item, push) (*self)(ecx, sp, meta_item, item, push)
} }
} }
@ -63,18 +64,18 @@ pub trait ItemModifier {
fn expand(&self, fn expand(&self,
ecx: &mut ExtCtxt, ecx: &mut ExtCtxt,
span: Span, span: Span,
meta_item: Gc<ast::MetaItem>, meta_item: &ast::MetaItem,
item: Gc<ast::Item>) item: P<ast::Item>)
-> Gc<ast::Item>; -> P<ast::Item>;
} }
impl ItemModifier for fn(&mut ExtCtxt, Span, Gc<ast::MetaItem>, Gc<ast::Item>) -> Gc<ast::Item> { impl ItemModifier for fn(&mut ExtCtxt, Span, &ast::MetaItem, P<ast::Item>) -> P<ast::Item> {
fn expand(&self, fn expand(&self,
ecx: &mut ExtCtxt, ecx: &mut ExtCtxt,
span: Span, span: Span,
meta_item: Gc<ast::MetaItem>, meta_item: &ast::MetaItem,
item: Gc<ast::Item>) item: P<ast::Item>)
-> Gc<ast::Item> { -> P<ast::Item> {
(*self)(ecx, span, meta_item, item) (*self)(ecx, span, meta_item, item)
} }
} }
@ -128,29 +129,29 @@ impl IdentMacroExpander for IdentMacroExpanderFn {
/// methods are spliced into the AST at the callsite of the macro (or /// methods are spliced into the AST at the callsite of the macro (or
/// just into the compiler's internal macro table, for `make_def`). /// just into the compiler's internal macro table, for `make_def`).
pub trait MacResult { pub trait MacResult {
/// Define a new macro. /// Attempt to define a new macro.
// this should go away; the idea that a macro might expand into // this should go away; the idea that a macro might expand into
// either a macro definition or an expression, depending on what // either a macro definition or an expression, depending on what
// the context wants, is kind of silly. // the context wants, is kind of silly.
fn make_def(&self) -> Option<MacroDef> { fn make_def(&mut self) -> Option<MacroDef> {
None None
} }
/// Create an expression. /// Create an expression.
fn make_expr(&self) -> Option<Gc<ast::Expr>> { fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
None None
} }
/// Create zero or more items. /// Create zero or more items.
fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> { fn make_items(self: Box<Self>) -> Option<SmallVector<P<ast::Item>>> {
None None
} }
/// Create zero or more methods. /// Create zero or more methods.
fn make_methods(&self) -> Option<SmallVector<Gc<ast::Method>>> { fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::Method>>> {
None None
} }
/// Create a pattern. /// Create a pattern.
fn make_pat(&self) -> Option<Gc<ast::Pat>> { fn make_pat(self: Box<Self>) -> Option<P<ast::Pat>> {
None None
} }
@ -158,69 +159,69 @@ pub trait MacResult {
/// ///
/// By default this attempts to create an expression statement, /// By default this attempts to create an expression statement,
/// returning None if that fails. /// returning None if that fails.
fn make_stmt(&self) -> Option<Gc<ast::Stmt>> { fn make_stmt(self: Box<Self>) -> Option<P<ast::Stmt>> {
self.make_expr() self.make_expr()
.map(|e| box(GC) codemap::respan(e.span, ast::StmtExpr(e, ast::DUMMY_NODE_ID))) .map(|e| P(codemap::respan(e.span, ast::StmtExpr(e, ast::DUMMY_NODE_ID))))
} }
} }
/// A convenience type for macros that return a single expression. /// A convenience type for macros that return a single expression.
pub struct MacExpr { pub struct MacExpr {
e: Gc<ast::Expr>, e: P<ast::Expr>
} }
impl MacExpr { impl MacExpr {
pub fn new(e: Gc<ast::Expr>) -> Box<MacResult+'static> { pub fn new(e: P<ast::Expr>) -> Box<MacResult+'static> {
box MacExpr { e: e } as Box<MacResult+'static> box MacExpr { e: e } as Box<MacResult+'static>
} }
} }
impl MacResult for MacExpr { impl MacResult for MacExpr {
fn make_expr(&self) -> Option<Gc<ast::Expr>> { fn make_expr(self: Box<MacExpr>) -> Option<P<ast::Expr>> {
Some(self.e) Some(self.e)
} }
fn make_pat(&self) -> Option<Gc<ast::Pat>> { fn make_pat(self: Box<MacExpr>) -> Option<P<ast::Pat>> {
match self.e.node { match self.e.node {
ast::ExprLit(_) => Some(box(GC) ast::Pat { ast::ExprLit(_) => Some(P(ast::Pat {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::PatLit(self.e), span: self.e.span,
span: self.e.span node: ast::PatLit(self.e)
}), })),
_ => None _ => None
} }
} }
} }
/// A convenience type for macros that return a single pattern. /// A convenience type for macros that return a single pattern.
pub struct MacPat { pub struct MacPat {
p: Gc<ast::Pat>, p: P<ast::Pat>
} }
impl MacPat { impl MacPat {
pub fn new(p: Gc<ast::Pat>) -> Box<MacResult+'static> { pub fn new(p: P<ast::Pat>) -> Box<MacResult+'static> {
box MacPat { p: p } as Box<MacResult+'static> box MacPat { p: p } as Box<MacResult+'static>
} }
} }
impl MacResult for MacPat { impl MacResult for MacPat {
fn make_pat(&self) -> Option<Gc<ast::Pat>> { fn make_pat(self: Box<MacPat>) -> Option<P<ast::Pat>> {
Some(self.p) Some(self.p)
} }
} }
/// A convenience type for macros that return a single item. /// A convenience type for macros that return a single item.
pub struct MacItem { pub struct MacItem {
i: Gc<ast::Item> i: P<ast::Item>
} }
impl MacItem { impl MacItem {
pub fn new(i: Gc<ast::Item>) -> Box<MacResult+'static> { pub fn new(i: P<ast::Item>) -> Box<MacResult+'static> {
box MacItem { i: i } as Box<MacResult+'static> box MacItem { i: i } as Box<MacResult+'static>
} }
} }
impl MacResult for MacItem { impl MacResult for MacItem {
fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> { fn make_items(self: Box<MacItem>) -> Option<SmallVector<P<ast::Item>>> {
Some(SmallVector::one(self.i)) Some(SmallVector::one(self.i))
} }
fn make_stmt(&self) -> Option<Gc<ast::Stmt>> { fn make_stmt(self: Box<MacItem>) -> Option<P<ast::Stmt>> {
Some(box(GC) codemap::respan( Some(P(codemap::respan(
self.i.span, self.i.span,
ast::StmtDecl( ast::StmtDecl(
box(GC) codemap::respan(self.i.span, ast::DeclItem(self.i)), P(codemap::respan(self.i.span, ast::DeclItem(self.i))),
ast::DUMMY_NODE_ID))) ast::DUMMY_NODE_ID))))
} }
} }
@ -250,17 +251,17 @@ impl DummyResult {
} }
/// A plain dummy expression. /// A plain dummy expression.
pub fn raw_expr(sp: Span) -> Gc<ast::Expr> { pub fn raw_expr(sp: Span) -> P<ast::Expr> {
box(GC) ast::Expr { P(ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprLit(box(GC) codemap::respan(sp, ast::LitNil)), node: ast::ExprLit(P(codemap::respan(sp, ast::LitNil))),
span: sp, span: sp,
} })
} }
/// A plain dummy pattern. /// A plain dummy pattern.
pub fn raw_pat(sp: Span) -> Gc<ast::Pat> { pub fn raw_pat(sp: Span) -> ast::Pat {
box(GC) ast::Pat { ast::Pat {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::PatWild(ast::PatWildSingle), node: ast::PatWild(ast::PatWildSingle),
span: sp, span: sp,
@ -270,13 +271,13 @@ impl DummyResult {
} }
impl MacResult for DummyResult { impl MacResult for DummyResult {
fn make_expr(&self) -> Option<Gc<ast::Expr>> { fn make_expr(self: Box<DummyResult>) -> Option<P<ast::Expr>> {
Some(DummyResult::raw_expr(self.span)) Some(DummyResult::raw_expr(self.span))
} }
fn make_pat(&self) -> Option<Gc<ast::Pat>> { fn make_pat(self: Box<DummyResult>) -> Option<P<ast::Pat>> {
Some(DummyResult::raw_pat(self.span)) Some(P(DummyResult::raw_pat(self.span)))
} }
fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> { fn make_items(self: Box<DummyResult>) -> Option<SmallVector<P<ast::Item>>> {
// this code needs a comment... why not always just return the Some() ? // this code needs a comment... why not always just return the Some() ?
if self.expr_only { if self.expr_only {
None None
@ -284,17 +285,17 @@ impl MacResult for DummyResult {
Some(SmallVector::zero()) Some(SmallVector::zero())
} }
} }
fn make_methods(&self) -> Option<SmallVector<Gc<ast::Method>>> { fn make_methods(self: Box<DummyResult>) -> Option<SmallVector<P<ast::Method>>> {
if self.expr_only { if self.expr_only {
None None
} else { } else {
Some(SmallVector::zero()) Some(SmallVector::zero())
} }
} }
fn make_stmt(&self) -> Option<Gc<ast::Stmt>> { fn make_stmt(self: Box<DummyResult>) -> Option<P<ast::Stmt>> {
Some(box(GC) codemap::respan(self.span, Some(P(codemap::respan(self.span,
ast::StmtExpr(DummyResult::raw_expr(self.span), ast::StmtExpr(DummyResult::raw_expr(self.span),
ast::DUMMY_NODE_ID))) ast::DUMMY_NODE_ID))))
} }
} }
@ -461,7 +462,7 @@ pub struct ExtCtxt<'a> {
pub mod_path: Vec<ast::Ident> , pub mod_path: Vec<ast::Ident> ,
pub trace_mac: bool, pub trace_mac: bool,
pub exported_macros: Vec<Gc<ast::Item>>, pub exported_macros: Vec<P<ast::Item>>,
pub syntax_env: SyntaxEnv, pub syntax_env: SyntaxEnv,
} }
@ -482,7 +483,7 @@ impl<'a> ExtCtxt<'a> {
} }
#[deprecated = "Replaced with `expander().fold_expr()`"] #[deprecated = "Replaced with `expander().fold_expr()`"]
pub fn expand_expr(&mut self, e: Gc<ast::Expr>) -> Gc<ast::Expr> { pub fn expand_expr(&mut self, e: P<ast::Expr>) -> P<ast::Expr> {
self.expander().fold_expr(e) self.expander().fold_expr(e)
} }
@ -595,12 +596,12 @@ impl<'a> ExtCtxt<'a> {
/// Extract a string literal from the macro expanded version of `expr`, /// Extract a string literal from the macro expanded version of `expr`,
/// emitting `err_msg` if `expr` is not a string literal. This does not stop /// emitting `err_msg` if `expr` is not a string literal. This does not stop
/// compilation on error, merely emits a non-fatal error and returns None. /// compilation on error, merely emits a non-fatal error and returns None.
pub fn expr_to_string(cx: &mut ExtCtxt, expr: Gc<ast::Expr>, err_msg: &str) pub fn expr_to_string(cx: &mut ExtCtxt, expr: P<ast::Expr>, err_msg: &str)
-> Option<(InternedString, ast::StrStyle)> { -> Option<(InternedString, ast::StrStyle)> {
// we want to be able to handle e.g. concat("foo", "bar") // we want to be able to handle e.g. concat("foo", "bar")
let expr = cx.expander().fold_expr(expr); let expr = cx.expander().fold_expr(expr);
match expr.node { match expr.node {
ast::ExprLit(l) => match l.node { ast::ExprLit(ref l) => match l.node {
ast::LitStr(ref s, style) => return Some(((*s).clone(), style)), ast::LitStr(ref s, style) => return Some(((*s).clone(), style)),
_ => cx.span_err(l.span, err_msg) _ => cx.span_err(l.span, err_msg)
}, },
@ -651,7 +652,7 @@ pub fn get_single_str_from_tts(cx: &ExtCtxt,
/// parsing error, emit a non-fatal error and return None. /// parsing error, emit a non-fatal error and return None.
pub fn get_exprs_from_tts(cx: &mut ExtCtxt, pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
sp: Span, sp: Span,
tts: &[ast::TokenTree]) -> Option<Vec<Gc<ast::Expr>>> { tts: &[ast::TokenTree]) -> Option<Vec<P<ast::Expr>>> {
let mut p = cx.new_parser_from_tts(tts); let mut p = cx.new_parser_from_tts(tts);
let mut es = Vec::new(); let mut es = Vec::new();
while p.token != token::EOF { while p.token != token::EOF {

File diff suppressed because it is too large Load diff

View file

@ -40,7 +40,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
for expr in exprs.iter() { for expr in exprs.iter() {
match expr.node { match expr.node {
// expression is a literal // expression is a literal
ast::ExprLit(lit) => match lit.node { ast::ExprLit(ref lit) => match lit.node {
// string literal, push each byte to vector expression // string literal, push each byte to vector expression
ast::LitStr(ref s, _) => { ast::LitStr(ref s, _) => {
for byte in s.get().bytes() { for byte in s.get().bytes() {

View file

@ -40,10 +40,10 @@ pub fn expand_cfg<'cx>(cx: &mut ExtCtxt,
} }
// test_cfg searches for meta items looking like `cfg(foo, ...)` // test_cfg searches for meta items looking like `cfg(foo, ...)`
let in_cfg = &[cx.meta_list(sp, InternedString::new("cfg"), cfgs)]; let in_cfg = Some(cx.meta_list(sp, InternedString::new("cfg"), cfgs));
let matches_cfg = attr::test_cfg(cx.cfg().as_slice(), let matches_cfg = attr::test_cfg(cx.cfg().as_slice(),
in_cfg.iter().map(|&x| x)); in_cfg.iter());
let e = cx.expr_bool(sp, matches_cfg); let e = cx.expr_bool(sp, matches_cfg);
MacExpr::new(e) MacExpr::new(e)
} }

View file

@ -27,7 +27,7 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
let mut accumulator = String::new(); let mut accumulator = String::new();
for e in es.move_iter() { for e in es.move_iter() {
match e.node { match e.node {
ast::ExprLit(lit) => { ast::ExprLit(ref lit) => {
match lit.node { match lit.node {
ast::LitStr(ref s, _) | ast::LitStr(ref s, _) |
ast::LitFloat(ref s, _) | ast::LitFloat(ref s, _) |

View file

@ -15,8 +15,7 @@ use ext::base;
use owned_slice::OwnedSlice; use owned_slice::OwnedSlice;
use parse::token; use parse::token;
use parse::token::{str_to_ident}; use parse::token::{str_to_ident};
use ptr::P;
use std::gc::GC;
pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> Box<base::MacResult+'cx> { -> Box<base::MacResult+'cx> {
@ -44,7 +43,7 @@ pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]
} }
let res = str_to_ident(res_str.as_slice()); let res = str_to_ident(res_str.as_slice());
let e = box(GC) ast::Expr { let e = P(ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprPath( node: ast::ExprPath(
ast::Path { ast::Path {
@ -60,6 +59,6 @@ pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]
} }
), ),
span: sp, span: sp,
}; });
MacExpr::new(e) MacExpr::new(e)
} }

View file

@ -13,14 +13,13 @@ use codemap::Span;
use ext::base::ExtCtxt; use ext::base::ExtCtxt;
use ext::deriving::generic::*; use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use ptr::P;
use std::gc::Gc;
pub fn expand_deriving_bound(cx: &mut ExtCtxt, pub fn expand_deriving_bound(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: Gc<MetaItem>, mitem: &MetaItem,
item: Gc<Item>, item: &Item,
push: |Gc<Item>|) { push: |P<Item>|) {
let name = match mitem.node { let name = match mitem.node {
MetaWord(ref tname) => { MetaWord(ref tname) => {

View file

@ -15,14 +15,13 @@ use ext::build::AstBuilder;
use ext::deriving::generic::*; use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use ptr::P;
use std::gc::Gc;
pub fn expand_deriving_clone(cx: &mut ExtCtxt, pub fn expand_deriving_clone(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: Gc<MetaItem>, mitem: &MetaItem,
item: Gc<Item>, item: &Item,
push: |Gc<Item>|) { push: |P<Item>|) {
let inline = cx.meta_word(span, InternedString::new("inline")); let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline)); let attrs = vec!(cx.attribute(span, inline));
let trait_def = TraitDef { let trait_def = TraitDef {
@ -52,12 +51,12 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt,
fn cs_clone( fn cs_clone(
name: &str, name: &str,
cx: &mut ExtCtxt, trait_span: Span, cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> Gc<Expr> { substr: &Substructure) -> P<Expr> {
let clone_ident = substr.method_ident; let clone_ident = substr.method_ident;
let ctor_ident; let ctor_ident;
let all_fields; let all_fields;
let subcall = |field: &FieldInfo| let subcall = |field: &FieldInfo|
cx.expr_method_call(field.span, field.self_, clone_ident, Vec::new()); cx.expr_method_call(field.span, field.self_.clone(), clone_ident, Vec::new());
match *substr.fields { match *substr.fields {
Struct(ref af) => { Struct(ref af) => {

View file

@ -15,21 +15,20 @@ use ext::build::AstBuilder;
use ext::deriving::generic::*; use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use ptr::P;
use std::gc::Gc;
pub fn expand_deriving_eq(cx: &mut ExtCtxt, pub fn expand_deriving_eq(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: Gc<MetaItem>, mitem: &MetaItem,
item: Gc<Item>, item: &Item,
push: |Gc<Item>|) { push: |P<Item>|) {
// structures are equal if all fields are equal, and non equal, if // structures are equal if all fields are equal, and non equal, if
// any fields are not equal or if the enum variants are different // any fields are not equal or if the enum variants are different
fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> Gc<Expr> { fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
cs_and(|cx, span, _, _| cx.expr_bool(span, false), cs_and(|cx, span, _, _| cx.expr_bool(span, false),
cx, span, substr) cx, span, substr)
} }
fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> Gc<Expr> { fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
cs_or(|cx, span, _, _| cx.expr_bool(span, true), cs_or(|cx, span, _, _| cx.expr_bool(span, true),
cx, span, substr) cx, span, substr)
} }

View file

@ -16,14 +16,13 @@ use ext::build::AstBuilder;
use ext::deriving::generic::*; use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use ptr::P;
use std::gc::Gc;
pub fn expand_deriving_ord(cx: &mut ExtCtxt, pub fn expand_deriving_ord(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: Gc<MetaItem>, mitem: &MetaItem,
item: Gc<Item>, item: &Item,
push: |Gc<Item>|) { push: |P<Item>|) {
macro_rules! md ( macro_rules! md (
($name:expr, $op:expr, $equal:expr) => { { ($name:expr, $op:expr, $equal:expr) => { {
let inline = cx.meta_word(span, InternedString::new("inline")); let inline = cx.meta_word(span, InternedString::new("inline"));
@ -87,7 +86,7 @@ pub enum OrderingOp {
pub fn some_ordering_collapsed(cx: &mut ExtCtxt, pub fn some_ordering_collapsed(cx: &mut ExtCtxt,
span: Span, span: Span,
op: OrderingOp, op: OrderingOp,
self_arg_tags: &[ast::Ident]) -> Gc<ast::Expr> { self_arg_tags: &[ast::Ident]) -> P<ast::Expr> {
let lft = cx.expr_ident(span, self_arg_tags[0]); let lft = cx.expr_ident(span, self_arg_tags[0]);
let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1])); let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
let op_str = match op { let op_str = match op {
@ -99,7 +98,7 @@ pub fn some_ordering_collapsed(cx: &mut ExtCtxt,
} }
pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span, pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
substr: &Substructure) -> Gc<Expr> { substr: &Substructure) -> P<Expr> {
let test_id = cx.ident_of("__test"); let test_id = cx.ident_of("__test");
let ordering = cx.path_global(span, let ordering = cx.path_global(span,
vec!(cx.ident_of("std"), vec!(cx.ident_of("std"),
@ -159,8 +158,8 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
} }
/// Strict inequality. /// Strict inequality.
fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span, fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt,
substr: &Substructure) -> Gc<Expr> { span: Span, substr: &Substructure) -> P<Expr> {
let op = if less {ast::BiLt} else {ast::BiGt}; let op = if less {ast::BiLt} else {ast::BiGt};
cs_fold( cs_fold(
false, // need foldr, false, // need foldr,
@ -183,14 +182,14 @@ fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span,
layers of pointers, if the type includes pointers. layers of pointers, if the type includes pointers.
*/ */
let other_f = match other_fs { let other_f = match other_fs {
[o_f] => o_f, [ref o_f] => o_f,
_ => cx.span_bug(span, "not exactly 2 arguments in `deriving(Ord)`") _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(Ord)`")
}; };
let cmp = cx.expr_binary(span, op, self_f, other_f); let cmp = cx.expr_binary(span, op, self_f.clone(), other_f.clone());
let not_cmp = cx.expr_unary(span, ast::UnNot, let not_cmp = cx.expr_unary(span, ast::UnNot,
cx.expr_binary(span, op, other_f, self_f)); cx.expr_binary(span, op, other_f.clone(), self_f));
let and = cx.expr_binary(span, ast::BiAnd, not_cmp, subexpr); let and = cx.expr_binary(span, ast::BiAnd, not_cmp, subexpr);
cx.expr_binary(span, ast::BiOr, cmp, and) cx.expr_binary(span, ast::BiOr, cmp, and)

View file

@ -15,16 +15,14 @@ use ext::build::AstBuilder;
use ext::deriving::generic::*; use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use ptr::P;
use std::gc::Gc;
pub fn expand_deriving_totaleq(cx: &mut ExtCtxt, pub fn expand_deriving_totaleq(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: Gc<MetaItem>, mitem: &MetaItem,
item: Gc<Item>, item: &Item,
push: |Gc<Item>|) { push: |P<Item>|) {
fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
substr: &Substructure) -> Gc<Expr> {
cs_same_method(|cx, span, exprs| { cs_same_method(|cx, span, exprs| {
// create `a.<method>(); b.<method>(); c.<method>(); ...` // create `a.<method>(); b.<method>(); c.<method>(); ...`
// (where method is `assert_receiver_is_total_eq`) // (where method is `assert_receiver_is_total_eq`)

View file

@ -16,14 +16,13 @@ use ext::build::AstBuilder;
use ext::deriving::generic::*; use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use ptr::P;
use std::gc::Gc;
pub fn expand_deriving_totalord(cx: &mut ExtCtxt, pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: Gc<MetaItem>, mitem: &MetaItem,
item: Gc<Item>, item: &Item,
push: |Gc<Item>|) { push: |P<Item>|) {
let inline = cx.meta_word(span, InternedString::new("inline")); let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline)); let attrs = vec!(cx.attribute(span, inline));
let trait_def = TraitDef { let trait_def = TraitDef {
@ -53,14 +52,14 @@ pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
pub fn ordering_collapsed(cx: &mut ExtCtxt, pub fn ordering_collapsed(cx: &mut ExtCtxt,
span: Span, span: Span,
self_arg_tags: &[ast::Ident]) -> Gc<ast::Expr> { self_arg_tags: &[ast::Ident]) -> P<ast::Expr> {
let lft = cx.expr_ident(span, self_arg_tags[0]); let lft = cx.expr_ident(span, self_arg_tags[0]);
let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1])); let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
cx.expr_method_call(span, lft, cx.ident_of("cmp"), vec![rgt]) cx.expr_method_call(span, lft, cx.ident_of("cmp"), vec![rgt])
} }
pub fn cs_cmp(cx: &mut ExtCtxt, span: Span, pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
substr: &Substructure) -> Gc<Expr> { substr: &Substructure) -> P<Expr> {
let test_id = cx.ident_of("__test"); let test_id = cx.ident_of("__test");
let equals_path = cx.path_global(span, let equals_path = cx.path_global(span,
vec!(cx.ident_of("std"), vec!(cx.ident_of("std"),

View file

@ -21,14 +21,13 @@ use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use parse::token; use parse::token;
use ptr::P;
use std::gc::Gc;
pub fn expand_deriving_decodable(cx: &mut ExtCtxt, pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: Gc<MetaItem>, mitem: &MetaItem,
item: Gc<Item>, item: &Item,
push: |Gc<Item>|) { push: |P<Item>|) {
let trait_def = TraitDef { let trait_def = TraitDef {
span: span, span: span,
attributes: Vec::new(), attributes: Vec::new(),
@ -64,15 +63,15 @@ pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
} }
fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span, fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> Gc<Expr> { substr: &Substructure) -> P<Expr> {
let decoder = substr.nonself_args[0]; let decoder = substr.nonself_args[0].clone();
let recurse = vec!(cx.ident_of("serialize"), let recurse = vec!(cx.ident_of("serialize"),
cx.ident_of("Decodable"), cx.ident_of("Decodable"),
cx.ident_of("decode")); cx.ident_of("decode"));
// throw an underscore in front to suppress unused variable warnings // throw an underscore in front to suppress unused variable warnings
let blkarg = cx.ident_of("_d"); let blkarg = cx.ident_of("_d");
let blkdecoder = cx.expr_ident(trait_span, blkarg); let blkdecoder = cx.expr_ident(trait_span, blkarg);
let calldecode = cx.expr_call_global(trait_span, recurse, vec!(blkdecoder)); let calldecode = cx.expr_call_global(trait_span, recurse, vec!(blkdecoder.clone()));
let lambdadecode = cx.lambda_expr_1(trait_span, calldecode, blkarg); let lambdadecode = cx.lambda_expr_1(trait_span, calldecode, blkarg);
return match *substr.fields { return match *substr.fields {
@ -89,10 +88,10 @@ fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
summary, summary,
|cx, span, name, field| { |cx, span, name, field| {
cx.expr_try(span, cx.expr_try(span,
cx.expr_method_call(span, blkdecoder, read_struct_field, cx.expr_method_call(span, blkdecoder.clone(), read_struct_field,
vec!(cx.expr_str(span, name), vec!(cx.expr_str(span, name),
cx.expr_uint(span, field), cx.expr_uint(span, field),
lambdadecode))) lambdadecode.clone())))
}); });
let result = cx.expr_ok(trait_span, result); let result = cx.expr_ok(trait_span, result);
cx.expr_method_call(trait_span, cx.expr_method_call(trait_span,
@ -121,8 +120,8 @@ fn decodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
|cx, span, _, field| { |cx, span, _, field| {
let idx = cx.expr_uint(span, field); let idx = cx.expr_uint(span, field);
cx.expr_try(span, cx.expr_try(span,
cx.expr_method_call(span, blkdecoder, rvariant_arg, cx.expr_method_call(span, blkdecoder.clone(), rvariant_arg,
vec!(idx, lambdadecode))) vec!(idx, lambdadecode.clone())))
}); });
arms.push(cx.arm(v_span, arms.push(cx.arm(v_span,
@ -159,8 +158,8 @@ fn decode_static_fields(cx: &mut ExtCtxt,
trait_span: Span, trait_span: Span,
outer_pat_ident: Ident, outer_pat_ident: Ident,
fields: &StaticFields, fields: &StaticFields,
getarg: |&mut ExtCtxt, Span, InternedString, uint| -> Gc<Expr>) getarg: |&mut ExtCtxt, Span, InternedString, uint| -> P<Expr>)
-> Gc<Expr> { -> P<Expr> {
match *fields { match *fields {
Unnamed(ref fields) => { Unnamed(ref fields) => {
if fields.is_empty() { if fields.is_empty() {

View file

@ -15,14 +15,13 @@ use ext::build::AstBuilder;
use ext::deriving::generic::*; use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use ptr::P;
use std::gc::Gc;
pub fn expand_deriving_default(cx: &mut ExtCtxt, pub fn expand_deriving_default(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: Gc<MetaItem>, mitem: &MetaItem,
item: Gc<Item>, item: &Item,
push: |Gc<Item>|) { push: |P<Item>|) {
let inline = cx.meta_word(span, InternedString::new("inline")); let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline)); let attrs = vec!(cx.attribute(span, inline));
let trait_def = TraitDef { let trait_def = TraitDef {
@ -47,8 +46,7 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt,
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)
} }
fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
substr: &Substructure) -> Gc<Expr> {
let default_ident = vec!( let default_ident = vec!(
cx.ident_of("std"), cx.ident_of("std"),
cx.ident_of("default"), cx.ident_of("default"),

View file

@ -86,14 +86,13 @@ use ext::build::AstBuilder;
use ext::deriving::generic::*; use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token; use parse::token;
use ptr::P;
use std::gc::Gc;
pub fn expand_deriving_encodable(cx: &mut ExtCtxt, pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: Gc<MetaItem>, mitem: &MetaItem,
item: Gc<Item>, item: &Item,
push: |Gc<Item>|) { push: |P<Item>|) {
let trait_def = TraitDef { let trait_def = TraitDef {
span: span, span: span,
attributes: Vec::new(), attributes: Vec::new(),
@ -131,8 +130,8 @@ pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
} }
fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span, fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
substr: &Substructure) -> Gc<Expr> { substr: &Substructure) -> P<Expr> {
let encoder = substr.nonself_args[0]; let encoder = substr.nonself_args[0].clone();
// throw an underscore in front to suppress unused variable warnings // throw an underscore in front to suppress unused variable warnings
let blkarg = cx.ident_of("_e"); let blkarg = cx.ident_of("_e");
let blkencoder = cx.expr_ident(trait_span, blkarg); let blkencoder = cx.expr_ident(trait_span, blkarg);
@ -145,7 +144,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
let last = fields.len() - 1; let last = fields.len() - 1;
for (i, &FieldInfo { for (i, &FieldInfo {
name, name,
self_, ref self_,
span, span,
.. ..
}) in fields.iter().enumerate() { }) in fields.iter().enumerate() {
@ -156,9 +155,10 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
i).as_slice()) i).as_slice())
} }
}; };
let enc = cx.expr_method_call(span, self_, encode, vec!(blkencoder)); let enc = cx.expr_method_call(span, self_.clone(),
encode, vec!(blkencoder.clone()));
let lambda = cx.lambda_expr_1(span, enc, blkarg); let lambda = cx.lambda_expr_1(span, enc, blkarg);
let call = cx.expr_method_call(span, blkencoder, let call = cx.expr_method_call(span, blkencoder.clone(),
emit_struct_field, emit_struct_field,
vec!(cx.expr_str(span, name), vec!(cx.expr_str(span, name),
cx.expr_uint(span, i), cx.expr_uint(span, i),
@ -202,10 +202,11 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
let emit_variant_arg = cx.ident_of("emit_enum_variant_arg"); let emit_variant_arg = cx.ident_of("emit_enum_variant_arg");
let mut stmts = Vec::new(); let mut stmts = Vec::new();
let last = fields.len() - 1; let last = fields.len() - 1;
for (i, &FieldInfo { self_, span, .. }) in fields.iter().enumerate() { for (i, &FieldInfo { ref self_, span, .. }) in fields.iter().enumerate() {
let enc = cx.expr_method_call(span, self_, encode, vec!(blkencoder)); let enc = cx.expr_method_call(span, self_.clone(),
encode, vec!(blkencoder.clone()));
let lambda = cx.lambda_expr_1(span, enc, blkarg); let lambda = cx.lambda_expr_1(span, enc, blkarg);
let call = cx.expr_method_call(span, blkencoder, let call = cx.expr_method_call(span, blkencoder.clone(),
emit_variant_arg, emit_variant_arg,
vec!(cx.expr_uint(span, i), vec!(cx.expr_uint(span, i),
lambda)); lambda));

View file

@ -181,12 +181,13 @@
//! ~~~ //! ~~~
use std::cell::RefCell; use std::cell::RefCell;
use std::gc::{Gc, GC}; use std::gc::GC;
use std::vec;
use abi::Abi; use abi::Abi;
use abi; use abi;
use ast; use ast;
use ast::{P, EnumDef, Expr, Ident, Generics, StructDef}; use ast::{EnumDef, Expr, Ident, Generics, StructDef};
use ast_util; use ast_util;
use attr; use attr;
use attr::AttrMetaMethods; use attr::AttrMetaMethods;
@ -194,9 +195,11 @@ use ext::base::ExtCtxt;
use ext::build::AstBuilder; use ext::build::AstBuilder;
use codemap; use codemap;
use codemap::Span; use codemap::Span;
use fold::MoveMap;
use owned_slice::OwnedSlice; use owned_slice::OwnedSlice;
use parse::token::InternedString; use parse::token::InternedString;
use parse::token::special_idents; use parse::token::special_idents;
use ptr::P;
use self::ty::{LifetimeBounds, Path, Ptr, PtrTy, Self, Ty}; use self::ty::{LifetimeBounds, Path, Ptr, PtrTy, Self, Ty};
@ -251,9 +254,9 @@ pub struct Substructure<'a> {
/// ident of the method /// ident of the method
pub method_ident: Ident, pub method_ident: Ident,
/// dereferenced access to any Self or Ptr(Self, _) arguments /// dereferenced access to any Self or Ptr(Self, _) arguments
pub self_args: &'a [Gc<Expr>], pub self_args: &'a [P<Expr>],
/// verbatim access to any other arguments /// verbatim access to any other arguments
pub nonself_args: &'a [Gc<Expr>], pub nonself_args: &'a [P<Expr>],
pub fields: &'a SubstructureFields<'a> pub fields: &'a SubstructureFields<'a>
} }
@ -265,10 +268,10 @@ pub struct FieldInfo {
pub name: Option<Ident>, pub name: Option<Ident>,
/// The expression corresponding to this field of `self` /// The expression corresponding to this field of `self`
/// (specifically, a reference to it). /// (specifically, a reference to it).
pub self_: Gc<Expr>, pub self_: P<Expr>,
/// The expressions corresponding to references to this field in /// The expressions corresponding to references to this field in
/// the other Self arguments. /// the other Self arguments.
pub other: Vec<Gc<Expr>>, pub other: Vec<P<Expr>>,
} }
/// Fields for a static method /// Fields for a static method
@ -298,7 +301,7 @@ pub enum SubstructureFields<'a> {
Idents bound to the variant index values for each of the actual Idents bound to the variant index values for each of the actual
input Self arguments. input Self arguments.
*/ */
EnumNonMatchingCollapsed(Vec<Ident>, &'a [Gc<ast::Variant>], &'a [Ident]), EnumNonMatchingCollapsed(Vec<Ident>, &'a [P<ast::Variant>], &'a [Ident]),
/// A static method where Self is a struct. /// A static method where Self is a struct.
StaticStruct(&'a ast::StructDef, StaticFields), StaticStruct(&'a ast::StructDef, StaticFields),
@ -313,7 +316,7 @@ Combine the values of all the fields together. The last argument is
all the fields of all the structures, see above for details. all the fields of all the structures, see above for details.
*/ */
pub type CombineSubstructureFunc<'a> = pub type CombineSubstructureFunc<'a> =
|&mut ExtCtxt, Span, &Substructure|: 'a -> Gc<Expr>; |&mut ExtCtxt, Span, &Substructure|: 'a -> P<Expr>;
/** /**
Deal with non-matching enum variants. The tuple is a list of Deal with non-matching enum variants. The tuple is a list of
@ -324,10 +327,10 @@ last argument is all the non-Self args of the method being derived.
*/ */
pub type EnumNonMatchCollapsedFunc<'a> = pub type EnumNonMatchCollapsedFunc<'a> =
|&mut ExtCtxt, |&mut ExtCtxt,
Span, Span,
(&[Ident], &[Ident]), (&[Ident], &[Ident]),
&[Gc<Expr>]|: 'a &[P<Expr>]|: 'a
-> Gc<Expr>; -> P<Expr>;
pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>) pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
-> RefCell<CombineSubstructureFunc<'a>> { -> RefCell<CombineSubstructureFunc<'a>> {
@ -338,9 +341,9 @@ pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
impl<'a> TraitDef<'a> { impl<'a> TraitDef<'a> {
pub fn expand(&self, pub fn expand(&self,
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
_mitem: Gc<ast::MetaItem>, _mitem: &ast::MetaItem,
item: Gc<ast::Item>, item: &ast::Item,
push: |Gc<ast::Item>|) { push: |P<ast::Item>|) {
let newitem = match item.node { let newitem = match item.node {
ast::ItemStruct(ref struct_def, ref generics) => { ast::ItemStruct(ref struct_def, ref generics) => {
self.expand_struct_def(cx, self.expand_struct_def(cx,
@ -365,10 +368,10 @@ impl<'a> TraitDef<'a> {
_ => false, _ => false,
} }
}).map(|a| a.clone())); }).map(|a| a.clone()));
push(box(GC) ast::Item { push(P(ast::Item {
attrs: attrs, attrs: attrs,
..(*newitem).clone() ..(*newitem).clone()
}) }))
} }
/** /**
@ -387,7 +390,7 @@ impl<'a> TraitDef<'a> {
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
type_ident: Ident, type_ident: Ident,
generics: &Generics, generics: &Generics,
methods: Vec<Gc<ast::Method>> ) -> Gc<ast::Item> { methods: Vec<P<ast::Method>>) -> P<ast::Item> {
let trait_path = self.path.to_path(cx, self.span, type_ident, generics); let trait_path = self.path.to_path(cx, self.span, type_ident, generics);
let Generics { mut lifetimes, ty_params, where_clause: _ } = let Generics { mut lifetimes, ty_params, where_clause: _ } =
@ -475,7 +478,7 @@ impl<'a> TraitDef<'a> {
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
struct_def: &StructDef, struct_def: &StructDef,
type_ident: Ident, type_ident: Ident,
generics: &Generics) -> Gc<ast::Item> { generics: &Generics) -> P<ast::Item> {
let methods = self.methods.iter().map(|method_def| { let methods = self.methods.iter().map(|method_def| {
let (explicit_self, self_args, nonself_args, tys) = let (explicit_self, self_args, nonself_args, tys) =
method_def.split_self_nonself_args( method_def.split_self_nonself_args(
@ -515,7 +518,7 @@ impl<'a> TraitDef<'a> {
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
enum_def: &EnumDef, enum_def: &EnumDef,
type_ident: Ident, type_ident: Ident,
generics: &Generics) -> Gc<ast::Item> { generics: &Generics) -> P<ast::Item> {
let methods = self.methods.iter().map(|method_def| { let methods = self.methods.iter().map(|method_def| {
let (explicit_self, self_args, nonself_args, tys) = let (explicit_self, self_args, nonself_args, tys) =
method_def.split_self_nonself_args(cx, self, method_def.split_self_nonself_args(cx, self,
@ -534,7 +537,7 @@ impl<'a> TraitDef<'a> {
self, self,
enum_def, enum_def,
type_ident, type_ident,
self_args.as_slice(), self_args,
nonself_args.as_slice()) nonself_args.as_slice())
}; };
@ -553,7 +556,7 @@ impl<'a> TraitDef<'a> {
} }
fn variant_to_pat(cx: &mut ExtCtxt, sp: Span, variant: &ast::Variant) fn variant_to_pat(cx: &mut ExtCtxt, sp: Span, variant: &ast::Variant)
-> Gc<ast::Pat> { -> P<ast::Pat> {
let ident = cx.path_ident(sp, variant.node.name); let ident = cx.path_ident(sp, variant.node.name);
cx.pat(sp, match variant.node.kind { cx.pat(sp, match variant.node.kind {
ast::TupleVariantKind(..) => ast::PatEnum(ident, None), ast::TupleVariantKind(..) => ast::PatEnum(ident, None),
@ -566,10 +569,10 @@ impl<'a> MethodDef<'a> {
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
trait_: &TraitDef, trait_: &TraitDef,
type_ident: Ident, type_ident: Ident,
self_args: &[Gc<Expr>], self_args: &[P<Expr>],
nonself_args: &[Gc<Expr>], nonself_args: &[P<Expr>],
fields: &SubstructureFields) fields: &SubstructureFields)
-> Gc<Expr> { -> P<Expr> {
let substructure = Substructure { let substructure = Substructure {
type_ident: type_ident, type_ident: type_ident,
method_ident: cx.ident_of(self.name), method_ident: cx.ident_of(self.name),
@ -600,8 +603,7 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef, trait_: &TraitDef,
type_ident: Ident, type_ident: Ident,
generics: &Generics) generics: &Generics)
-> (ast::ExplicitSelf, Vec<Gc<Expr>>, Vec<Gc<Expr>>, -> (ast::ExplicitSelf, Vec<P<Expr>>, Vec<P<Expr>>, Vec<(Ident, P<ast::Ty>)>) {
Vec<(Ident, P<ast::Ty>)>) {
let mut self_args = Vec::new(); let mut self_args = Vec::new();
let mut nonself_args = Vec::new(); let mut nonself_args = Vec::new();
@ -654,8 +656,7 @@ impl<'a> MethodDef<'a> {
abi: Abi, abi: Abi,
explicit_self: ast::ExplicitSelf, explicit_self: ast::ExplicitSelf,
arg_types: Vec<(Ident, P<ast::Ty>)> , arg_types: Vec<(Ident, P<ast::Ty>)> ,
body: Gc<Expr>) body: P<Expr>) -> P<ast::Method> {
-> Gc<ast::Method> {
// create the generics that aren't for Self // create the generics that aren't for Self
let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics); let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics);
@ -678,7 +679,7 @@ impl<'a> MethodDef<'a> {
let body_block = cx.block_expr(body); let body_block = cx.block_expr(body);
// Create the method. // Create the method.
box(GC) ast::Method { P(ast::Method {
attrs: self.attributes.clone(), attrs: self.attributes.clone(),
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
span: trait_.span, span: trait_.span,
@ -690,7 +691,7 @@ impl<'a> MethodDef<'a> {
fn_decl, fn_decl,
body_block, body_block,
ast::Inherited) ast::Inherited)
} })
} }
/** /**
@ -719,9 +720,9 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef, trait_: &TraitDef,
struct_def: &StructDef, struct_def: &StructDef,
type_ident: Ident, type_ident: Ident,
self_args: &[Gc<Expr>], self_args: &[P<Expr>],
nonself_args: &[Gc<Expr>]) nonself_args: &[P<Expr>])
-> Gc<Expr> { -> P<Expr> {
let mut raw_fields = Vec::new(); // ~[[fields of self], let mut raw_fields = Vec::new(); // ~[[fields of self],
// [fields of next Self arg], [etc]] // [fields of next Self arg], [etc]]
@ -740,20 +741,20 @@ impl<'a> MethodDef<'a> {
// transpose raw_fields // transpose raw_fields
let fields = if raw_fields.len() > 0 { let fields = if raw_fields.len() > 0 {
raw_fields.get(0) let mut raw_fields = raw_fields.move_iter().map(|v| v.move_iter());
.iter() let first_field = raw_fields.next().unwrap();
.enumerate() let mut other_fields: Vec<vec::MoveItems<(Span, Option<Ident>, P<Expr>)>>
.map(|(i, &(span, opt_id, field))| { = raw_fields.collect();
let other_fields = raw_fields.tail().iter().map(|l| { first_field.map(|(span, opt_id, field)| {
match l.get(i) {
&(_, _, ex) => ex
}
}).collect();
FieldInfo { FieldInfo {
span: span, span: span,
name: opt_id, name: opt_id,
self_: field, self_: field,
other: other_fields other: other_fields.mut_iter().map(|l| {
match l.next().unwrap() {
(_, _, ex) => ex
}
}).collect()
} }
}).collect() }).collect()
} else { } else {
@ -774,9 +775,9 @@ impl<'a> MethodDef<'a> {
// make a series of nested matches, to destructure the // make a series of nested matches, to destructure the
// structs. This is actually right-to-left, but it shouldn't // structs. This is actually right-to-left, but it shouldn't
// matter. // matter.
for (&arg_expr, &pat) in self_args.iter().zip(patterns.iter()) { for (arg_expr, pat) in self_args.iter().zip(patterns.iter()) {
body = cx.expr_match(trait_.span, arg_expr, body = cx.expr_match(trait_.span, arg_expr.clone(),
vec!( cx.arm(trait_.span, vec!(pat), body) )) vec!( cx.arm(trait_.span, vec!(pat.clone()), body) ))
} }
body body
} }
@ -786,9 +787,9 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef, trait_: &TraitDef,
struct_def: &StructDef, struct_def: &StructDef,
type_ident: Ident, type_ident: Ident,
self_args: &[Gc<Expr>], self_args: &[P<Expr>],
nonself_args: &[Gc<Expr>]) nonself_args: &[P<Expr>])
-> Gc<Expr> { -> P<Expr> {
let summary = trait_.summarise_struct(cx, struct_def); let summary = trait_.summarise_struct(cx, struct_def);
self.call_substructure_method(cx, self.call_substructure_method(cx,
@ -834,9 +835,9 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef, trait_: &TraitDef,
enum_def: &EnumDef, enum_def: &EnumDef,
type_ident: Ident, type_ident: Ident,
self_args: &[Gc<Expr>], self_args: Vec<P<Expr>>,
nonself_args: &[Gc<Expr>]) nonself_args: &[P<Expr>])
-> Gc<Expr> { -> P<Expr> {
self.build_enum_match_tuple( self.build_enum_match_tuple(
cx, trait_, enum_def, type_ident, self_args, nonself_args) cx, trait_, enum_def, type_ident, self_args, nonself_args)
} }
@ -875,8 +876,8 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef, trait_: &TraitDef,
enum_def: &EnumDef, enum_def: &EnumDef,
type_ident: Ident, type_ident: Ident,
self_args: &[Gc<Expr>], self_args: Vec<P<Expr>>,
nonself_args: &[Gc<Expr>]) -> Gc<Expr> { nonself_args: &[P<Expr>]) -> P<Expr> {
let sp = trait_.span; let sp = trait_.span;
let variants = &enum_def.variants; let variants = &enum_def.variants;
@ -898,7 +899,7 @@ impl<'a> MethodDef<'a> {
// The `vi_idents` will be bound, solely in the catch-all, to // The `vi_idents` will be bound, solely in the catch-all, to
// a series of let statements mapping each self_arg to a uint // a series of let statements mapping each self_arg to a uint
// corresponding to its variant index. // corresponding to its variant index.
let vi_idents : Vec<ast::Ident> = self_arg_names.iter() let vi_idents: Vec<ast::Ident> = self_arg_names.iter()
.map(|name| { let vi_suffix = format!("{:s}_vi", name.as_slice()); .map(|name| { let vi_suffix = format!("{:s}_vi", name.as_slice());
cx.ident_of(vi_suffix.as_slice()) }) cx.ident_of(vi_suffix.as_slice()) })
.collect::<Vec<ast::Ident>>(); .collect::<Vec<ast::Ident>>();
@ -914,24 +915,29 @@ impl<'a> MethodDef<'a> {
// (Variant2, Variant2, ...) => Body2 // (Variant2, Variant2, ...) => Body2
// ... // ...
// where each tuple has length = self_args.len() // where each tuple has length = self_args.len()
let mut match_arms : Vec<ast::Arm> = variants.iter().enumerate() let mut match_arms: Vec<ast::Arm> = variants.iter().enumerate()
.map(|(index, &variant)| { .map(|(index, variant)| {
let mk_self_pat = |cx: &mut ExtCtxt, self_arg_name: &str| {
// These self_pats have form Variant1, Variant2, ... let (p, idents) = trait_.create_enum_variant_pattern(cx, &**variant,
let self_pats : Vec<(Gc<ast::Pat>, self_arg_name,
Vec<(Span, Option<Ident>, Gc<Expr>)>)>; ast::MutImmutable);
self_pats = self_arg_names.iter() (cx.pat(sp, ast::PatRegion(p)), idents)
.map(|self_arg_name| };
trait_.create_enum_variant_pattern(
cx, &*variant, self_arg_name.as_slice(),
ast::MutImmutable))
.collect();
// A single arm has form (&VariantK, &VariantK, ...) => BodyK // A single arm has form (&VariantK, &VariantK, ...) => BodyK
// (see "Final wrinkle" note below for why.) // (see "Final wrinkle" note below for why.)
let subpats = self_pats.iter() let mut subpats = Vec::with_capacity(self_arg_names.len());
.map(|&(p, ref _idents)| cx.pat(sp, ast::PatRegion(p))) let mut self_pats_idents = Vec::with_capacity(self_arg_names.len() - 1);
.collect::<Vec<Gc<ast::Pat>>>(); let first_self_pat_idents = {
let (p, idents) = mk_self_pat(cx, self_arg_names[0].as_slice());
subpats.push(p);
idents
};
for self_arg_name in self_arg_names.tail().iter() {
let (p, idents) = mk_self_pat(cx, self_arg_name.as_slice());
subpats.push(p);
self_pats_idents.push(idents);
}
// Here is the pat = `(&VariantK, &VariantK, ...)` // Here is the pat = `(&VariantK, &VariantK, ...)`
let single_pat = cx.pat(sp, ast::PatTup(subpats)); let single_pat = cx.pat(sp, ast::PatTup(subpats));
@ -941,39 +947,33 @@ impl<'a> MethodDef<'a> {
// we are in. // we are in.
// All of the Self args have the same variant in these // All of the Self args have the same variant in these
// cases. So we transpose the info in self_pats to // cases. So we transpose the info in self_pats_idents
// gather the getter expressions together, in the form // to gather the getter expressions together, in the
// that EnumMatching expects. // form that EnumMatching expects.
// The transposition is driven by walking across the // The transposition is driven by walking across the
// arg fields of the variant for the first self pat. // arg fields of the variant for the first self pat.
let &(_, ref self_arg_fields) = self_pats.get(0); let field_tuples = first_self_pat_idents.move_iter().enumerate()
let field_tuples : Vec<FieldInfo>;
field_tuples = self_arg_fields.iter().enumerate()
// For each arg field of self, pull out its getter expr ... // For each arg field of self, pull out its getter expr ...
.map(|(field_index, &(sp, opt_ident, self_getter_expr))| { .map(|(field_index, (sp, opt_ident, self_getter_expr))| {
// ... but FieldInfo also wants getter expr // ... but FieldInfo also wants getter expr
// for matching other arguments of Self type; // for matching other arguments of Self type;
// so walk across the *other* self_pats and // so walk across the *other* self_pats_idents
// pull out getter for same field in each of // and pull out getter for same field in each
// them (using `field_index` tracked above). // of them (using `field_index` tracked above).
// That is the heart of the transposition. // That is the heart of the transposition.
let others = self_pats.tail().iter() let others = self_pats_idents.iter().map(|fields| {
.map(|&(_pat, ref fields)| { let &(_, _opt_ident, ref other_getter_expr) =
fields.get(field_index);
let &(_, _opt_ident, other_getter_expr) = // All Self args have same variant, so
fields.get(field_index); // opt_idents are the same. (Assert
// here to make it self-evident that
// it is okay to ignore `_opt_ident`.)
assert!(opt_ident == _opt_ident);
// All Self args have same variant, so other_getter_expr.clone()
// opt_idents are the same. (Assert }).collect::<Vec<P<Expr>>>();
// here to make it self-evident that
// it is okay to ignore `_opt_ident`.)
assert!(opt_ident == _opt_ident);
other_getter_expr
}).collect::<Vec<Gc<Expr>>>();
FieldInfo { span: sp, FieldInfo { span: sp,
name: opt_ident, name: opt_ident,
@ -987,10 +987,10 @@ impl<'a> MethodDef<'a> {
// Self arg, assuming all are instances of VariantK. // Self arg, assuming all are instances of VariantK.
// Build up code associated with such a case. // Build up code associated with such a case.
let substructure = EnumMatching(index, let substructure = EnumMatching(index,
&*variant, &**variant,
field_tuples); field_tuples);
let arm_expr = self.call_substructure_method( let arm_expr = self.call_substructure_method(
cx, trait_, type_ident, self_args, nonself_args, cx, trait_, type_ident, self_args.as_slice(), nonself_args,
&substructure); &substructure);
cx.arm(sp, vec![single_pat], arm_expr) cx.arm(sp, vec![single_pat], arm_expr)
@ -1012,9 +1012,9 @@ impl<'a> MethodDef<'a> {
// unreachable-pattern error. // unreachable-pattern error.
// //
if variants.len() > 1 && self_args.len() > 1 { if variants.len() > 1 && self_args.len() > 1 {
let arms : Vec<ast::Arm> = variants.iter().enumerate() let arms: Vec<ast::Arm> = variants.iter().enumerate()
.map(|(index, &variant)| { .map(|(index, variant)| {
let pat = variant_to_pat(cx, sp, &*variant); let pat = variant_to_pat(cx, sp, &**variant);
let lit = ast::LitInt(index as u64, ast::UnsignedIntLit(ast::TyU)); let lit = ast::LitInt(index as u64, ast::UnsignedIntLit(ast::TyU));
cx.arm(sp, vec![pat], cx.expr_lit(sp, lit)) cx.arm(sp, vec![pat], cx.expr_lit(sp, lit))
}).collect(); }).collect();
@ -1035,15 +1035,15 @@ impl<'a> MethodDef<'a> {
// A => 0u, B(..) => 1u, C(..) => 2u // A => 0u, B(..) => 1u, C(..) => 2u
// }; // };
// ``` // ```
let mut index_let_stmts : Vec<Gc<ast::Stmt>> = Vec::new(); let mut index_let_stmts: Vec<P<ast::Stmt>> = Vec::new();
for (&ident, &self_arg) in vi_idents.iter().zip(self_args.iter()) { for (&ident, self_arg) in vi_idents.iter().zip(self_args.iter()) {
let variant_idx = cx.expr_match(sp, self_arg, arms.clone()); let variant_idx = cx.expr_match(sp, self_arg.clone(), arms.clone());
let let_stmt = cx.stmt_let(sp, false, ident, variant_idx); let let_stmt = cx.stmt_let(sp, false, ident, variant_idx);
index_let_stmts.push(let_stmt); index_let_stmts.push(let_stmt);
} }
let arm_expr = self.call_substructure_method( let arm_expr = self.call_substructure_method(
cx, trait_, type_ident, self_args, nonself_args, cx, trait_, type_ident, self_args.as_slice(), nonself_args,
&catch_all_substructure); &catch_all_substructure);
// Builds the expression: // Builds the expression:
@ -1124,9 +1124,7 @@ impl<'a> MethodDef<'a> {
// them when they are fed as r-values into a tuple // them when they are fed as r-values into a tuple
// expression; here add a layer of borrowing, turning // expression; here add a layer of borrowing, turning
// `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`. // `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
let borrowed_self_args = self_args.iter() let borrowed_self_args = self_args.move_map(|self_arg| cx.expr_addr_of(sp, self_arg));
.map(|&self_arg| cx.expr_addr_of(sp, self_arg))
.collect::<Vec<Gc<ast::Expr>>>();
let match_arg = cx.expr(sp, ast::ExprTup(borrowed_self_args)); let match_arg = cx.expr(sp, ast::ExprTup(borrowed_self_args));
cx.expr_match(sp, match_arg, match_arms) cx.expr_match(sp, match_arg, match_arms)
} }
@ -1136,9 +1134,9 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef, trait_: &TraitDef,
enum_def: &EnumDef, enum_def: &EnumDef,
type_ident: Ident, type_ident: Ident,
self_args: &[Gc<Expr>], self_args: &[P<Expr>],
nonself_args: &[Gc<Expr>]) nonself_args: &[P<Expr>])
-> Gc<Expr> { -> P<Expr> {
let summary = enum_def.variants.iter().map(|v| { let summary = enum_def.variants.iter().map(|v| {
let ident = v.node.name; let ident = v.node.name;
let summary = match v.node.kind { let summary = match v.node.kind {
@ -1210,11 +1208,11 @@ impl<'a> TraitDef<'a> {
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
field_paths: Vec<ast::SpannedIdent> , field_paths: Vec<ast::SpannedIdent> ,
mutbl: ast::Mutability) mutbl: ast::Mutability)
-> Vec<Gc<ast::Pat>> { -> Vec<P<ast::Pat>> {
field_paths.iter().map(|path| { field_paths.iter().map(|path| {
cx.pat(path.span, cx.pat(path.span,
ast::PatIdent(ast::BindByRef(mutbl), (*path).clone(), None)) ast::PatIdent(ast::BindByRef(mutbl), (*path).clone(), None))
}).collect() }).collect()
} }
fn create_struct_pattern(&self, fn create_struct_pattern(&self,
@ -1223,7 +1221,7 @@ impl<'a> TraitDef<'a> {
struct_def: &StructDef, struct_def: &StructDef,
prefix: &str, prefix: &str,
mutbl: ast::Mutability) mutbl: ast::Mutability)
-> (Gc<ast::Pat>, Vec<(Span, Option<Ident>, Gc<Expr>)>) { -> (P<ast::Pat>, Vec<(Span, Option<Ident>, P<Expr>)>) {
if struct_def.fields.is_empty() { if struct_def.fields.is_empty() {
return ( return (
cx.pat_ident_binding_mode( cx.pat_ident_binding_mode(
@ -1266,7 +1264,7 @@ impl<'a> TraitDef<'a> {
// struct_type is definitely not Unknown, since struct_def.fields // struct_type is definitely not Unknown, since struct_def.fields
// must be nonempty to reach here // must be nonempty to reach here
let pattern = if struct_type == Record { let pattern = if struct_type == Record {
let field_pats = subpats.iter().zip(ident_expr.iter()).map(|(&pat, &(_, id, _))| { let field_pats = subpats.move_iter().zip(ident_expr.iter()).map(|(pat, &(_, id, _))| {
// id is guaranteed to be Some // id is guaranteed to be Some
ast::FieldPat { ident: id.unwrap(), pat: pat } ast::FieldPat { ident: id.unwrap(), pat: pat }
}).collect(); }).collect();
@ -1283,7 +1281,7 @@ impl<'a> TraitDef<'a> {
variant: &ast::Variant, variant: &ast::Variant,
prefix: &str, prefix: &str,
mutbl: ast::Mutability) mutbl: ast::Mutability)
-> (Gc<ast::Pat>, Vec<(Span, Option<Ident>, Gc<Expr>)> ) { -> (P<ast::Pat>, Vec<(Span, Option<Ident>, P<Expr>)>) {
let variant_ident = variant.node.name; let variant_ident = variant.node.name;
match variant.node.kind { match variant.node.kind {
ast::TupleVariantKind(ref variant_args) => { ast::TupleVariantKind(ref variant_args) => {
@ -1327,13 +1325,13 @@ Fold the fields. `use_foldl` controls whether this is done
left-to-right (`true`) or right-to-left (`false`). left-to-right (`true`) or right-to-left (`false`).
*/ */
pub fn cs_fold(use_foldl: bool, pub fn cs_fold(use_foldl: bool,
f: |&mut ExtCtxt, Span, Gc<Expr>, Gc<Expr>, &[Gc<Expr>]| -> Gc<Expr>, f: |&mut ExtCtxt, Span, P<Expr>, P<Expr>, &[P<Expr>]| -> P<Expr>,
base: Gc<Expr>, base: P<Expr>,
enum_nonmatch_f: EnumNonMatchCollapsedFunc, enum_nonmatch_f: EnumNonMatchCollapsedFunc,
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
trait_span: Span, trait_span: Span,
substructure: &Substructure) substructure: &Substructure)
-> Gc<Expr> { -> P<Expr> {
match *substructure.fields { match *substructure.fields {
EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => { EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
if use_foldl { if use_foldl {
@ -1341,7 +1339,7 @@ pub fn cs_fold(use_foldl: bool,
f(cx, f(cx,
field.span, field.span,
old, old,
field.self_, field.self_.clone(),
field.other.as_slice()) field.other.as_slice())
}) })
} else { } else {
@ -1349,7 +1347,7 @@ pub fn cs_fold(use_foldl: bool,
f(cx, f(cx,
field.span, field.span,
old, old,
field.self_, field.self_.clone(),
field.other.as_slice()) field.other.as_slice())
}) })
} }
@ -1374,21 +1372,21 @@ f(cx, span, ~[self_1.method(__arg_1_1, __arg_2_1),
~~~ ~~~
*/ */
#[inline] #[inline]
pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<Gc<Expr>>| -> Gc<Expr>, pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<P<Expr>>| -> P<Expr>,
enum_nonmatch_f: EnumNonMatchCollapsedFunc, enum_nonmatch_f: EnumNonMatchCollapsedFunc,
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
trait_span: Span, trait_span: Span,
substructure: &Substructure) substructure: &Substructure)
-> Gc<Expr> { -> P<Expr> {
match *substructure.fields { match *substructure.fields {
EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => { EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
// call self_n.method(other_1_n, other_2_n, ...) // call self_n.method(other_1_n, other_2_n, ...)
let called = all_fields.iter().map(|field| { let called = all_fields.iter().map(|field| {
cx.expr_method_call(field.span, cx.expr_method_call(field.span,
field.self_, field.self_.clone(),
substructure.method_ident, substructure.method_ident,
field.other.iter() field.other.iter()
.map(|e| cx.expr_addr_of(field.span, *e)) .map(|e| cx.expr_addr_of(field.span, e.clone()))
.collect()) .collect())
}).collect(); }).collect();
@ -1410,21 +1408,21 @@ fields. `use_foldl` controls whether this is done left-to-right
*/ */
#[inline] #[inline]
pub fn cs_same_method_fold(use_foldl: bool, pub fn cs_same_method_fold(use_foldl: bool,
f: |&mut ExtCtxt, Span, Gc<Expr>, Gc<Expr>| -> Gc<Expr>, f: |&mut ExtCtxt, Span, P<Expr>, P<Expr>| -> P<Expr>,
base: Gc<Expr>, base: P<Expr>,
enum_nonmatch_f: EnumNonMatchCollapsedFunc, enum_nonmatch_f: EnumNonMatchCollapsedFunc,
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
trait_span: Span, trait_span: Span,
substructure: &Substructure) substructure: &Substructure)
-> Gc<Expr> { -> P<Expr> {
cs_same_method( cs_same_method(
|cx, span, vals| { |cx, span, vals| {
if use_foldl { if use_foldl {
vals.iter().fold(base, |old, &new| { vals.move_iter().fold(base.clone(), |old, new| {
f(cx, span, old, new) f(cx, span, old, new)
}) })
} else { } else {
vals.iter().rev().fold(base, |old, &new| { vals.move_iter().rev().fold(base.clone(), |old, new| {
f(cx, span, old, new) f(cx, span, old, new)
}) })
} }
@ -1438,10 +1436,10 @@ Use a given binop to combine the result of calling the derived method
on all the fields. on all the fields.
*/ */
#[inline] #[inline]
pub fn cs_binop(binop: ast::BinOp, base: Gc<Expr>, pub fn cs_binop(binop: ast::BinOp, base: P<Expr>,
enum_nonmatch_f: EnumNonMatchCollapsedFunc, enum_nonmatch_f: EnumNonMatchCollapsedFunc,
cx: &mut ExtCtxt, trait_span: Span, cx: &mut ExtCtxt, trait_span: Span,
substructure: &Substructure) -> Gc<Expr> { substructure: &Substructure) -> P<Expr> {
cs_same_method_fold( cs_same_method_fold(
true, // foldl is good enough true, // foldl is good enough
|cx, span, old, new| { |cx, span, old, new| {
@ -1459,7 +1457,7 @@ pub fn cs_binop(binop: ast::BinOp, base: Gc<Expr>,
#[inline] #[inline]
pub fn cs_or(enum_nonmatch_f: EnumNonMatchCollapsedFunc, pub fn cs_or(enum_nonmatch_f: EnumNonMatchCollapsedFunc,
cx: &mut ExtCtxt, span: Span, cx: &mut ExtCtxt, span: Span,
substructure: &Substructure) -> Gc<Expr> { substructure: &Substructure) -> P<Expr> {
cs_binop(ast::BiOr, cx.expr_bool(span, false), cs_binop(ast::BiOr, cx.expr_bool(span, false),
enum_nonmatch_f, enum_nonmatch_f,
cx, span, substructure) cx, span, substructure)
@ -1469,7 +1467,7 @@ pub fn cs_or(enum_nonmatch_f: EnumNonMatchCollapsedFunc,
#[inline] #[inline]
pub fn cs_and(enum_nonmatch_f: EnumNonMatchCollapsedFunc, pub fn cs_and(enum_nonmatch_f: EnumNonMatchCollapsedFunc,
cx: &mut ExtCtxt, span: Span, cx: &mut ExtCtxt, span: Span,
substructure: &Substructure) -> Gc<Expr> { substructure: &Substructure) -> P<Expr> {
cs_binop(ast::BiAnd, cx.expr_bool(span, true), cs_binop(ast::BiAnd, cx.expr_bool(span, true),
enum_nonmatch_f, enum_nonmatch_f,
cx, span, substructure) cx, span, substructure)

View file

@ -14,14 +14,13 @@ explicit `Self` type to use when specifying impls to be derived.
*/ */
use ast; use ast;
use ast::{P,Expr,Generics,Ident}; use ast::{Expr,Generics,Ident};
use ext::base::ExtCtxt; use ext::base::ExtCtxt;
use ext::build::AstBuilder; use ext::build::AstBuilder;
use codemap::{Span,respan}; use codemap::{Span,respan};
use owned_slice::OwnedSlice; use owned_slice::OwnedSlice;
use parse::token::special_idents; use parse::token::special_idents;
use ptr::P;
use std::gc::Gc;
/// The types of pointers /// The types of pointers
#[deriving(Clone)] #[deriving(Clone)]
@ -260,7 +259,7 @@ impl<'a> LifetimeBounds<'a> {
} }
pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>) pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
-> (Gc<Expr>, ast::ExplicitSelf) { -> (P<Expr>, ast::ExplicitSelf) {
// this constructs a fresh `self` path, which will match the fresh `self` binding // this constructs a fresh `self` path, which will match the fresh `self` binding
// created below. // created below.
let self_path = cx.expr_self(span); let self_path = cx.expr_self(span);

View file

@ -15,14 +15,13 @@ use ext::build::AstBuilder;
use ext::deriving::generic::*; use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use ptr::P;
use std::gc::Gc;
pub fn expand_deriving_hash(cx: &mut ExtCtxt, pub fn expand_deriving_hash(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: Gc<MetaItem>, mitem: &MetaItem,
item: Gc<Item>, item: &Item,
push: |Gc<Item>|) { push: |P<Item>|) {
let (path, generics, args) = if cx.ecfg.deriving_hash_type_parameter { let (path, generics, args) = if cx.ecfg.deriving_hash_type_parameter {
(Path::new_(vec!("std", "hash", "Hash"), None, (Path::new_(vec!("std", "hash", "Hash"), None,
@ -64,15 +63,14 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
hash_trait_def.expand(cx, mitem, item, push); hash_trait_def.expand(cx, mitem, item, push);
} }
fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span, fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
substr: &Substructure) -> Gc<Expr> {
let state_expr = match substr.nonself_args { let state_expr = match substr.nonself_args {
[state_expr] => state_expr, [ref state_expr] => state_expr,
_ => cx.span_bug(trait_span, "incorrect number of arguments in `deriving(Hash)`") _ => cx.span_bug(trait_span, "incorrect number of arguments in `deriving(Hash)`")
}; };
let hash_ident = substr.method_ident; let hash_ident = substr.method_ident;
let call_hash = |span, thing_expr| { let call_hash = |span, thing_expr| {
let expr = cx.expr_method_call(span, thing_expr, hash_ident, vec!(state_expr)); let expr = cx.expr_method_call(span, thing_expr, hash_ident, vec!(state_expr.clone()));
cx.stmt_expr(expr) cx.stmt_expr(expr)
}; };
let mut stmts = Vec::new(); let mut stmts = Vec::new();
@ -83,7 +81,7 @@ fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span,
// Determine the discriminant. We will feed this value to the byte // Determine the discriminant. We will feed this value to the byte
// iteration function. // iteration function.
let discriminant = match variant.node.disr_expr { let discriminant = match variant.node.disr_expr {
Some(d) => d, Some(ref d) => d.clone(),
None => cx.expr_uint(trait_span, index) None => cx.expr_uint(trait_span, index)
}; };
@ -94,8 +92,8 @@ fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span,
_ => cx.span_bug(trait_span, "impossible substructure in `deriving(Hash)`") _ => cx.span_bug(trait_span, "impossible substructure in `deriving(Hash)`")
}; };
for &FieldInfo { self_, span, .. } in fields.iter() { for &FieldInfo { ref self_, span, .. } in fields.iter() {
stmts.push(call_hash(span, self_)); stmts.push(call_hash(span, self_.clone()));
} }
if stmts.len() == 0 { if stmts.len() == 0 {

View file

@ -21,8 +21,7 @@ library.
use ast::{Item, MetaItem, MetaList, MetaNameValue, MetaWord}; use ast::{Item, MetaItem, MetaList, MetaNameValue, MetaWord};
use ext::base::ExtCtxt; use ext::base::ExtCtxt;
use codemap::Span; use codemap::Span;
use ptr::P;
use std::gc::Gc;
pub mod bounds; pub mod bounds;
pub mod clone; pub mod clone;
@ -49,9 +48,9 @@ pub mod generic;
pub fn expand_meta_deriving(cx: &mut ExtCtxt, pub fn expand_meta_deriving(cx: &mut ExtCtxt,
_span: Span, _span: Span,
mitem: Gc<MetaItem>, mitem: &MetaItem,
item: Gc<Item>, item: &Item,
push: |Gc<Item>|) { push: |P<Item>|) {
match mitem.node { match mitem.node {
MetaNameValue(_, ref l) => { MetaNameValue(_, ref l) => {
cx.span_err(l.span, "unexpected value in `deriving`"); cx.span_err(l.span, "unexpected value in `deriving`");
@ -63,13 +62,13 @@ pub fn expand_meta_deriving(cx: &mut ExtCtxt,
cx.span_warn(mitem.span, "empty trait list in `deriving`"); cx.span_warn(mitem.span, "empty trait list in `deriving`");
} }
MetaList(_, ref titems) => { MetaList(_, ref titems) => {
for &titem in titems.iter().rev() { for titem in titems.iter().rev() {
match titem.node { match titem.node {
MetaNameValue(ref tname, _) | MetaNameValue(ref tname, _) |
MetaList(ref tname, _) | MetaList(ref tname, _) |
MetaWord(ref tname) => { MetaWord(ref tname) => {
macro_rules! expand(($func:path) => ($func(cx, titem.span, macro_rules! expand(($func:path) => ($func(cx, titem.span,
titem, item, &**titem, item,
|i| push(i)))); |i| push(i))));
match tname.get() { match tname.get() {
"Clone" => expand!(clone::expand_deriving_clone), "Clone" => expand!(clone::expand_deriving_clone),

View file

@ -16,14 +16,13 @@ use ext::build::AstBuilder;
use ext::deriving::generic::*; use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use ptr::P;
use std::gc::Gc;
pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt, pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: Gc<MetaItem>, mitem: &MetaItem,
item: Gc<Item>, item: &Item,
push: |Gc<Item>|) { push: |P<Item>|) {
let inline = cx.meta_word(span, InternedString::new("inline")); let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline)); let attrs = vec!(cx.attribute(span, inline));
let trait_def = TraitDef { let trait_def = TraitDef {
@ -70,10 +69,9 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)
} }
fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
substr: &Substructure) -> Gc<Expr> {
let n = match substr.nonself_args { let n = match substr.nonself_args {
[n] => n, [ref n] => n,
_ => cx.span_bug(trait_span, "incorrect number of arguments in `deriving(FromPrimitive)`") _ => cx.span_bug(trait_span, "incorrect number of arguments in `deriving(FromPrimitive)`")
}; };
@ -106,8 +104,8 @@ fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span,
// expr for `$n == $variant as $name` // expr for `$n == $variant as $name`
let variant = cx.expr_ident(span, variant.node.name); let variant = cx.expr_ident(span, variant.node.name);
let ty = cx.ty_ident(span, cx.ident_of(name)); let ty = cx.ty_ident(span, cx.ident_of(name));
let cast = cx.expr_cast(span, variant, ty); let cast = cx.expr_cast(span, variant.clone(), ty);
let guard = cx.expr_binary(span, ast::BiEq, n, cast); let guard = cx.expr_binary(span, ast::BiEq, n.clone(), cast);
// expr for `Some($variant)` // expr for `Some($variant)`
let body = cx.expr_some(span, variant); let body = cx.expr_some(span, variant);
@ -141,7 +139,7 @@ fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span,
}; };
arms.push(arm); arms.push(arm);
cx.expr_match(trait_span, n, arms) cx.expr_match(trait_span, n.clone(), arms)
} }
_ => cx.span_bug(trait_span, "expected StaticEnum in deriving(FromPrimitive)") _ => cx.span_bug(trait_span, "expected StaticEnum in deriving(FromPrimitive)")
} }

View file

@ -15,14 +15,13 @@ use ext::base::ExtCtxt;
use ext::build::{AstBuilder}; use ext::build::{AstBuilder};
use ext::deriving::generic::*; use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use ptr::P;
use std::gc::Gc;
pub fn expand_deriving_rand(cx: &mut ExtCtxt, pub fn expand_deriving_rand(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: Gc<MetaItem>, mitem: &MetaItem,
item: Gc<Item>, item: &Item,
push: |Gc<Item>|) { push: |P<Item>|) {
let trait_def = TraitDef { let trait_def = TraitDef {
span: span, span: span,
attributes: Vec::new(), attributes: Vec::new(),
@ -54,10 +53,9 @@ pub fn expand_deriving_rand(cx: &mut ExtCtxt,
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)
} }
fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
substr: &Substructure) -> Gc<Expr> {
let rng = match substr.nonself_args { let rng = match substr.nonself_args {
[rng] => vec!( rng ), [ref rng] => rng,
_ => cx.bug("Incorrect number of arguments to `rand` in `deriving(Rand)`") _ => cx.bug("Incorrect number of arguments to `rand` in `deriving(Rand)`")
}; };
let rand_ident = vec!( let rand_ident = vec!(
@ -69,7 +67,7 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span,
let rand_call = |cx: &mut ExtCtxt, span| { let rand_call = |cx: &mut ExtCtxt, span| {
cx.expr_call_global(span, cx.expr_call_global(span,
rand_ident.clone(), rand_ident.clone(),
vec!( *rng.get(0) )) vec!(rng.clone()))
}; };
return match *substr.fields { return match *substr.fields {
@ -95,7 +93,7 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span,
// ::rand::Rand::rand(rng) // ::rand::Rand::rand(rng)
let rv_call = cx.expr_call(trait_span, let rv_call = cx.expr_call(trait_span,
rand_name, rand_name,
vec!( *rng.get(0) )); vec!(rng.clone()));
// need to specify the uint-ness of the random number // need to specify the uint-ness of the random number
let uint_ty = cx.ty_ident(trait_span, cx.ident_of("uint")); let uint_ty = cx.ty_ident(trait_span, cx.ident_of("uint"));
@ -136,8 +134,8 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span,
trait_span: Span, trait_span: Span,
ctor_ident: Ident, ctor_ident: Ident,
summary: &StaticFields, summary: &StaticFields,
rand_call: |&mut ExtCtxt, Span| -> Gc<Expr>) rand_call: |&mut ExtCtxt, Span| -> P<Expr>)
-> Gc<Expr> { -> P<Expr> {
match *summary { match *summary {
Unnamed(ref fields) => { Unnamed(ref fields) => {
if fields.is_empty() { if fields.is_empty() {

View file

@ -9,7 +9,7 @@
// except according to those terms. // except according to those terms.
use ast; use ast;
use ast::{MetaItem, Item, Expr}; use ast::{MetaItem, Item, Expr,};
use codemap::Span; use codemap::Span;
use ext::format; use ext::format;
use ext::base::ExtCtxt; use ext::base::ExtCtxt;
@ -17,16 +17,15 @@ use ext::build::AstBuilder;
use ext::deriving::generic::*; use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token; use parse::token;
use ptr::P;
use std::collections::HashMap; use std::collections::HashMap;
use std::string::String;
use std::gc::Gc;
pub fn expand_deriving_show(cx: &mut ExtCtxt, pub fn expand_deriving_show(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: Gc<MetaItem>, mitem: &MetaItem,
item: Gc<Item>, item: &Item,
push: |Gc<Item>|) { push: |P<Item>|) {
// &mut ::std::fmt::Formatter // &mut ::std::fmt::Formatter
let fmtr = Ptr(box Literal(Path::new(vec!("std", "fmt", "Formatter"))), let fmtr = Ptr(box Literal(Path::new(vec!("std", "fmt", "Formatter"))),
Borrowed(None, ast::MutMutable)); Borrowed(None, ast::MutMutable));
@ -57,7 +56,7 @@ pub fn expand_deriving_show(cx: &mut ExtCtxt,
/// We construct a format string and then defer to std::fmt, since that /// We construct a format string and then defer to std::fmt, since that
/// knows what's up with formatting and so on. /// knows what's up with formatting and so on.
fn show_substructure(cx: &mut ExtCtxt, span: Span, fn show_substructure(cx: &mut ExtCtxt, span: Span,
substr: &Substructure) -> Gc<Expr> { substr: &Substructure) -> P<Expr> {
// build `<name>`, `<name>({}, {}, ...)` or `<name> { <field>: {}, // build `<name>`, `<name>({}, {}, ...)` or `<name> { <field>: {},
// <field>: {}, ... }` based on the "shape". // <field>: {}, ... }` based on the "shape".
// //
@ -91,7 +90,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
format_string.push_str("{}"); format_string.push_str("{}");
exprs.push(field.self_); exprs.push(field.self_.clone());
} }
format_string.push_str(")"); format_string.push_str(")");
@ -108,7 +107,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
format_string.push_str(name.get()); format_string.push_str(name.get());
format_string.push_str(": {}"); format_string.push_str(": {}");
exprs.push(field.self_); exprs.push(field.self_.clone());
} }
format_string.push_str(" }}"); format_string.push_str(" }}");
@ -123,7 +122,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
// format_arg_method!(fmt, write_fmt, "<format_string>", exprs...) // format_arg_method!(fmt, write_fmt, "<format_string>", exprs...)
// //
// but doing it directly via ext::format. // but doing it directly via ext::format.
let formatter = substr.nonself_args[0]; let formatter = substr.nonself_args[0].clone();
let meth = cx.ident_of("write_fmt"); let meth = cx.ident_of("write_fmt");
let s = token::intern_and_get_ident(format_string.as_slice()); let s = token::intern_and_get_ident(format_string.as_slice());

View file

@ -15,14 +15,13 @@ use ext::build::AstBuilder;
use ext::deriving::generic::*; use ext::deriving::generic::*;
use ext::deriving::generic::ty::*; use ext::deriving::generic::ty::*;
use parse::token::InternedString; use parse::token::InternedString;
use ptr::P;
use std::gc::Gc;
pub fn expand_deriving_zero(cx: &mut ExtCtxt, pub fn expand_deriving_zero(cx: &mut ExtCtxt,
span: Span, span: Span,
mitem: Gc<MetaItem>, mitem: &MetaItem,
item: Gc<Item>, item: &Item,
push: |Gc<Item>|) { push: |P<Item>|) {
let inline = cx.meta_word(span, InternedString::new("inline")); let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline)); let attrs = vec!(cx.attribute(span, inline));
let trait_def = TraitDef { let trait_def = TraitDef {
@ -63,8 +62,7 @@ pub fn expand_deriving_zero(cx: &mut ExtCtxt,
trait_def.expand(cx, mitem, item, push) trait_def.expand(cx, mitem, item, push)
} }
fn zero_substructure(cx: &mut ExtCtxt, trait_span: Span, fn zero_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
substr: &Substructure) -> Gc<Expr> {
let zero_ident = vec!( let zero_ident = vec!(
cx.ident_of("std"), cx.ident_of("std"),
cx.ident_of("num"), cx.ident_of("num"),

View file

@ -61,38 +61,42 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT
pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> Box<base::MacResult+'cx> { -> Box<base::MacResult+'cx> {
let exprs = match get_exprs_from_tts(cx, sp, tts) { let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
Some(ref exprs) if exprs.len() == 0 => { Some(ref exprs) if exprs.len() == 0 => {
cx.span_err(sp, "env! takes 1 or 2 arguments"); cx.span_err(sp, "env! takes 1 or 2 arguments");
return DummyResult::expr(sp); return DummyResult::expr(sp);
} }
None => return DummyResult::expr(sp), None => return DummyResult::expr(sp),
Some(exprs) => exprs Some(exprs) => exprs.move_iter()
}; };
let var = match expr_to_string(cx, let var = match expr_to_string(cx,
*exprs.get(0), exprs.next().unwrap(),
"expected string literal") { "expected string literal") {
None => return DummyResult::expr(sp), None => return DummyResult::expr(sp),
Some((v, _style)) => v Some((v, _style)) => v
}; };
let msg = match exprs.len() { let msg = match exprs.next() {
1 => { None => {
token::intern_and_get_ident(format!("environment variable `{}` \ token::intern_and_get_ident(format!("environment variable `{}` \
not defined", not defined",
var).as_slice()) var).as_slice())
} }
2 => { Some(second) => {
match expr_to_string(cx, *exprs.get(1), "expected string literal") { match expr_to_string(cx, second, "expected string literal") {
None => return DummyResult::expr(sp), None => return DummyResult::expr(sp),
Some((s, _style)) => s Some((s, _style)) => s
} }
} }
_ => { };
match exprs.next() {
None => {}
Some(_) => {
cx.span_err(sp, "env! takes 1 or 2 arguments"); cx.span_err(sp, "env! takes 1 or 2 arguments");
return DummyResult::expr(sp); return DummyResult::expr(sp);
} }
}; }
let e = match os::getenv(var.get()) { let e = match os::getenv(var.get()) {
None => { None => {

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use ast::{P, Block, Crate, DeclLocal, ExprMac, PatMac}; use ast::{Block, Crate, DeclLocal, ExprMac, PatMac};
use ast::{Local, Ident, MacInvocTT}; use ast::{Local, Ident, MacInvocTT};
use ast::{ItemMac, Mrk, Stmt, StmtDecl, StmtMac, StmtExpr, StmtSemi}; use ast::{ItemMac, Mrk, Stmt, StmtDecl, StmtMac, StmtExpr, StmtSemi};
use ast::TokenTree; use ast::TokenTree;
@ -25,103 +25,106 @@ use fold::*;
use parse; use parse;
use parse::token::{fresh_mark, fresh_name, intern}; use parse::token::{fresh_mark, fresh_name, intern};
use parse::token; use parse::token;
use ptr::P;
use util::small_vector::SmallVector;
use visit; use visit;
use visit::Visitor; use visit::Visitor;
use util::small_vector::SmallVector;
use std::gc::{Gc, GC}; use std::gc::Gc;
enum Either<L,R> { enum Either<L,R> {
Left(L), Left(L),
Right(R) Right(R)
} }
fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> { pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
match e.node { e.and_then(|ast::Expr {id, node, span}| match 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.
ExprMac(ref mac) => { ExprMac(mac) => {
let expanded_expr = match expand_mac_invoc(mac,&e.span, let expanded_expr = match expand_mac_invoc(mac, span,
|r|{r.make_expr()}, |r| r.make_expr(),
|expr,fm|{mark_expr(expr,fm)}, mark_expr, fld) {
fld) {
Some(expr) => expr, Some(expr) => expr,
None => { None => {
return DummyResult::raw_expr(e.span); return DummyResult::raw_expr(span);
} }
}; };
// Keep going, outside-in. // Keep going, outside-in.
// //
// FIXME(pcwalton): Is it necessary to clone the let fully_expanded = fld.fold_expr(expanded_expr);
// node here?
let fully_expanded =
fld.fold_expr(expanded_expr).node.clone();
fld.cx.bt_pop(); fld.cx.bt_pop();
box(GC) ast::Expr { fully_expanded.map(|e| ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: fully_expanded, node: e.node,
span: e.span, span: span,
} })
} }
ast::ExprWhile(cond, body, opt_ident) => { ast::ExprWhile(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(e.span, ast::ExprWhile(cond, body, opt_ident)) fld.cx.expr(span, ast::ExprWhile(cond, body, opt_ident))
} }
ast::ExprLoop(loop_block, opt_ident) => { ast::ExprLoop(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(e.span, ast::ExprLoop(loop_block, opt_ident)) fld.cx.expr(span, ast::ExprLoop(loop_block, opt_ident))
} }
ast::ExprForLoop(pat, head, body, opt_ident) => { ast::ExprForLoop(pat, head, body, opt_ident) => {
let pat = fld.fold_pat(pat); let pat = fld.fold_pat(pat);
let head = fld.fold_expr(head); let head = fld.fold_expr(head);
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(e.span, ast::ExprForLoop(pat, head, body, opt_ident)) fld.cx.expr(span, ast::ExprForLoop(pat, head, body, opt_ident))
} }
ast::ExprFnBlock(capture_clause, fn_decl, block) => { ast::ExprFnBlock(capture_clause, fn_decl, block) => {
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::ExprFnBlock(capture_clause, let new_node = ast::ExprFnBlock(capture_clause,
rewritten_fn_decl, rewritten_fn_decl,
rewritten_block); rewritten_block);
box(GC) ast::Expr{id:e.id, node: new_node, span: fld.new_span(e.span)} P(ast::Expr{id:id, node: new_node, span: fld.new_span(span)})
} }
ast::ExprProc(fn_decl, block) => { ast::ExprProc(fn_decl, block) => {
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::ExprProc(rewritten_fn_decl, rewritten_block); let new_node = ast::ExprProc(rewritten_fn_decl, rewritten_block);
box(GC) ast::Expr{id:e.id, node: new_node, span: fld.new_span(e.span)} P(ast::Expr{id:id, node: new_node, span: fld.new_span(span)})
} }
_ => noop_fold_expr(e, fld) _ => {
} P(noop_fold_expr(ast::Expr {
id: id,
node: node,
span: span
}, fld))
}
})
} }
/// Expand a (not-ident-style) macro invocation. Returns the result /// Expand a (not-ident-style) macro invocation. Returns the result
/// of expansion and the mark which must be applied to the result. /// of expansion and the mark which must be applied to the result.
/// Our current interface doesn't allow us to apply the mark to the /// Our current interface doesn't allow us to apply the mark to the
/// result until after calling make_expr, make_items, etc. /// result until after calling make_expr, make_items, etc.
fn expand_mac_invoc<T>(mac: &ast::Mac, span: &codemap::Span, fn expand_mac_invoc<T>(mac: ast::Mac, span: codemap::Span,
parse_thunk: |Box<MacResult>|->Option<T>, parse_thunk: |Box<MacResult>|->Option<T>,
mark_thunk: |T,Mrk|->T, mark_thunk: |T,Mrk|->T,
fld: &mut MacroExpander) fld: &mut MacroExpander)
-> Option<T> -> Option<T>
{ {
match (*mac).node { match mac.node {
// 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
// for the other three macro invocation chunks of code // for the other three macro invocation chunks of code
// in this file. // in this file.
// Token-tree macros: // Token-tree macros:
MacInvocTT(ref pth, ref tts, _) => { MacInvocTT(pth, tts, _) => {
if pth.segments.len() > 1u { if pth.segments.len() > 1u {
fld.cx.span_err(pth.span, fld.cx.span_err(pth.span,
"expected macro name without module \ "expected macro name without module \
@ -144,7 +147,7 @@ fn expand_mac_invoc<T>(mac: &ast::Mac, span: &codemap::Span,
Some(rc) => match *rc { Some(rc) => match *rc {
NormalTT(ref expandfun, exp_span) => { NormalTT(ref expandfun, exp_span) => {
fld.cx.bt_push(ExpnInfo { fld.cx.bt_push(ExpnInfo {
call_site: *span, call_site: span,
callee: NameAndSpan { callee: NameAndSpan {
name: extnamestr.get().to_string(), name: extnamestr.get().to_string(),
format: MacroBang, format: MacroBang,
@ -218,7 +221,7 @@ fn expand_loop_block(loop_block: P<Block>,
// in a block enclosed by loop head. // in a block enclosed by loop head.
fld.cx.syntax_env.push_frame(); fld.cx.syntax_env.push_frame();
fld.cx.syntax_env.info().pending_renames.push(rename); fld.cx.syntax_env.info().pending_renames.push(rename);
let expanded_block = expand_block_elts(&*loop_block, fld); let expanded_block = expand_block_elts(loop_block, fld);
fld.cx.syntax_env.pop_frame(); fld.cx.syntax_env.pop_frame();
(expanded_block, Some(renamed_ident)) (expanded_block, Some(renamed_ident))
@ -240,8 +243,8 @@ macro_rules! with_exts_frame (
) )
// When we enter a module, record it, for the sake of `module!` // When we enter a module, record it, for the sake of `module!`
fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander) pub fn expand_item(it: P<ast::Item>, fld: &mut MacroExpander)
-> SmallVector<Gc<ast::Item>> { -> SmallVector<P<ast::Item>> {
let it = expand_item_modifiers(it, fld); let it = expand_item_modifiers(it, fld);
let mut decorator_items = SmallVector::zero(); let mut decorator_items = SmallVector::zero();
@ -265,8 +268,9 @@ fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander)
// we'd ideally decorator_items.push_all(expand_item(item, fld)), // we'd ideally decorator_items.push_all(expand_item(item, fld)),
// but that double-mut-borrows fld // but that double-mut-borrows fld
let mut items: SmallVector<Gc<ast::Item>> = SmallVector::zero(); let mut items: SmallVector<P<ast::Item>> = SmallVector::zero();
dec.expand(fld.cx, attr.span, attr.node.value, it, |item| items.push(item)); dec.expand(fld.cx, attr.span, &*attr.node.value, &*it,
|item| items.push(item));
decorator_items.extend(items.move_iter() decorator_items.extend(items.move_iter()
.flat_map(|item| expand_item(item, fld).move_iter())); .flat_map(|item| expand_item(item, fld).move_iter()));
@ -285,17 +289,16 @@ fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander)
let macro_escape = contains_macro_escape(new_attrs.as_slice()); let macro_escape = contains_macro_escape(new_attrs.as_slice());
let result = with_exts_frame!(fld.cx.syntax_env, let result = with_exts_frame!(fld.cx.syntax_env,
macro_escape, macro_escape,
noop_fold_item(&*it, fld)); noop_fold_item(it, fld));
fld.cx.mod_pop(); fld.cx.mod_pop();
result result
}, },
_ => { _ => {
let it = box(GC) ast::Item { let it = P(ast::Item {
attrs: new_attrs, attrs: new_attrs,
..(*it).clone() ..(*it).clone()
});
}; noop_fold_item(it, fld)
noop_fold_item(&*it, fld)
} }
}; };
@ -303,8 +306,8 @@ fn expand_item(it: Gc<ast::Item>, fld: &mut MacroExpander)
new_items new_items
} }
fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander) fn expand_item_modifiers(mut it: P<ast::Item>, fld: &mut MacroExpander)
-> Gc<ast::Item> { -> P<ast::Item> {
// partition the attributes into ItemModifiers and others // partition the attributes into ItemModifiers and others
let (modifiers, other_attrs) = it.attrs.partitioned(|attr| { let (modifiers, other_attrs) = it.attrs.partitioned(|attr| {
match fld.cx.syntax_env.find(&intern(attr.name().get())) { match fld.cx.syntax_env.find(&intern(attr.name().get())) {
@ -313,10 +316,10 @@ fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
} }
}); });
// update the attrs, leave everything else alone. Is this mutation really a good idea? // update the attrs, leave everything else alone. Is this mutation really a good idea?
it = box(GC) ast::Item { it = P(ast::Item {
attrs: other_attrs, attrs: other_attrs,
..(*it).clone() ..(*it).clone()
}; });
if modifiers.is_empty() { if modifiers.is_empty() {
return it; return it;
@ -337,7 +340,7 @@ fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
span: None, span: None,
} }
}); });
it = mac.expand(fld.cx, attr.span, attr.node.value, it); it = mac.expand(fld.cx, attr.span, &*attr.node.value, it);
fld.cx.bt_pop(); fld.cx.bt_pop();
} }
_ => unreachable!() _ => unreachable!()
@ -351,15 +354,15 @@ fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
} }
/// Expand item_underscore /// Expand item_underscore
fn expand_item_underscore(item: &ast::Item_, fld: &mut MacroExpander) -> ast::Item_ { fn expand_item_underscore(item: ast::Item_, fld: &mut MacroExpander) -> ast::Item_ {
match *item { match item {
ast::ItemFn(decl, fn_style, abi, ref generics, body) => { ast::ItemFn(decl, fn_style, abi, generics, body) => {
let (rewritten_fn_decl, rewritten_body) let (rewritten_fn_decl, rewritten_body)
= expand_and_rename_fn_decl_and_block(&*decl, body, fld); = expand_and_rename_fn_decl_and_block(decl, body, fld);
let expanded_generics = fold::noop_fold_generics(generics,fld); let expanded_generics = fold::noop_fold_generics(generics,fld);
ast::ItemFn(rewritten_fn_decl, fn_style, abi, expanded_generics, rewritten_body) ast::ItemFn(rewritten_fn_decl, fn_style, abi, expanded_generics, rewritten_body)
} }
_ => noop_fold_item_underscore(&*item, fld) _ => noop_fold_item_underscore(item, fld)
} }
} }
@ -370,26 +373,24 @@ fn contains_macro_escape(attrs: &[ast::Attribute]) -> bool {
// Support for item-position macro invocations, exactly the same // Support for item-position macro invocations, exactly the same
// logic as for expression-position macro invocations. // logic as for expression-position macro invocations.
fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander) pub fn expand_item_mac(it: P<ast::Item>, fld: &mut MacroExpander)
-> SmallVector<Gc<ast::Item>> -> SmallVector<P<ast::Item>> {
{ let (extname, path_span, tts) = match it.node {
let (pth, tts) = match it.node {
ItemMac(codemap::Spanned { ItemMac(codemap::Spanned {
node: MacInvocTT(ref pth, ref tts, _), node: MacInvocTT(ref pth, ref tts, _),
.. ..
}) => { }) => {
(pth, (*tts).clone()) (pth.segments.get(0).identifier, pth.span, (*tts).clone())
} }
_ => fld.cx.span_bug(it.span, "invalid item macro invocation") _ => fld.cx.span_bug(it.span, "invalid item macro invocation")
}; };
let extname = pth.segments.get(0).identifier;
let extnamestr = token::get_ident(extname); let extnamestr = token::get_ident(extname);
let fm = fresh_mark(); let fm = fresh_mark();
let def_or_items = { let def_or_items = {
let expanded = match fld.cx.syntax_env.find(&extname.name) { let mut expanded = match fld.cx.syntax_env.find(&extname.name) {
None => { None => {
fld.cx.span_err(pth.span, fld.cx.span_err(path_span,
format!("macro undefined: '{}!'", format!("macro undefined: '{}!'",
extnamestr).as_slice()); extnamestr).as_slice());
// let compilation continue // let compilation continue
@ -400,7 +401,7 @@ fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
NormalTT(ref expander, span) => { NormalTT(ref expander, span) => {
if it.ident.name != parse::token::special_idents::invalid.name { if it.ident.name != parse::token::special_idents::invalid.name {
fld.cx fld.cx
.span_err(pth.span, .span_err(path_span,
format!("macro {}! expects no ident argument, \ format!("macro {}! expects no ident argument, \
given '{}'", given '{}'",
extnamestr, extnamestr,
@ -421,7 +422,7 @@ fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
} }
IdentTT(ref expander, span) => { IdentTT(ref expander, span) => {
if it.ident.name == parse::token::special_idents::invalid.name { if it.ident.name == parse::token::special_idents::invalid.name {
fld.cx.span_err(pth.span, fld.cx.span_err(path_span,
format!("macro {}! expects an ident argument", format!("macro {}! expects an ident argument",
extnamestr.get()).as_slice()); extnamestr.get()).as_slice());
return SmallVector::zero(); return SmallVector::zero();
@ -440,7 +441,7 @@ fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
} }
LetSyntaxTT(ref expander, span) => { LetSyntaxTT(ref expander, span) => {
if it.ident.name == parse::token::special_idents::invalid.name { if it.ident.name == parse::token::special_idents::invalid.name {
fld.cx.span_err(pth.span, fld.cx.span_err(path_span,
format!("macro {}! expects an ident argument", format!("macro {}! expects an ident argument",
extnamestr.get()).as_slice()); extnamestr.get()).as_slice());
return SmallVector::zero(); return SmallVector::zero();
@ -490,7 +491,7 @@ fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
.collect() .collect()
} }
Right(None) => { Right(None) => {
fld.cx.span_err(pth.span, fld.cx.span_err(path_span,
format!("non-item macro in item position: {}", format!("non-item macro in item position: {}",
extnamestr.get()).as_slice()); extnamestr.get()).as_slice());
return SmallVector::zero(); return SmallVector::zero();
@ -498,24 +499,21 @@ fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander)
}; };
fld.cx.bt_pop(); fld.cx.bt_pop();
return items; items
} }
/// Expand a stmt /// Expand a stmt
// //
// I don't understand why this returns a vector... it looks like we're // I don't understand why this returns a vector... it looks like we're
// half done adding machinery to allow macros to expand into multiple statements. // half done adding machinery to allow macros to expand into multiple statements.
fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<Gc<Stmt>> { fn expand_stmt(s: Stmt, fld: &mut MacroExpander) -> SmallVector<P<Stmt>> {
let (mac, semi) = match s.node { let (mac, semi) = match s.node {
StmtMac(ref mac, semi) => (mac, semi), StmtMac(mac, semi) => (mac, semi),
_ => return expand_non_macro_stmt(s, fld) _ => return expand_non_macro_stmt(s, fld)
}; };
let expanded_stmt = match expand_mac_invoc(mac,&s.span, let expanded_stmt = match expand_mac_invoc(mac, s.span,
|r|{r.make_stmt()}, |r| r.make_stmt(),
|sts,mrk| { mark_stmt, fld) {
mark_stmt(&*sts,mrk)
},
fld) {
Some(stmt) => stmt, Some(stmt) => stmt,
None => { None => {
return SmallVector::zero(); return SmallVector::zero();
@ -523,46 +521,34 @@ fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<Gc<Stmt>> {
}; };
// Keep going, outside-in. // Keep going, outside-in.
let fully_expanded = fld.fold_stmt(&*expanded_stmt); let fully_expanded = fld.fold_stmt(expanded_stmt);
fld.cx.bt_pop(); fld.cx.bt_pop();
let fully_expanded: SmallVector<Gc<Stmt>> = fully_expanded.move_iter()
.map(|s| box(GC) Spanned { span: s.span, node: s.node.clone() })
.collect();
fully_expanded.move_iter().map(|s| { if semi {
match s.node { fully_expanded.move_iter().map(|s| s.map(|Spanned {node, span}| {
StmtExpr(e, stmt_id) if semi => { Spanned {
box(GC) Spanned { node: match node {
span: s.span, StmtExpr(e, stmt_id) => StmtSemi(e, stmt_id),
node: StmtSemi(e, stmt_id) _ => node /* might already have a semi */
} },
span: span
} }
_ => s /* might already have a semi */ })).collect()
} } else {
}).collect() fully_expanded
}
} }
// expand a non-macro stmt. this is essentially the fallthrough for // expand a non-macro stmt. this is essentially the fallthrough for
// expand_stmt, above. // expand_stmt, above.
fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander) fn expand_non_macro_stmt(Spanned {node, span: stmt_span}: Stmt, fld: &mut MacroExpander)
-> SmallVector<Gc<Stmt>> { -> SmallVector<P<Stmt>> {
// is it a let? // is it a let?
match s.node { match node {
StmtDecl(decl, node_id) => { StmtDecl(decl, node_id) => decl.and_then(|Spanned {node: decl, span}| match decl {
match *decl { DeclLocal(local) => {
Spanned { // take it apart:
node: DeclLocal(ref local), let rewritten_local = local.map(|Local {id, pat, ty, init, source, span}| {
span: stmt_span
} => {
// take it apart:
let Local {
ty: ty,
pat: pat,
init: init,
id: id,
span: span,
source: source,
} = **local;
// expand the ty since TyFixedLengthVec contains an Expr // expand the ty since TyFixedLengthVec contains an Expr
// and thus may have a macro use // and thus may have a macro use
let expanded_ty = fld.fold_ty(ty); let expanded_ty = fld.fold_ty(ty);
@ -585,57 +571,66 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
}; };
// add them to the existing pending renames: // add them to the existing pending renames:
fld.cx.syntax_env.info().pending_renames.push_all_move(new_pending_renames); fld.cx.syntax_env.info().pending_renames.push_all_move(new_pending_renames);
// also, don't forget to expand the init: Local {
let new_init_opt = init.map(|e| fld.fold_expr(e)); id: id,
let rewritten_local = ty: expanded_ty,
box(GC) Local { pat: rewritten_pat,
ty: expanded_ty, // also, don't forget to expand the init:
pat: rewritten_pat, init: init.map(|e| fld.fold_expr(e)),
init: new_init_opt, source: source,
id: id,
span: span,
source: source
};
SmallVector::one(box(GC) Spanned {
node: StmtDecl(box(GC) Spanned {
node: DeclLocal(rewritten_local),
span: stmt_span
},
node_id),
span: span span: span
}) }
} });
_ => noop_fold_stmt(s, fld), SmallVector::one(P(Spanned {
node: StmtDecl(P(Spanned {
node: DeclLocal(rewritten_local),
span: span
}),
node_id),
span: stmt_span
}))
} }
}, _ => {
_ => noop_fold_stmt(s, fld), noop_fold_stmt(Spanned {
node: StmtDecl(P(Spanned {
node: decl,
span: span
}),
node_id),
span: stmt_span
}, fld)
}
}),
_ => {
noop_fold_stmt(Spanned {
node: node,
span: stmt_span
}, fld)
}
} }
} }
// expand the arm of a 'match', renaming for macro hygiene // expand the arm of a 'match', renaming for macro hygiene
fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm { fn expand_arm(arm: ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
// expand pats... they might contain macro uses: // expand pats... they might contain macro uses:
let expanded_pats : Vec<Gc<ast::Pat>> = arm.pats.iter().map(|pat| fld.fold_pat(*pat)).collect(); let expanded_pats = arm.pats.move_map(|pat| fld.fold_pat(pat));
if expanded_pats.len() == 0 { if expanded_pats.len() == 0 {
fail!("encountered match arm with 0 patterns"); fail!("encountered match arm with 0 patterns");
} }
// all of the pats must have the same set of bindings, so use the // all of the pats must have the same set of bindings, so use the
// first one to extract them and generate new names: // first one to extract them and generate new names:
let first_pat = expanded_pats.get(0); let idents = pattern_bindings(&**expanded_pats.get(0));
let idents = pattern_bindings(&**first_pat); let new_renames = idents.move_iter().map(|id| (id, fresh_name(&id))).collect();
let new_renames =
idents.iter().map(|id| (*id,fresh_name(id))).collect();
// apply the renaming, but only to the PatIdents: // apply the renaming, but only to the PatIdents:
let mut rename_pats_fld = PatIdentRenamer{renames:&new_renames}; let mut rename_pats_fld = PatIdentRenamer{renames:&new_renames};
let rewritten_pats = let rewritten_pats = expanded_pats.move_map(|pat| rename_pats_fld.fold_pat(pat));
expanded_pats.iter().map(|pat| rename_pats_fld.fold_pat(*pat)).collect();
// apply renaming and then expansion to the guard and the body: // apply renaming and then expansion to the guard and the body:
let mut rename_fld = IdentRenamer{renames:&new_renames}; let mut rename_fld = IdentRenamer{renames:&new_renames};
let rewritten_guard = let rewritten_guard =
arm.guard.map(|g| fld.fold_expr(rename_fld.fold_expr(g))); arm.guard.map(|g| fld.fold_expr(rename_fld.fold_expr(g)));
let rewritten_body = fld.fold_expr(rename_fld.fold_expr(arm.body)); let rewritten_body = fld.fold_expr(rename_fld.fold_expr(arm.body));
ast::Arm { ast::Arm {
attrs: arm.attrs.iter().map(|x| fld.fold_attribute(*x)).collect(), attrs: arm.attrs.move_map(|x| fld.fold_attribute(x)),
pats: rewritten_pats, pats: rewritten_pats,
guard: rewritten_guard, guard: rewritten_guard,
body: rewritten_body, body: rewritten_body,
@ -683,121 +678,126 @@ fn fn_decl_arg_bindings(fn_decl: &ast::FnDecl) -> Vec<ast::Ident> {
} }
// expand a block. pushes a new exts_frame, then calls expand_block_elts // expand a block. pushes a new exts_frame, then calls expand_block_elts
fn expand_block(blk: &Block, fld: &mut MacroExpander) -> P<Block> { pub fn expand_block(blk: P<Block>, fld: &mut MacroExpander) -> P<Block> {
// see note below about treatment of exts table // see note below about treatment of exts table
with_exts_frame!(fld.cx.syntax_env,false, with_exts_frame!(fld.cx.syntax_env,false,
expand_block_elts(blk, fld)) expand_block_elts(blk, fld))
} }
// expand the elements of a block. // expand the elements of a block.
fn expand_block_elts(b: &Block, fld: &mut MacroExpander) -> P<Block> { pub fn expand_block_elts(b: P<Block>, fld: &mut MacroExpander) -> P<Block> {
let new_view_items = b.view_items.iter().map(|x| fld.fold_view_item(x)).collect(); b.map(|Block {id, view_items, stmts, expr, rules, span}| {
let new_stmts = let new_view_items = view_items.move_iter().map(|x| fld.fold_view_item(x)).collect();
b.stmts.iter().flat_map(|x| { let new_stmts = stmts.move_iter().flat_map(|x| {
// perform all pending renames // perform all pending renames
let renamed_stmt = { let renamed_stmt = {
let pending_renames = &mut fld.cx.syntax_env.info().pending_renames; let pending_renames = &mut fld.cx.syntax_env.info().pending_renames;
let mut rename_fld = IdentRenamer{renames:pending_renames}; let mut rename_fld = IdentRenamer{renames:pending_renames};
rename_fld.fold_stmt(&**x).expect_one("rename_fold didn't return one value") rename_fld.fold_stmt(x).expect_one("rename_fold didn't return one value")
}; };
// expand macros in the statement // expand macros in the statement
fld.fold_stmt(&*renamed_stmt).move_iter() fld.fold_stmt(renamed_stmt).move_iter()
}).collect(); }).collect();
let new_expr = b.expr.map(|x| { let new_expr = expr.map(|x| {
let expr = { let expr = {
let pending_renames = &mut fld.cx.syntax_env.info().pending_renames; let pending_renames = &mut fld.cx.syntax_env.info().pending_renames;
let mut rename_fld = IdentRenamer{renames:pending_renames}; let mut rename_fld = IdentRenamer{renames:pending_renames};
rename_fld.fold_expr(x) rename_fld.fold_expr(x)
}; };
fld.fold_expr(expr) fld.fold_expr(expr)
}); });
P(Block { Block {
view_items: new_view_items, id: fld.new_id(id),
stmts: new_stmts, view_items: new_view_items,
expr: new_expr, stmts: new_stmts,
id: fld.new_id(b.id), expr: new_expr,
rules: b.rules, rules: rules,
span: b.span, span: span
}
}) })
} }
fn expand_pat(p: Gc<ast::Pat>, fld: &mut MacroExpander) -> Gc<ast::Pat> { fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> {
let (pth, tts) = match p.node { match p.node {
PatMac(ref mac) => { PatMac(_) => {}
match mac.node { _ => return noop_fold_pat(p, fld)
MacInvocTT(ref pth, ref tts, _) => { }
(pth, (*tts).clone()) p.map(|ast::Pat {node, span, ..}| {
let (pth, tts) = match node {
PatMac(mac) => match mac.node {
MacInvocTT(pth, tts, _) => {
(pth, tts)
}
},
_ => unreachable!()
};
if pth.segments.len() > 1u {
fld.cx.span_err(pth.span, "expected macro name without module separators");
return DummyResult::raw_pat(span);
}
let extname = pth.segments.get(0).identifier;
let extnamestr = token::get_ident(extname);
let marked_after = match fld.cx.syntax_env.find(&extname.name) {
None => {
fld.cx.span_err(pth.span,
format!("macro undefined: '{}!'",
extnamestr).as_slice());
// let compilation continue
return DummyResult::raw_pat(span);
}
Some(rc) => match *rc {
NormalTT(ref expander, tt_span) => {
fld.cx.bt_push(ExpnInfo {
call_site: span,
callee: NameAndSpan {
name: extnamestr.get().to_string(),
format: MacroBang,
span: tt_span
}
});
let fm = fresh_mark();
let marked_before = mark_tts(tts.as_slice(), fm);
let mac_span = original_span(fld.cx);
let expanded = match expander.expand(fld.cx,
mac_span.call_site,
marked_before.as_slice()).make_pat() {
Some(e) => e,
None => {
fld.cx.span_err(
pth.span,
format!(
"non-pattern macro in pattern position: {}",
extnamestr.get()
).as_slice()
);
return DummyResult::raw_pat(span);
}
};
// mark after:
mark_pat(expanded,fm)
}
_ => {
fld.cx.span_err(span,
format!("{}! is not legal in pattern position",
extnamestr.get()).as_slice());
return DummyResult::raw_pat(span);
} }
} }
};
let fully_expanded =
fld.fold_pat(marked_after).node.clone();
fld.cx.bt_pop();
ast::Pat {
id: ast::DUMMY_NODE_ID,
node: fully_expanded,
span: span
} }
_ => return noop_fold_pat(p, fld), })
};
if pth.segments.len() > 1u {
fld.cx.span_err(pth.span, "expected macro name without module separators");
return DummyResult::raw_pat(p.span);
}
let extname = pth.segments.get(0).identifier;
let extnamestr = token::get_ident(extname);
let marked_after = match fld.cx.syntax_env.find(&extname.name) {
None => {
fld.cx.span_err(pth.span,
format!("macro undefined: '{}!'",
extnamestr).as_slice());
// let compilation continue
return DummyResult::raw_pat(p.span);
}
Some(rc) => match *rc {
NormalTT(ref expander, span) => {
fld.cx.bt_push(ExpnInfo {
call_site: p.span,
callee: NameAndSpan {
name: extnamestr.get().to_string(),
format: MacroBang,
span: span
}
});
let fm = fresh_mark();
let marked_before = mark_tts(tts.as_slice(), fm);
let mac_span = original_span(fld.cx);
let expanded = match expander.expand(fld.cx,
mac_span.call_site,
marked_before.as_slice()).make_pat() {
Some(e) => e,
None => {
fld.cx.span_err(
pth.span,
format!(
"non-pattern macro in pattern position: {}",
extnamestr.get()
).as_slice()
);
return DummyResult::raw_pat(p.span);
}
};
// mark after:
mark_pat(expanded,fm)
}
_ => {
fld.cx.span_err(p.span,
format!("{}! is not legal in pattern position",
extnamestr.get()).as_slice());
return DummyResult::raw_pat(p.span);
}
}
};
let fully_expanded =
fld.fold_pat(marked_after).node.clone();
fld.cx.bt_pop();
box(GC) ast::Pat {
id: ast::DUMMY_NODE_ID,
node: fully_expanded,
span: p.span,
}
} }
/// A tree-folder that applies every rename in its (mutable) list /// A tree-folder that applies every rename in its (mutable) list
@ -814,7 +814,7 @@ impl<'a> Folder for IdentRenamer<'a> {
ctxt: mtwt::apply_renames(self.renames, id.ctxt), ctxt: mtwt::apply_renames(self.renames, id.ctxt),
} }
} }
fn fold_mac(&mut self, macro: &ast::Mac) -> ast::Mac { fn fold_mac(&mut self, macro: ast::Mac) -> ast::Mac {
fold::noop_fold_mac(macro, self) fold::noop_fold_mac(macro, self)
} }
} }
@ -828,45 +828,50 @@ pub struct PatIdentRenamer<'a> {
} }
impl<'a> Folder for PatIdentRenamer<'a> { impl<'a> Folder for PatIdentRenamer<'a> {
fn fold_pat(&mut self, pat: Gc<ast::Pat>) -> Gc<ast::Pat> { fn fold_pat(&mut self, pat: P<ast::Pat>) -> P<ast::Pat> {
match pat.node { match pat.node {
ast::PatIdent(binding_mode, Spanned{span: ref sp, node: id}, ref sub) => { ast::PatIdent(..) => {},
let new_ident = Ident{name: id.name, _ => return noop_fold_pat(pat, self)
ctxt: mtwt::apply_renames(self.renames, id.ctxt)}; }
pat.map(|ast::Pat {id, node, span}| match node {
ast::PatIdent(binding_mode, Spanned{span: sp, node: ident}, sub) => {
let new_ident = Ident{name: ident.name,
ctxt: mtwt::apply_renames(self.renames, ident.ctxt)};
let new_node = let new_node =
ast::PatIdent(binding_mode, ast::PatIdent(binding_mode,
Spanned{span: self.new_span(*sp), node: new_ident}, Spanned{span: self.new_span(sp), node: new_ident},
sub.map(|p| self.fold_pat(p))); sub.map(|p| self.fold_pat(p)));
box(GC) ast::Pat { ast::Pat {
id: pat.id, id: id,
span: self.new_span(pat.span),
node: new_node, node: new_node,
span: self.new_span(span)
} }
}, },
_ => noop_fold_pat(pat, self) _ => unreachable!()
} })
} }
fn fold_mac(&mut self, macro: &ast::Mac) -> ast::Mac { fn fold_mac(&mut self, macro: ast::Mac) -> ast::Mac {
fold::noop_fold_mac(macro, self) fold::noop_fold_mac(macro, self)
} }
} }
// expand a method // expand a method
fn expand_method(m: &ast::Method, fld: &mut MacroExpander) -> SmallVector<Gc<ast::Method>> { fn expand_method(m: P<ast::Method>, fld: &mut MacroExpander) -> SmallVector<P<ast::Method>> {
let id = fld.new_id(m.id); m.and_then(|m| match m.node {
match m.node {
ast::MethDecl(ident, ast::MethDecl(ident,
ref generics, generics,
abi, abi,
ref explicit_self, explicit_self,
fn_style, fn_style,
decl, decl,
body, body,
vis) => { vis) => {
let id = fld.new_id(m.id);
let (rewritten_fn_decl, rewritten_body) let (rewritten_fn_decl, rewritten_body)
= expand_and_rename_fn_decl_and_block(&*decl,body,fld); = expand_and_rename_fn_decl_and_block(decl,body,fld);
SmallVector::one(box(GC) ast::Method { SmallVector::one(P(ast::Method {
attrs: m.attrs.iter().map(|a| fld.fold_attribute(*a)).collect(), attrs: m.attrs.move_map(|a| fld.fold_attribute(a)),
id: id, id: id,
span: fld.new_span(m.span), span: fld.new_span(m.span),
node: ast::MethDecl(fld.fold_ident(ident), node: ast::MethDecl(fld.fold_ident(ident),
@ -877,15 +882,13 @@ fn expand_method(m: &ast::Method, fld: &mut MacroExpander) -> SmallVector<Gc<ast
rewritten_fn_decl, rewritten_fn_decl,
rewritten_body, rewritten_body,
vis) vis)
}) }))
}, },
ast::MethMac(ref mac) => { ast::MethMac(mac) => {
let maybe_new_methods = let maybe_new_methods =
expand_mac_invoc(mac, &m.span, expand_mac_invoc(mac, m.span,
|r|{r.make_methods()}, |r| r.make_methods(),
|meths,mark|{ |meths, mark| meths.move_map(|m| mark_method(m, mark)),
meths.move_iter().map(|m|{mark_method(m,mark)})
.collect()},
fld); fld);
let new_methods = match maybe_new_methods { let new_methods = match maybe_new_methods {
@ -896,22 +899,22 @@ fn expand_method(m: &ast::Method, fld: &mut MacroExpander) -> SmallVector<Gc<ast
// expand again if necessary // expand again if necessary
new_methods.move_iter().flat_map(|m| fld.fold_method(m).move_iter()).collect() new_methods.move_iter().flat_map(|m| fld.fold_method(m).move_iter()).collect()
} }
} })
} }
/// Given a fn_decl and a block and a MacroExpander, expand the fn_decl, then use the /// Given a fn_decl and a block and a MacroExpander, expand the fn_decl, then use the
/// PatIdents in its arguments to perform renaming in the FnDecl and /// PatIdents in its arguments to perform renaming in the FnDecl and
/// the block, returning both the new FnDecl and the new Block. /// the block, returning both the new FnDecl and the new Block.
fn expand_and_rename_fn_decl_and_block(fn_decl: &ast::FnDecl, block: Gc<ast::Block>, fn expand_and_rename_fn_decl_and_block(fn_decl: P<ast::FnDecl>, block: P<ast::Block>,
fld: &mut MacroExpander) fld: &mut MacroExpander)
-> (Gc<ast::FnDecl>, Gc<ast::Block>) { -> (P<ast::FnDecl>, P<ast::Block>) {
let expanded_decl = fld.fold_fn_decl(fn_decl); let expanded_decl = fld.fold_fn_decl(fn_decl);
let idents = fn_decl_arg_bindings(&*expanded_decl); let idents = fn_decl_arg_bindings(&*expanded_decl);
let renames = let renames =
idents.iter().map(|id : &ast::Ident| (*id,fresh_name(id))).collect(); idents.iter().map(|id : &ast::Ident| (*id,fresh_name(id))).collect();
// first, a renamer for the PatIdents, for the fn_decl: // first, a renamer for the PatIdents, for the fn_decl:
let mut rename_pat_fld = PatIdentRenamer{renames: &renames}; let mut rename_pat_fld = PatIdentRenamer{renames: &renames};
let rewritten_fn_decl = rename_pat_fld.fold_fn_decl(&*expanded_decl); let rewritten_fn_decl = rename_pat_fld.fold_fn_decl(expanded_decl);
// now, a renamer for *all* idents, for the body: // now, a renamer for *all* idents, for the body:
let mut rename_fld = IdentRenamer{renames: &renames}; let mut rename_fld = IdentRenamer{renames: &renames};
let rewritten_body = fld.fold_block(rename_fld.fold_block(block)); let rewritten_body = fld.fold_block(rename_fld.fold_block(block));
@ -924,36 +927,36 @@ pub struct MacroExpander<'a, 'b:'a> {
} }
impl<'a, 'b> Folder for MacroExpander<'a, 'b> { impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
fn fold_expr(&mut self, expr: Gc<ast::Expr>) -> Gc<ast::Expr> { fn fold_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
expand_expr(expr, self) expand_expr(expr, self)
} }
fn fold_pat(&mut self, pat: Gc<ast::Pat>) -> Gc<ast::Pat> { fn fold_pat(&mut self, pat: P<ast::Pat>) -> P<ast::Pat> {
expand_pat(pat, self) expand_pat(pat, self)
} }
fn fold_item(&mut self, item: Gc<ast::Item>) -> SmallVector<Gc<ast::Item>> { fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
expand_item(item, self) expand_item(item, self)
} }
fn fold_item_underscore(&mut self, item: &ast::Item_) -> ast::Item_ { fn fold_item_underscore(&mut self, item: ast::Item_) -> ast::Item_ {
expand_item_underscore(item, self) expand_item_underscore(item, self)
} }
fn fold_stmt(&mut self, stmt: &ast::Stmt) -> SmallVector<Gc<ast::Stmt>> { fn fold_stmt(&mut self, stmt: P<ast::Stmt>) -> SmallVector<P<ast::Stmt>> {
expand_stmt(stmt, self) stmt.and_then(|stmt| expand_stmt(stmt, self))
} }
fn fold_block(&mut self, block: P<Block>) -> P<Block> { fn fold_block(&mut self, block: P<Block>) -> P<Block> {
expand_block(&*block, self) expand_block(block, self)
} }
fn fold_arm(&mut self, arm: &ast::Arm) -> ast::Arm { fn fold_arm(&mut self, arm: ast::Arm) -> ast::Arm {
expand_arm(arm, self) expand_arm(arm, self)
} }
fn fold_method(&mut self, method: Gc<ast::Method>) -> SmallVector<Gc<ast::Method>> { fn fold_method(&mut self, method: P<ast::Method>) -> SmallVector<P<ast::Method>> {
expand_method(&*method, self) expand_method(method, self)
} }
fn new_span(&mut self, span: Span) -> Span { fn new_span(&mut self, span: Span) -> Span {
@ -1033,17 +1036,16 @@ impl Folder for Marker {
ctxt: mtwt::apply_mark(self.mark, id.ctxt) ctxt: mtwt::apply_mark(self.mark, id.ctxt)
} }
} }
fn fold_mac(&mut self, m: &ast::Mac) -> ast::Mac { fn fold_mac(&mut self, Spanned {node, span}: ast::Mac) -> ast::Mac {
let macro = match m.node {
MacInvocTT(ref path, ref tts, ctxt) => {
MacInvocTT(self.fold_path(path),
self.fold_tts(tts.as_slice()),
mtwt::apply_mark(self.mark, ctxt))
}
};
Spanned { Spanned {
node: macro, node: match node {
span: m.span, MacInvocTT(path, tts, ctxt) => {
MacInvocTT(self.fold_path(path),
self.fold_tts(tts.as_slice()),
mtwt::apply_mark(self.mark, ctxt))
}
},
span: span,
} }
} }
} }
@ -1054,29 +1056,29 @@ fn mark_tts(tts: &[TokenTree], m: Mrk) -> Vec<TokenTree> {
} }
// apply a given mark to the given expr. Used following the expansion of a macro. // apply a given mark to the given expr. Used following the expansion of a macro.
fn mark_expr(expr: Gc<ast::Expr>, m: Mrk) -> Gc<ast::Expr> { fn mark_expr(expr: P<ast::Expr>, m: Mrk) -> P<ast::Expr> {
Marker{mark:m}.fold_expr(expr) Marker{mark:m}.fold_expr(expr)
} }
// apply a given mark to the given pattern. Used following the expansion of a macro. // apply a given mark to the given pattern. Used following the expansion of a macro.
fn mark_pat(pat: Gc<ast::Pat>, m: Mrk) -> Gc<ast::Pat> { fn mark_pat(pat: P<ast::Pat>, m: Mrk) -> P<ast::Pat> {
Marker{mark:m}.fold_pat(pat) Marker{mark:m}.fold_pat(pat)
} }
// apply a given mark to the given stmt. Used following the expansion of a macro. // apply a given mark to the given stmt. Used following the expansion of a macro.
fn mark_stmt(expr: &ast::Stmt, m: Mrk) -> Gc<ast::Stmt> { fn mark_stmt(expr: P<ast::Stmt>, m: Mrk) -> P<ast::Stmt> {
Marker{mark:m}.fold_stmt(expr) Marker{mark:m}.fold_stmt(expr)
.expect_one("marking a stmt didn't return exactly one stmt") .expect_one("marking a stmt didn't return exactly one stmt")
} }
// apply a given mark to the given item. Used following the expansion of a macro. // apply a given mark to the given item. Used following the expansion of a macro.
fn mark_item(expr: Gc<ast::Item>, m: Mrk) -> Gc<ast::Item> { fn mark_item(expr: P<ast::Item>, m: Mrk) -> P<ast::Item> {
Marker{mark:m}.fold_item(expr) Marker{mark:m}.fold_item(expr)
.expect_one("marking an item didn't return exactly one item") .expect_one("marking an item didn't return exactly one item")
} }
// apply a given mark to the given item. Used following the expansion of a macro. // apply a given mark to the given item. Used following the expansion of a macro.
fn mark_method(expr: Gc<ast::Method>, m: Mrk) -> Gc<ast::Method> { fn mark_method(expr: P<ast::Method>, m: Mrk) -> P<ast::Method> {
Marker{mark:m}.fold_method(expr) Marker{mark:m}.fold_method(expr)
.expect_one("marking an item didn't return exactly one method") .expect_one("marking an item didn't return exactly one method")
} }
@ -1133,8 +1135,6 @@ mod test {
use visit; use visit;
use visit::Visitor; use visit::Visitor;
use std::gc::GC;
// a visitor that extracts the paths // a visitor that extracts the paths
// from a given thingy and puts them in a mutable // from a given thingy and puts them in a mutable
// array (passed in to the traversal) // array (passed in to the traversal)
@ -1252,10 +1252,10 @@ mod test {
node: Attribute_ { node: Attribute_ {
id: attr::mk_attr_id(), id: attr::mk_attr_id(),
style: AttrOuter, style: AttrOuter,
value: box(GC) Spanned { value: P(Spanned {
node: MetaWord(token::intern_and_get_ident(s)), node: MetaWord(token::intern_and_get_ident(s)),
span: codemap::DUMMY_SP, span: codemap::DUMMY_SP,
}, }),
is_sugared_doc: false, is_sugared_doc: false,
} }
} }

View file

@ -9,7 +9,6 @@
// except according to those terms. // except according to those terms.
use ast; use ast;
use ast::P;
use codemap::{Span, respan}; use codemap::{Span, respan};
use ext::base::*; use ext::base::*;
use ext::base; use ext::base;
@ -17,9 +16,9 @@ use ext::build::AstBuilder;
use fmt_macros as parse; use fmt_macros as parse;
use parse::token::InternedString; use parse::token::InternedString;
use parse::token; use parse::token;
use ptr::P;
use std::collections::HashMap; use std::collections::HashMap;
use std::gc::{Gc, GC};
#[deriving(PartialEq)] #[deriving(PartialEq)]
enum ArgumentType { enum ArgumentType {
@ -39,13 +38,13 @@ struct Context<'a, 'b:'a> {
/// Parsed argument expressions and the types that we've found so far for /// Parsed argument expressions and the types that we've found so far for
/// them. /// them.
args: Vec<Gc<ast::Expr>>, args: Vec<P<ast::Expr>>,
arg_types: Vec<Option<ArgumentType>>, arg_types: Vec<Option<ArgumentType>>,
/// Parsed named expressions and the types that we've found for them so far. /// Parsed named expressions and the types that we've found for them so far.
/// Note that we keep a side-array of the ordering of the named arguments /// Note that we keep a side-array of the ordering of the named arguments
/// found to be sure that we can translate them in the same order that they /// found to be sure that we can translate them in the same order that they
/// were declared in. /// were declared in.
names: HashMap<String, Gc<ast::Expr>>, names: HashMap<String, P<ast::Expr>>,
name_types: HashMap<String, ArgumentType>, name_types: HashMap<String, ArgumentType>,
name_ordering: Vec<String>, name_ordering: Vec<String>,
@ -53,14 +52,14 @@ struct Context<'a, 'b:'a> {
literal: String, literal: String,
/// Collection of the compiled `rt::Argument` structures /// Collection of the compiled `rt::Argument` structures
pieces: Vec<Gc<ast::Expr>>, pieces: Vec<P<ast::Expr>>,
/// Collection of string literals /// Collection of string literals
str_pieces: Vec<Gc<ast::Expr>>, str_pieces: Vec<P<ast::Expr>>,
/// Stays `true` if all formatting parameters are default (as in "{}{}"). /// Stays `true` if all formatting parameters are default (as in "{}{}").
all_pieces_simple: bool, all_pieces_simple: bool,
name_positions: HashMap<String, uint>, name_positions: HashMap<String, uint>,
method_statics: Vec<Gc<ast::Item>>, method_statics: Vec<P<ast::Item>>,
/// Updated as arguments are consumed or methods are entered /// Updated as arguments are consumed or methods are entered
nest_level: uint, nest_level: uint,
@ -68,8 +67,8 @@ struct Context<'a, 'b:'a> {
} }
pub enum Invocation { pub enum Invocation {
Call(Gc<ast::Expr>), Call(P<ast::Expr>),
MethodCall(Gc<ast::Expr>, ast::Ident), MethodCall(P<ast::Expr>, ast::Ident),
} }
/// Parses the arguments from the given list of tokens, returning None /// Parses the arguments from the given list of tokens, returning None
@ -82,10 +81,10 @@ pub enum Invocation {
/// named arguments)) /// named arguments))
fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool, fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool,
tts: &[ast::TokenTree]) tts: &[ast::TokenTree])
-> (Invocation, Option<(Gc<ast::Expr>, Vec<Gc<ast::Expr>>, Vec<String>, -> (Invocation, Option<(P<ast::Expr>, Vec<P<ast::Expr>>, Vec<String>,
HashMap<String, Gc<ast::Expr>>)>) { HashMap<String, P<ast::Expr>>)>) {
let mut args = Vec::new(); let mut args = Vec::new();
let mut names = HashMap::<String, Gc<ast::Expr>>::new(); let mut names = HashMap::<String, P<ast::Expr>>::new();
let mut order = Vec::new(); let mut order = Vec::new();
let mut p = ecx.new_parser_from_tts(tts); let mut p = ecx.new_parser_from_tts(tts);
@ -323,44 +322,44 @@ impl<'a, 'b> Context<'a, 'b> {
/// These attributes are applied to all statics that this syntax extension /// These attributes are applied to all statics that this syntax extension
/// will generate. /// will generate.
fn static_attrs(&self) -> Vec<ast::Attribute> { fn static_attrs(ecx: &ExtCtxt, fmtsp: Span) -> Vec<ast::Attribute> {
// Flag statics as `inline` so LLVM can merge duplicate globals as much // Flag statics as `inline` so LLVM can merge duplicate globals as much
// as possible (which we're generating a whole lot of). // as possible (which we're generating a whole lot of).
let unnamed = self.ecx.meta_word(self.fmtsp, InternedString::new("inline")); let unnamed = ecx.meta_word(fmtsp, InternedString::new("inline"));
let unnamed = self.ecx.attribute(self.fmtsp, unnamed); let unnamed = ecx.attribute(fmtsp, unnamed);
// Do not warn format string as dead code // Do not warn format string as dead code
let dead_code = self.ecx.meta_word(self.fmtsp, let dead_code = ecx.meta_word(fmtsp, InternedString::new("dead_code"));
InternedString::new("dead_code")); let allow_dead_code = ecx.meta_list(fmtsp,
let allow_dead_code = self.ecx.meta_list(self.fmtsp, InternedString::new("allow"),
InternedString::new("allow"), vec![dead_code]);
vec!(dead_code)); let allow_dead_code = ecx.attribute(fmtsp, allow_dead_code);
let allow_dead_code = self.ecx.attribute(self.fmtsp, allow_dead_code); vec![unnamed, allow_dead_code]
return vec!(unnamed, allow_dead_code);
} }
fn rtpath(&self, s: &str) -> Vec<ast::Ident> { fn rtpath(ecx: &ExtCtxt, s: &str) -> Vec<ast::Ident> {
vec!(self.ecx.ident_of("std"), self.ecx.ident_of("fmt"), vec![ecx.ident_of("std"), ecx.ident_of("fmt"), ecx.ident_of("rt"), ecx.ident_of(s)]
self.ecx.ident_of("rt"), self.ecx.ident_of(s))
} }
fn trans_count(&self, c: parse::Count) -> Gc<ast::Expr> { fn trans_count(&self, c: parse::Count) -> P<ast::Expr> {
let sp = self.fmtsp; let sp = self.fmtsp;
match c { match c {
parse::CountIs(i) => { parse::CountIs(i) => {
self.ecx.expr_call_global(sp, self.rtpath("CountIs"), self.ecx.expr_call_global(sp, Context::rtpath(self.ecx, "CountIs"),
vec!(self.ecx.expr_uint(sp, i))) vec!(self.ecx.expr_uint(sp, i)))
} }
parse::CountIsParam(i) => { parse::CountIsParam(i) => {
self.ecx.expr_call_global(sp, self.rtpath("CountIsParam"), self.ecx.expr_call_global(sp, Context::rtpath(self.ecx, "CountIsParam"),
vec!(self.ecx.expr_uint(sp, i))) vec!(self.ecx.expr_uint(sp, i)))
} }
parse::CountImplied => { parse::CountImplied => {
let path = self.ecx.path_global(sp, self.rtpath("CountImplied")); let path = self.ecx.path_global(sp, Context::rtpath(self.ecx,
"CountImplied"));
self.ecx.expr_path(path) self.ecx.expr_path(path)
} }
parse::CountIsNextParam => { parse::CountIsNextParam => {
let path = self.ecx.path_global(sp, self.rtpath("CountIsNextParam")); let path = self.ecx.path_global(sp, Context::rtpath(self.ecx,
"CountIsNextParam"));
self.ecx.expr_path(path) self.ecx.expr_path(path)
} }
parse::CountIsName(n) => { parse::CountIsName(n) => {
@ -369,14 +368,14 @@ impl<'a, 'b> Context<'a, 'b> {
None => 0, // error already emitted elsewhere None => 0, // error already emitted elsewhere
}; };
let i = i + self.args.len(); let i = i + self.args.len();
self.ecx.expr_call_global(sp, self.rtpath("CountIsParam"), self.ecx.expr_call_global(sp, Context::rtpath(self.ecx, "CountIsParam"),
vec!(self.ecx.expr_uint(sp, i))) vec!(self.ecx.expr_uint(sp, i)))
} }
} }
} }
/// Translate the accumulated string literals to a literal expression /// Translate the accumulated string literals to a literal expression
fn trans_literal_string(&mut self) -> Gc<ast::Expr> { fn trans_literal_string(&mut self) -> P<ast::Expr> {
let sp = self.fmtsp; let sp = self.fmtsp;
let s = token::intern_and_get_ident(self.literal.as_slice()); let s = token::intern_and_get_ident(self.literal.as_slice());
self.literal.clear(); self.literal.clear();
@ -385,7 +384,7 @@ impl<'a, 'b> Context<'a, 'b> {
/// Translate a `parse::Piece` to a static `rt::Argument` or append /// Translate a `parse::Piece` to a static `rt::Argument` or append
/// to the `literal` string. /// to the `literal` string.
fn trans_piece(&mut self, piece: &parse::Piece) -> Option<Gc<ast::Expr>> { fn trans_piece(&mut self, piece: &parse::Piece) -> Option<P<ast::Expr>> {
let sp = self.fmtsp; let sp = self.fmtsp;
match *piece { match *piece {
parse::String(s) => { parse::String(s) => {
@ -397,12 +396,12 @@ impl<'a, 'b> Context<'a, 'b> {
let pos = match arg.position { let pos = match arg.position {
// These two have a direct mapping // These two have a direct mapping
parse::ArgumentNext => { parse::ArgumentNext => {
let path = self.ecx.path_global(sp, let path = self.ecx.path_global(sp, Context::rtpath(self.ecx,
self.rtpath("ArgumentNext")); "ArgumentNext"));
self.ecx.expr_path(path) self.ecx.expr_path(path)
} }
parse::ArgumentIs(i) => { parse::ArgumentIs(i) => {
self.ecx.expr_call_global(sp, self.rtpath("ArgumentIs"), self.ecx.expr_call_global(sp, Context::rtpath(self.ecx, "ArgumentIs"),
vec!(self.ecx.expr_uint(sp, i))) vec!(self.ecx.expr_uint(sp, i)))
} }
// Named arguments are converted to positional arguments at // Named arguments are converted to positional arguments at
@ -413,7 +412,7 @@ impl<'a, 'b> Context<'a, 'b> {
None => 0, // error already emitted elsewhere None => 0, // error already emitted elsewhere
}; };
let i = i + self.args.len(); let i = i + self.args.len();
self.ecx.expr_call_global(sp, self.rtpath("ArgumentIs"), self.ecx.expr_call_global(sp, Context::rtpath(self.ecx, "ArgumentIs"),
vec!(self.ecx.expr_uint(sp, i))) vec!(self.ecx.expr_uint(sp, i)))
} }
}; };
@ -440,23 +439,23 @@ impl<'a, 'b> Context<'a, 'b> {
let fill = self.ecx.expr_lit(sp, ast::LitChar(fill)); let fill = self.ecx.expr_lit(sp, ast::LitChar(fill));
let align = match arg.format.align { let align = match arg.format.align {
parse::AlignLeft => { parse::AlignLeft => {
self.ecx.path_global(sp, self.rtpath("AlignLeft")) self.ecx.path_global(sp, Context::rtpath(self.ecx, "AlignLeft"))
} }
parse::AlignRight => { parse::AlignRight => {
self.ecx.path_global(sp, self.rtpath("AlignRight")) self.ecx.path_global(sp, Context::rtpath(self.ecx, "AlignRight"))
} }
parse::AlignCenter => { parse::AlignCenter => {
self.ecx.path_global(sp, self.rtpath("AlignCenter")) self.ecx.path_global(sp, Context::rtpath(self.ecx, "AlignCenter"))
} }
parse::AlignUnknown => { parse::AlignUnknown => {
self.ecx.path_global(sp, self.rtpath("AlignUnknown")) self.ecx.path_global(sp, Context::rtpath(self.ecx, "AlignUnknown"))
} }
}; };
let align = self.ecx.expr_path(align); let align = self.ecx.expr_path(align);
let flags = self.ecx.expr_uint(sp, arg.format.flags); let flags = self.ecx.expr_uint(sp, arg.format.flags);
let prec = self.trans_count(arg.format.precision); let prec = self.trans_count(arg.format.precision);
let width = self.trans_count(arg.format.width); let width = self.trans_count(arg.format.width);
let path = self.ecx.path_global(sp, self.rtpath("FormatSpec")); let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, "FormatSpec"));
let fmt = self.ecx.expr_struct(sp, path, vec!( let fmt = self.ecx.expr_struct(sp, path, vec!(
self.ecx.field_imm(sp, self.ecx.ident_of("fill"), fill), self.ecx.field_imm(sp, self.ecx.ident_of("fill"), fill),
self.ecx.field_imm(sp, self.ecx.ident_of("align"), align), self.ecx.field_imm(sp, self.ecx.ident_of("align"), align),
@ -464,7 +463,7 @@ impl<'a, 'b> Context<'a, 'b> {
self.ecx.field_imm(sp, self.ecx.ident_of("precision"), prec), self.ecx.field_imm(sp, self.ecx.ident_of("precision"), prec),
self.ecx.field_imm(sp, self.ecx.ident_of("width"), width))); self.ecx.field_imm(sp, self.ecx.ident_of("width"), width)));
let path = self.ecx.path_global(sp, self.rtpath("Argument")); let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, "Argument"));
Some(self.ecx.expr_struct(sp, path, vec!( Some(self.ecx.expr_struct(sp, path, vec!(
self.ecx.field_imm(sp, self.ecx.ident_of("position"), pos), self.ecx.field_imm(sp, self.ecx.ident_of("position"), pos),
self.ecx.field_imm(sp, self.ecx.ident_of("format"), fmt)))) self.ecx.field_imm(sp, self.ecx.ident_of("format"), fmt))))
@ -472,29 +471,28 @@ impl<'a, 'b> Context<'a, 'b> {
} }
} }
fn item_static_array(&self, fn item_static_array(ecx: &mut ExtCtxt,
name: ast::Ident, name: ast::Ident,
piece_ty: Gc<ast::Ty>, piece_ty: P<ast::Ty>,
pieces: Vec<Gc<ast::Expr>>) pieces: Vec<P<ast::Expr>>)
-> ast::Stmt -> P<ast::Stmt> {
{ let fmtsp = piece_ty.span;
let pieces_len = self.ecx.expr_uint(self.fmtsp, pieces.len()); let pieces_len = ecx.expr_uint(fmtsp, pieces.len());
let fmt = self.ecx.expr_vec(self.fmtsp, pieces); let fmt = ecx.expr_vec(fmtsp, pieces);
let ty = ast::TyFixedLengthVec( let ty = ast::TyFixedLengthVec(
piece_ty, piece_ty,
pieces_len pieces_len
); );
let ty = self.ecx.ty(self.fmtsp, ty); let ty = ecx.ty(fmtsp, ty);
let st = ast::ItemStatic(ty, ast::MutImmutable, fmt); let st = ast::ItemStatic(ty, ast::MutImmutable, fmt);
let item = self.ecx.item(self.fmtsp, name, let item = ecx.item(fmtsp, name, Context::static_attrs(ecx, fmtsp), st);
self.static_attrs(), st); let decl = respan(fmtsp, ast::DeclItem(item));
let decl = respan(self.fmtsp, ast::DeclItem(item)); P(respan(fmtsp, ast::StmtDecl(P(decl), ast::DUMMY_NODE_ID)))
respan(self.fmtsp, ast::StmtDecl(box(GC) decl, ast::DUMMY_NODE_ID))
} }
/// Actually builds the expression which the iformat! block will be expanded /// Actually builds the expression which the iformat! block will be expanded
/// to /// to
fn to_expr(&self, invocation: Invocation) -> Gc<ast::Expr> { fn to_expr(mut self, invocation: Invocation) -> P<ast::Expr> {
let mut lets = Vec::new(); let mut lets = Vec::new();
let mut locals = Vec::new(); let mut locals = Vec::new();
let mut names = Vec::from_fn(self.name_positions.len(), |_| None); let mut names = Vec::from_fn(self.name_positions.len(), |_| None);
@ -502,10 +500,10 @@ impl<'a, 'b> Context<'a, 'b> {
let mut heads = Vec::new(); let mut heads = Vec::new();
// First, declare all of our methods that are statics // First, declare all of our methods that are statics
for &method in self.method_statics.iter() { for method in self.method_statics.move_iter() {
let decl = respan(self.fmtsp, ast::DeclItem(method)); let decl = respan(self.fmtsp, ast::DeclItem(method));
lets.push(box(GC) respan(self.fmtsp, lets.push(P(respan(self.fmtsp,
ast::StmtDecl(box(GC) decl, ast::DUMMY_NODE_ID))); ast::StmtDecl(P(decl), ast::DUMMY_NODE_ID))));
} }
// Next, build up the static array which will become our precompiled // Next, build up the static array which will become our precompiled
@ -517,9 +515,10 @@ impl<'a, 'b> Context<'a, 'b> {
self.ecx.ty_ident(self.fmtsp, self.ecx.ident_of("str")), self.ecx.ty_ident(self.fmtsp, self.ecx.ident_of("str")),
Some(static_lifetime), Some(static_lifetime),
ast::MutImmutable); ast::MutImmutable);
lets.push(box(GC) self.item_static_array(static_str_name, lets.push(Context::item_static_array(self.ecx,
piece_ty, static_str_name,
self.str_pieces.clone())); piece_ty,
self.str_pieces));
// Then, build up the static array which will store our precompiled // Then, build up the static array which will store our precompiled
// nonstandard placeholders, if there are any. // nonstandard placeholders, if there are any.
@ -527,13 +526,14 @@ impl<'a, 'b> Context<'a, 'b> {
if !self.all_pieces_simple { if !self.all_pieces_simple {
let piece_ty = self.ecx.ty_path(self.ecx.path_all( let piece_ty = self.ecx.ty_path(self.ecx.path_all(
self.fmtsp, self.fmtsp,
true, self.rtpath("Argument"), true, Context::rtpath(self.ecx, "Argument"),
vec![static_lifetime], vec![static_lifetime],
vec![] vec![]
), None); ), None);
lets.push(box(GC) self.item_static_array(static_args_name, lets.push(Context::item_static_array(self.ecx,
piece_ty, static_args_name,
self.pieces.clone())); piece_ty,
self.pieces));
} }
// Right now there is a bug such that for the expression: // Right now there is a bug such that for the expression:
@ -543,31 +543,35 @@ impl<'a, 'b> Context<'a, 'b> {
// format! string are shoved into locals. Furthermore, we shove the address // format! string are shoved into locals. Furthermore, we shove the address
// of each variable because we don't want to move out of the arguments // of each variable because we don't want to move out of the arguments
// passed to this function. // passed to this function.
for (i, &e) in self.args.iter().enumerate() { for (i, e) in self.args.move_iter().enumerate() {
if self.arg_types.get(i).is_none() { let arg_ty = match self.arg_types.get(i).as_ref() {
continue // error already generated Some(ty) => ty,
} None => continue // error already generated
};
let name = self.ecx.ident_of(format!("__arg{}", i).as_slice()); let name = self.ecx.ident_of(format!("__arg{}", i).as_slice());
pats.push(self.ecx.pat_ident(e.span, name)); pats.push(self.ecx.pat_ident(e.span, name));
locals.push(Context::format_arg(self.ecx, e.span, arg_ty,
self.ecx.expr_ident(e.span, name)));
heads.push(self.ecx.expr_addr_of(e.span, e)); heads.push(self.ecx.expr_addr_of(e.span, e));
locals.push(self.format_arg(e.span, Exact(i),
self.ecx.expr_ident(e.span, name)));
} }
for name in self.name_ordering.iter() { for name in self.name_ordering.iter() {
let e = match self.names.find(name) { let e = match self.names.pop(name) {
Some(&e) if self.name_types.contains_key(name) => e, Some(e) => e,
Some(..) | None => continue None => continue
};
let arg_ty = match self.name_types.find(name) {
Some(ty) => ty,
None => continue
}; };
let lname = self.ecx.ident_of(format!("__arg{}", let lname = self.ecx.ident_of(format!("__arg{}",
*name).as_slice()); *name).as_slice());
pats.push(self.ecx.pat_ident(e.span, lname)); pats.push(self.ecx.pat_ident(e.span, lname));
heads.push(self.ecx.expr_addr_of(e.span, e));
*names.get_mut(*self.name_positions.get(name)) = *names.get_mut(*self.name_positions.get(name)) =
Some(self.format_arg(e.span, Some(Context::format_arg(self.ecx, e.span, arg_ty,
Named((*name).clone()), self.ecx.expr_ident(e.span, lname)));
self.ecx.expr_ident(e.span, lname))); heads.push(self.ecx.expr_addr_of(e.span, e));
} }
// Now create a vector containing all the arguments // Now create a vector containing all the arguments
@ -611,12 +615,14 @@ impl<'a, 'b> Context<'a, 'b> {
let res = self.ecx.expr_ident(self.fmtsp, resname); let res = self.ecx.expr_ident(self.fmtsp, resname);
let result = match invocation { let result = match invocation {
Call(e) => { Call(e) => {
self.ecx.expr_call(e.span, e, let span = e.span;
vec!(self.ecx.expr_addr_of(e.span, res))) self.ecx.expr_call(span, e,
vec!(self.ecx.expr_addr_of(span, res)))
} }
MethodCall(e, m) => { MethodCall(e, m) => {
self.ecx.expr_method_call(e.span, e, m, let span = e.span;
vec!(self.ecx.expr_addr_of(e.span, res))) self.ecx.expr_method_call(span, e, m,
vec!(self.ecx.expr_addr_of(span, res)))
} }
}; };
let body = self.ecx.expr_block(self.ecx.block(self.fmtsp, lets, let body = self.ecx.expr_block(self.ecx.block(self.fmtsp, lets,
@ -655,13 +661,9 @@ impl<'a, 'b> Context<'a, 'b> {
self.ecx.expr_match(self.fmtsp, head, vec!(arm)) self.ecx.expr_match(self.fmtsp, head, vec!(arm))
} }
fn format_arg(&self, sp: Span, argno: Position, arg: Gc<ast::Expr>) fn format_arg(ecx: &ExtCtxt, sp: Span,
-> Gc<ast::Expr> { ty: &ArgumentType, arg: P<ast::Expr>)
let ty = match argno { -> P<ast::Expr> {
Exact(ref i) => self.arg_types.get(*i).get_ref(),
Named(ref s) => self.name_types.get(s)
};
let (krate, fmt_fn) = match *ty { let (krate, fmt_fn) = match *ty {
Known(ref tyname) => { Known(ref tyname) => {
match tyname.as_slice() { match tyname.as_slice() {
@ -681,36 +683,35 @@ impl<'a, 'b> Context<'a, 'b> {
"x" => ("std", "secret_lower_hex"), "x" => ("std", "secret_lower_hex"),
"X" => ("std", "secret_upper_hex"), "X" => ("std", "secret_upper_hex"),
_ => { _ => {
self.ecx ecx.span_err(sp,
.span_err(sp, format!("unknown format trait `{}`",
format!("unknown format trait `{}`", *tyname).as_slice());
*tyname).as_slice());
("std", "dummy") ("std", "dummy")
} }
} }
} }
String => { String => {
return self.ecx.expr_call_global(sp, vec!( return ecx.expr_call_global(sp, vec![
self.ecx.ident_of("std"), ecx.ident_of("std"),
self.ecx.ident_of("fmt"), ecx.ident_of("fmt"),
self.ecx.ident_of("argumentstr")), vec!(arg)) ecx.ident_of("argumentstr")], vec![arg])
} }
Unsigned => { Unsigned => {
return self.ecx.expr_call_global(sp, vec!( return ecx.expr_call_global(sp, vec![
self.ecx.ident_of("std"), ecx.ident_of("std"),
self.ecx.ident_of("fmt"), ecx.ident_of("fmt"),
self.ecx.ident_of("argumentuint")), vec!(arg)) ecx.ident_of("argumentuint")], vec![arg])
} }
}; };
let format_fn = self.ecx.path_global(sp, vec!( let format_fn = ecx.path_global(sp, vec![
self.ecx.ident_of(krate), ecx.ident_of(krate),
self.ecx.ident_of("fmt"), ecx.ident_of("fmt"),
self.ecx.ident_of(fmt_fn))); ecx.ident_of(fmt_fn)]);
self.ecx.expr_call_global(sp, vec!( ecx.expr_call_global(sp, vec![
self.ecx.ident_of("std"), ecx.ident_of("std"),
self.ecx.ident_of("fmt"), ecx.ident_of("fmt"),
self.ecx.ident_of("argument")), vec!(self.ecx.expr_path(format_fn), arg)) ecx.ident_of("argument")], vec![ecx.expr_path(format_fn), arg])
} }
} }
@ -744,12 +745,11 @@ pub fn expand_format_args_method<'cx>(ecx: &'cx mut ExtCtxt, sp: Span,
/// expression. /// expression.
pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
invocation: Invocation, invocation: Invocation,
efmt: Gc<ast::Expr>, efmt: P<ast::Expr>,
args: Vec<Gc<ast::Expr>>, args: Vec<P<ast::Expr>>,
name_ordering: Vec<String>, name_ordering: Vec<String>,
names: HashMap<String, Gc<ast::Expr>>) names: HashMap<String, P<ast::Expr>>)
-> Gc<ast::Expr> -> P<ast::Expr> {
{
let arg_types = Vec::from_fn(args.len(), |_| None); let arg_types = Vec::from_fn(args.len(), |_| None);
let mut cx = Context { let mut cx = Context {
ecx: ecx, ecx: ecx,
@ -796,7 +796,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
} }
match parser.errors.shift() { match parser.errors.shift() {
Some(error) => { Some(error) => {
cx.ecx.span_err(efmt.span, cx.ecx.span_err(cx.fmtsp,
format!("invalid format string: {}", format!("invalid format string: {}",
error).as_slice()); error).as_slice());
return DummyResult::raw_expr(sp); return DummyResult::raw_expr(sp);

View file

@ -15,8 +15,7 @@ use ext::base;
use ext::build::AstBuilder; use ext::build::AstBuilder;
use parse::token::*; use parse::token::*;
use parse::token; use parse::token;
use ptr::P;
use std::gc::Gc;
/** /**
* *
@ -36,14 +35,13 @@ pub mod rt {
use parse::token; use parse::token;
use parse; use parse;
use print::pprust; use print::pprust;
use ptr::P;
use ast::{TokenTree, Generics, Expr}; use ast::{TokenTree, Generics, Expr};
pub use parse::new_parser_from_tts; pub use parse::new_parser_from_tts;
pub use codemap::{BytePos, Span, dummy_spanned}; pub use codemap::{BytePos, Span, dummy_spanned};
use std::gc::Gc;
pub trait ToTokens { pub trait ToTokens {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> ; fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> ;
} }
@ -107,13 +105,13 @@ pub mod rt {
} }
macro_rules! impl_to_source( macro_rules! impl_to_source(
(Gc<$t:ty>, $pp:ident) => ( (P<$t:ty>, $pp:ident) => (
impl ToSource for Gc<$t> { impl ToSource for P<$t> {
fn to_source(&self) -> String { fn to_source(&self) -> String {
pprust::$pp(&**self) pprust::$pp(&**self)
} }
} }
impl ToSourceWithHygiene for Gc<$t> { impl ToSourceWithHygiene for P<$t> {
fn to_source_with_hygiene(&self) -> String { fn to_source_with_hygiene(&self) -> String {
pprust::with_hygiene::$pp(&**self) pprust::with_hygiene::$pp(&**self)
} }
@ -182,18 +180,18 @@ pub mod rt {
impl_to_source!(ast::Block, block_to_string) impl_to_source!(ast::Block, block_to_string)
impl_to_source!(ast::Arg, arg_to_string) impl_to_source!(ast::Arg, arg_to_string)
impl_to_source!(Generics, generics_to_string) impl_to_source!(Generics, generics_to_string)
impl_to_source!(Gc<ast::Item>, item_to_string) impl_to_source!(P<ast::Item>, item_to_string)
impl_to_source!(Gc<ast::Method>, method_to_string) impl_to_source!(P<ast::Method>, method_to_string)
impl_to_source!(Gc<ast::Stmt>, stmt_to_string) impl_to_source!(P<ast::Stmt>, stmt_to_string)
impl_to_source!(Gc<ast::Expr>, expr_to_string) impl_to_source!(P<ast::Expr>, expr_to_string)
impl_to_source!(Gc<ast::Pat>, pat_to_string) impl_to_source!(P<ast::Pat>, pat_to_string)
impl_to_source!(ast::Arm, arm_to_string) impl_to_source!(ast::Arm, arm_to_string)
impl_to_source_slice!(ast::Ty, ", ") impl_to_source_slice!(ast::Ty, ", ")
impl_to_source_slice!(Gc<ast::Item>, "\n\n") impl_to_source_slice!(P<ast::Item>, "\n\n")
impl ToSource for ast::Attribute_ { impl ToSource for ast::Attribute_ {
fn to_source(&self) -> String { fn to_source(&self) -> String {
pprust::attribute_to_string(&dummy_spanned(*self)) pprust::attribute_to_string(&dummy_spanned(self.clone()))
} }
} }
impl ToSourceWithHygiene for ast::Attribute_ { impl ToSourceWithHygiene for ast::Attribute_ {
@ -315,16 +313,16 @@ pub mod rt {
) )
impl_to_tokens!(ast::Ident) impl_to_tokens!(ast::Ident)
impl_to_tokens!(Gc<ast::Item>) impl_to_tokens!(P<ast::Item>)
impl_to_tokens!(Gc<ast::Pat>) impl_to_tokens!(P<ast::Pat>)
impl_to_tokens!(ast::Arm) impl_to_tokens!(ast::Arm)
impl_to_tokens!(Gc<ast::Method>) impl_to_tokens!(P<ast::Method>)
impl_to_tokens_lifetime!(&'a [Gc<ast::Item>]) impl_to_tokens_lifetime!(&'a [P<ast::Item>])
impl_to_tokens!(ast::Ty) impl_to_tokens!(ast::Ty)
impl_to_tokens_lifetime!(&'a [ast::Ty]) impl_to_tokens_lifetime!(&'a [ast::Ty])
impl_to_tokens!(Generics) impl_to_tokens!(Generics)
impl_to_tokens!(Gc<ast::Stmt>) impl_to_tokens!(P<ast::Stmt>)
impl_to_tokens!(Gc<ast::Expr>) impl_to_tokens!(P<ast::Expr>)
impl_to_tokens!(ast::Block) impl_to_tokens!(ast::Block)
impl_to_tokens!(ast::Arg) impl_to_tokens!(ast::Arg)
impl_to_tokens!(ast::Attribute_) impl_to_tokens!(ast::Attribute_)
@ -344,9 +342,9 @@ pub mod rt {
impl_to_tokens!(u64) impl_to_tokens!(u64)
pub trait ExtParseUtils { pub trait ExtParseUtils {
fn parse_item(&self, s: String) -> Gc<ast::Item>; fn parse_item(&self, s: String) -> P<ast::Item>;
fn parse_expr(&self, s: String) -> Gc<ast::Expr>; fn parse_expr(&self, s: String) -> P<ast::Expr>;
fn parse_stmt(&self, s: String) -> Gc<ast::Stmt>; fn parse_stmt(&self, s: String) -> P<ast::Stmt>;
fn parse_tts(&self, s: String) -> Vec<ast::TokenTree>; fn parse_tts(&self, s: String) -> Vec<ast::TokenTree>;
} }
@ -358,7 +356,7 @@ pub mod rt {
impl<'a> ExtParseUtils for ExtCtxt<'a> { impl<'a> ExtParseUtils for ExtCtxt<'a> {
fn parse_item(&self, s: String) -> Gc<ast::Item> { fn parse_item(&self, s: String) -> P<ast::Item> {
let res = parse::parse_item_from_source_str( let res = parse::parse_item_from_source_str(
"<quote expansion>".to_string(), "<quote expansion>".to_string(),
s, s,
@ -373,7 +371,7 @@ pub mod rt {
} }
} }
fn parse_stmt(&self, s: String) -> Gc<ast::Stmt> { fn parse_stmt(&self, s: String) -> P<ast::Stmt> {
parse::parse_stmt_from_source_str("<quote expansion>".to_string(), parse::parse_stmt_from_source_str("<quote expansion>".to_string(),
s, s,
self.cfg(), self.cfg(),
@ -381,7 +379,7 @@ pub mod rt {
self.parse_sess()) self.parse_sess())
} }
fn parse_expr(&self, s: String) -> Gc<ast::Expr> { fn parse_expr(&self, s: String) -> P<ast::Expr> {
parse::parse_expr_from_source_str("<quote expansion>".to_string(), parse::parse_expr_from_source_str("<quote expansion>".to_string(),
s, s,
self.cfg(), self.cfg(),
@ -491,7 +489,7 @@ fn id_ext(str: &str) -> ast::Ident {
} }
// Lift an ident to the expr that evaluates to that ident. // Lift an ident to the expr that evaluates to that ident.
fn mk_ident(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> Gc<ast::Expr> { fn mk_ident(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> P<ast::Expr> {
let e_str = cx.expr_str(sp, token::get_ident(ident)); let e_str = cx.expr_str(sp, token::get_ident(ident));
cx.expr_method_call(sp, cx.expr_method_call(sp,
cx.expr_ident(sp, id_ext("ext_cx")), cx.expr_ident(sp, id_ext("ext_cx")),
@ -500,7 +498,7 @@ fn mk_ident(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> Gc<ast::Expr> {
} }
// Lift a name to the expr that evaluates to that name // Lift a name to the expr that evaluates to that name
fn mk_name(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> Gc<ast::Expr> { fn mk_name(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> P<ast::Expr> {
let e_str = cx.expr_str(sp, token::get_ident(ident)); let e_str = cx.expr_str(sp, token::get_ident(ident));
cx.expr_method_call(sp, cx.expr_method_call(sp,
cx.expr_ident(sp, id_ext("ext_cx")), cx.expr_ident(sp, id_ext("ext_cx")),
@ -508,17 +506,17 @@ fn mk_name(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> Gc<ast::Expr> {
vec!(e_str)) vec!(e_str))
} }
fn mk_ast_path(cx: &ExtCtxt, sp: Span, name: &str) -> Gc<ast::Expr> { fn mk_ast_path(cx: &ExtCtxt, sp: Span, name: &str) -> P<ast::Expr> {
let idents = vec!(id_ext("syntax"), id_ext("ast"), id_ext(name)); let idents = vec!(id_ext("syntax"), id_ext("ast"), id_ext(name));
cx.expr_path(cx.path_global(sp, idents)) cx.expr_path(cx.path_global(sp, idents))
} }
fn mk_token_path(cx: &ExtCtxt, sp: Span, name: &str) -> Gc<ast::Expr> { fn mk_token_path(cx: &ExtCtxt, sp: Span, name: &str) -> P<ast::Expr> {
let idents = vec!(id_ext("syntax"), id_ext("parse"), id_ext("token"), id_ext(name)); let idents = vec!(id_ext("syntax"), id_ext("parse"), id_ext("token"), id_ext(name));
cx.expr_path(cx.path_global(sp, idents)) cx.expr_path(cx.path_global(sp, idents))
} }
fn mk_binop(cx: &ExtCtxt, sp: Span, bop: token::BinOp) -> Gc<ast::Expr> { fn mk_binop(cx: &ExtCtxt, sp: Span, bop: token::BinOp) -> P<ast::Expr> {
let name = match bop { let name = match bop {
PLUS => "PLUS", PLUS => "PLUS",
MINUS => "MINUS", MINUS => "MINUS",
@ -534,7 +532,7 @@ fn mk_binop(cx: &ExtCtxt, sp: Span, bop: token::BinOp) -> Gc<ast::Expr> {
mk_token_path(cx, sp, name) mk_token_path(cx, sp, name)
} }
fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> Gc<ast::Expr> { fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> {
match *tok { match *tok {
BINOP(binop) => { BINOP(binop) => {
@ -640,7 +638,7 @@ fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> Gc<ast::Expr> {
} }
fn mk_tt(cx: &ExtCtxt, sp: Span, tt: &ast::TokenTree) -> Vec<Gc<ast::Stmt>> { fn mk_tt(cx: &ExtCtxt, sp: Span, tt: &ast::TokenTree) -> Vec<P<ast::Stmt>> {
match *tt { match *tt {
ast::TTTok(sp, ref tok) => { ast::TTTok(sp, ref tok) => {
let e_sp = cx.expr_ident(sp, id_ext("_sp")); let e_sp = cx.expr_ident(sp, id_ext("_sp"));
@ -680,7 +678,7 @@ fn mk_tt(cx: &ExtCtxt, sp: Span, tt: &ast::TokenTree) -> Vec<Gc<ast::Stmt>> {
} }
fn mk_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree]) fn mk_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> Vec<Gc<ast::Stmt>> { -> Vec<P<ast::Stmt>> {
let mut ss = Vec::new(); let mut ss = Vec::new();
for tt in tts.iter() { for tt in tts.iter() {
ss.push_all_move(mk_tt(cx, sp, tt)); ss.push_all_move(mk_tt(cx, sp, tt));
@ -689,7 +687,7 @@ fn mk_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
} }
fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree]) fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> (Gc<ast::Expr>, Gc<ast::Expr>) { -> (P<ast::Expr>, P<ast::Expr>) {
// NB: It appears that the main parser loses its mind if we consider // NB: It appears that the main parser loses its mind if we consider
// $foo as a TTNonterminal during the main parse, so we have to re-parse // $foo as a TTNonterminal during the main parse, so we have to re-parse
// under quote_depth > 0. This is silly and should go away; the _guess_ is // under quote_depth > 0. This is silly and should go away; the _guess_ is
@ -757,8 +755,8 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
fn expand_wrapper(cx: &ExtCtxt, fn expand_wrapper(cx: &ExtCtxt,
sp: Span, sp: Span,
cx_expr: Gc<ast::Expr>, cx_expr: P<ast::Expr>,
expr: Gc<ast::Expr>) -> Gc<ast::Expr> { expr: P<ast::Expr>) -> P<ast::Expr> {
let uses = [ let uses = [
&["syntax", "ext", "quote", "rt"], &["syntax", "ext", "quote", "rt"],
].iter().map(|path| { ].iter().map(|path| {
@ -776,8 +774,8 @@ fn expand_wrapper(cx: &ExtCtxt,
fn expand_parse_call(cx: &ExtCtxt, fn expand_parse_call(cx: &ExtCtxt,
sp: Span, sp: Span,
parse_method: &str, parse_method: &str,
arg_exprs: Vec<Gc<ast::Expr>>, arg_exprs: Vec<P<ast::Expr>> ,
tts: &[ast::TokenTree]) -> Gc<ast::Expr> { tts: &[ast::TokenTree]) -> P<ast::Expr> {
let (cx_expr, tts_expr) = expand_tts(cx, sp, tts); let (cx_expr, tts_expr) = expand_tts(cx, sp, tts);
let cfg_call = || cx.expr_method_call( let cfg_call = || cx.expr_method_call(

View file

@ -87,9 +87,9 @@ use parse::attr::ParserAttr;
use parse::parser::{LifetimeAndTypesWithoutColons, Parser}; use parse::parser::{LifetimeAndTypesWithoutColons, Parser};
use parse::token::{Token, EOF, Nonterminal}; use parse::token::{Token, EOF, Nonterminal};
use parse::token; use parse::token;
use ptr::P;
use std::rc::Rc; use std::rc::Rc;
use std::gc::GC;
use std::collections::HashMap; use std::collections::HashMap;
/* to avoid costly uniqueness checks, we require that `MatchSeq` always has a /* to avoid costly uniqueness checks, we require that `MatchSeq` always has a
@ -451,7 +451,7 @@ pub fn parse_nt(p: &mut Parser, name: &str) -> Nonterminal {
"meta" => token::NtMeta(p.parse_meta_item()), "meta" => token::NtMeta(p.parse_meta_item()),
"tt" => { "tt" => {
p.quote_depth += 1u; //but in theory, non-quoted tts might be useful p.quote_depth += 1u; //but in theory, non-quoted tts might be useful
let res = token::NtTT(box(GC) p.parse_token_tree()); let res = token::NtTT(P(p.parse_token_tree()));
p.quote_depth -= 1u; p.quote_depth -= 1u;
res res
} }

View file

@ -8,8 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use ast::{Ident, Matcher_, Matcher, MatchTok, MatchNonterminal, MatchSeq}; use ast::{Ident, Matcher_, Matcher, MatchTok, MatchNonterminal, MatchSeq, TTDelim};
use ast::{TTDelim};
use ast; use ast;
use codemap::{Span, Spanned, DUMMY_SP}; use codemap::{Span, Spanned, DUMMY_SP};
use ext::base::{ExtCtxt, MacResult, MacroDef}; use ext::base::{ExtCtxt, MacResult, MacroDef};
@ -24,11 +23,12 @@ use parse::token::{special_idents, gensym_ident};
use parse::token::{FAT_ARROW, SEMI, NtMatchers, NtTT, EOF}; use parse::token::{FAT_ARROW, SEMI, NtMatchers, NtTT, EOF};
use parse::token; use parse::token;
use print; use print;
use ptr::P;
use util::small_vector::SmallVector; use util::small_vector::SmallVector;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use std::gc::Gc;
struct ParserAnyMacro<'a> { struct ParserAnyMacro<'a> {
parser: RefCell<Parser<'a>>, parser: RefCell<Parser<'a>>,
@ -58,17 +58,17 @@ impl<'a> ParserAnyMacro<'a> {
} }
impl<'a> MacResult for ParserAnyMacro<'a> { impl<'a> MacResult for ParserAnyMacro<'a> {
fn make_expr(&self) -> Option<Gc<ast::Expr>> { fn make_expr(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Expr>> {
let ret = self.parser.borrow_mut().parse_expr(); let ret = self.parser.borrow_mut().parse_expr();
self.ensure_complete_parse(true); self.ensure_complete_parse(true);
Some(ret) Some(ret)
} }
fn make_pat(&self) -> Option<Gc<ast::Pat>> { fn make_pat(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Pat>> {
let ret = self.parser.borrow_mut().parse_pat(); let ret = self.parser.borrow_mut().parse_pat();
self.ensure_complete_parse(false); self.ensure_complete_parse(false);
Some(ret) Some(ret)
} }
fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> { fn make_items(self: Box<ParserAnyMacro<'a>>) -> Option<SmallVector<P<ast::Item>>> {
let mut ret = SmallVector::zero(); let mut ret = SmallVector::zero();
loop { loop {
let mut parser = self.parser.borrow_mut(); let mut parser = self.parser.borrow_mut();
@ -84,7 +84,7 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
Some(ret) Some(ret)
} }
fn make_methods(&self) -> Option<SmallVector<Gc<ast::Method>>> { fn make_methods(self: Box<ParserAnyMacro<'a>>) -> Option<SmallVector<P<ast::Method>>> {
let mut ret = SmallVector::zero(); let mut ret = SmallVector::zero();
loop { loop {
let mut parser = self.parser.borrow_mut(); let mut parser = self.parser.borrow_mut();
@ -97,7 +97,7 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
Some(ret) Some(ret)
} }
fn make_stmt(&self) -> Option<Gc<ast::Stmt>> { fn make_stmt(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Stmt>> {
let attrs = self.parser.borrow_mut().parse_outer_attributes(); let attrs = self.parser.borrow_mut().parse_outer_attributes();
let ret = self.parser.borrow_mut().parse_stmt(attrs); let ret = self.parser.borrow_mut().parse_stmt(attrs);
self.ensure_complete_parse(true); self.ensure_complete_parse(true);
@ -127,11 +127,11 @@ impl TTMacroExpander for MacroRulesMacroExpander {
} }
struct MacroRulesDefiner { struct MacroRulesDefiner {
def: RefCell<Option<MacroDef>> def: Option<MacroDef>
} }
impl MacResult for MacroRulesDefiner { impl MacResult for MacroRulesDefiner {
fn make_def(&self) -> Option<MacroDef> { fn make_def(&mut self) -> Option<MacroDef> {
Some(self.def.borrow_mut().take().expect("MacroRulesDefiner expanded twice")) Some(self.def.take().expect("empty MacroRulesDefiner"))
} }
} }
@ -170,8 +170,8 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
Success(named_matches) => { Success(named_matches) => {
let rhs = match *rhses[i] { let rhs = match *rhses[i] {
// okay, what's your transcriber? // okay, what's your transcriber?
MatchedNonterminal(NtTT(tt)) => { MatchedNonterminal(NtTT(ref tt)) => {
match *tt { match **tt {
// cut off delimiters; don't parse 'em // cut off delimiters; don't parse 'em
TTDelim(ref tts) => { TTDelim(ref tts) => {
(*tts).slice(1u,(*tts).len()-1u) (*tts).slice(1u,(*tts).len()-1u)
@ -269,9 +269,9 @@ pub fn add_new_extension<'cx>(cx: &'cx mut ExtCtxt,
}; };
box MacroRulesDefiner { box MacroRulesDefiner {
def: RefCell::new(Some(MacroDef { def: Some(MacroDef {
name: token::get_ident(name).to_string(), name: token::get_ident(name).to_string(),
ext: NormalTT(exp, Some(sp)) ext: NormalTT(exp, Some(sp))
})) })
} as Box<MacResult+'cx> } as Box<MacResult+'cx>
} }

View file

@ -11,7 +11,7 @@
use std::fmt; use std::fmt;
use std::default::Default; use std::default::Default;
use std::hash; use std::hash;
use std::{mem, raw, ptr, slice}; use std::{mem, raw, ptr, slice, vec};
use serialize::{Encodable, Decodable, Encoder, Decoder}; use serialize::{Encodable, Decodable, Encoder, Decoder};
/// A non-growable owned slice. This would preferably become `~[T]` /// A non-growable owned slice. This would preferably become `~[T]`
@ -105,6 +105,10 @@ impl<T> OwnedSlice<T> {
self.as_slice().iter() self.as_slice().iter()
} }
pub fn move_iter(self) -> vec::MoveItems<T> {
self.into_vec().move_iter()
}
pub fn map<U>(&self, f: |&T| -> U) -> OwnedSlice<U> { pub fn map<U>(&self, f: |&T| -> U) -> OwnedSlice<U> {
self.iter().map(f).collect() self.iter().map(f).collect()
} }

View file

@ -15,8 +15,7 @@ use parse::common::*; //resolve bug?
use parse::token; use parse::token;
use parse::parser::Parser; use parse::parser::Parser;
use parse::token::INTERPOLATED; use parse::token::INTERPOLATED;
use ptr::P;
use std::gc::{Gc, GC};
/// A parser that can parse attributes. /// A parser that can parse attributes.
pub trait ParserAttr { pub trait ParserAttr {
@ -24,9 +23,9 @@ pub trait ParserAttr {
fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute; fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute;
fn parse_inner_attrs_and_next(&mut self) fn parse_inner_attrs_and_next(&mut self)
-> (Vec<ast::Attribute>, Vec<ast::Attribute>); -> (Vec<ast::Attribute>, Vec<ast::Attribute>);
fn parse_meta_item(&mut self) -> Gc<ast::MetaItem>; fn parse_meta_item(&mut self) -> P<ast::MetaItem>;
fn parse_meta_seq(&mut self) -> Vec<Gc<ast::MetaItem>>; fn parse_meta_seq(&mut self) -> Vec<P<ast::MetaItem>>;
fn parse_optional_meta(&mut self) -> Vec<Gc<ast::MetaItem>>; fn parse_optional_meta(&mut self) -> Vec<P<ast::MetaItem>>;
} }
impl<'a> ParserAttr for Parser<'a> { impl<'a> ParserAttr for Parser<'a> {
@ -160,13 +159,20 @@ impl<'a> ParserAttr for Parser<'a> {
/// matches meta_item = IDENT /// matches meta_item = IDENT
/// | IDENT = lit /// | IDENT = lit
/// | IDENT meta_seq /// | IDENT meta_seq
fn parse_meta_item(&mut self) -> Gc<ast::MetaItem> { fn parse_meta_item(&mut self) -> P<ast::MetaItem> {
match self.token { let nt_meta = match self.token {
token::INTERPOLATED(token::NtMeta(e)) => { token::INTERPOLATED(token::NtMeta(ref e)) => {
self.bump(); Some(e.clone())
return e
} }
_ => {} _ => None
};
match nt_meta {
Some(meta) => {
self.bump();
return meta;
}
None => {}
} }
let lo = self.span.lo; let lo = self.span.lo;
@ -187,29 +193,29 @@ impl<'a> ParserAttr for Parser<'a> {
} }
} }
let hi = self.span.hi; let hi = self.span.hi;
box(GC) spanned(lo, hi, ast::MetaNameValue(name, lit)) P(spanned(lo, hi, ast::MetaNameValue(name, lit)))
} }
token::LPAREN => { token::LPAREN => {
let inner_items = self.parse_meta_seq(); let inner_items = self.parse_meta_seq();
let hi = self.span.hi; let hi = self.span.hi;
box(GC) spanned(lo, hi, ast::MetaList(name, inner_items)) P(spanned(lo, hi, ast::MetaList(name, inner_items)))
} }
_ => { _ => {
let hi = self.last_span.hi; let hi = self.last_span.hi;
box(GC) spanned(lo, hi, ast::MetaWord(name)) P(spanned(lo, hi, ast::MetaWord(name)))
} }
} }
} }
/// matches meta_seq = ( COMMASEP(meta_item) ) /// matches meta_seq = ( COMMASEP(meta_item) )
fn parse_meta_seq(&mut self) -> Vec<Gc<ast::MetaItem>> { fn parse_meta_seq(&mut self) -> Vec<P<ast::MetaItem>> {
self.parse_seq(&token::LPAREN, self.parse_seq(&token::LPAREN,
&token::RPAREN, &token::RPAREN,
seq_sep_trailing_disallowed(token::COMMA), seq_sep_trailing_disallowed(token::COMMA),
|p| p.parse_meta_item()).node |p| p.parse_meta_item()).node
} }
fn parse_optional_meta(&mut self) -> Vec<Gc<ast::MetaItem>> { fn parse_optional_meta(&mut self) -> Vec<P<ast::MetaItem>> {
match self.token { match self.token {
token::LPAREN => self.parse_meta_seq(), token::LPAREN => self.parse_meta_seq(),
_ => Vec::new() _ => Vec::new()

View file

@ -13,7 +13,6 @@
// Predicates on exprs and stmts that the pretty-printer and parser use // Predicates on exprs and stmts that the pretty-printer and parser use
use ast; use ast;
use std::gc::Gc;
/// Does this expression require a semicolon to be treated /// Does this expression require a semicolon to be treated
/// as a statement? The negation of this: 'can this expression /// as a statement? The negation of this: 'can this expression
@ -22,7 +21,7 @@ use std::gc::Gc;
/// if true {...} else {...} /// if true {...} else {...}
/// |x| 5 /// |x| 5
/// isn't parsed as (if true {...} else {...} | x) | 5 /// isn't parsed as (if true {...} else {...} | x) | 5
pub fn expr_requires_semi_to_be_stmt(e: Gc<ast::Expr>) -> bool { pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool {
match e.node { match e.node {
ast::ExprIf(..) ast::ExprIf(..)
| ast::ExprMatch(..) | ast::ExprMatch(..)
@ -34,25 +33,25 @@ pub fn expr_requires_semi_to_be_stmt(e: Gc<ast::Expr>) -> bool {
} }
} }
pub fn expr_is_simple_block(e: Gc<ast::Expr>) -> bool { pub fn expr_is_simple_block(e: &ast::Expr) -> bool {
match e.node { match e.node {
ast::ExprBlock(block) => block.rules == ast::DefaultBlock, ast::ExprBlock(ref block) => block.rules == ast::DefaultBlock,
_ => false _ => false
} }
} }
/// this statement requires a semicolon after it. /// this statement requires a semicolon after it.
/// note that in one case (stmt_semi), we've already /// note that in one case (stmt_semi), we've already
/// seen the semicolon, and thus don't need another. /// seen the semicolon, and thus don't need another.
pub fn stmt_ends_with_semi(stmt: &ast::Stmt) -> bool { pub fn stmt_ends_with_semi(stmt: &ast::Stmt_) -> bool {
return match stmt.node { match *stmt {
ast::StmtDecl(d, _) => { ast::StmtDecl(ref d, _) => {
match d.node { match d.node {
ast::DeclLocal(_) => true, ast::DeclLocal(_) => true,
ast::DeclItem(_) => false ast::DeclItem(_) => false
} }
} }
ast::StmtExpr(e, _) => { expr_requires_semi_to_be_stmt(e) } ast::StmtExpr(ref e, _) => { expr_requires_semi_to_be_stmt(&**e) }
ast::StmtSemi(..) => { false } ast::StmtSemi(..) => { false }
ast::StmtMac(..) => { false } ast::StmtMac(..) => { false }
} }

View file

@ -15,9 +15,9 @@ use codemap::{Span, CodeMap, FileMap};
use diagnostic::{SpanHandler, mk_span_handler, default_handler, Auto}; use diagnostic::{SpanHandler, mk_span_handler, default_handler, Auto};
use parse::attr::ParserAttr; use parse::attr::ParserAttr;
use parse::parser::Parser; use parse::parser::Parser;
use ptr::P;
use std::cell::RefCell; use std::cell::RefCell;
use std::gc::Gc;
use std::io::File; use std::io::File;
use std::rc::Rc; use std::rc::Rc;
use std::str; use std::str;
@ -106,7 +106,7 @@ pub fn parse_expr_from_source_str(name: String,
source: String, source: String,
cfg: ast::CrateConfig, cfg: ast::CrateConfig,
sess: &ParseSess) sess: &ParseSess)
-> Gc<ast::Expr> { -> P<ast::Expr> {
let mut p = new_parser_from_source_str(sess, cfg, name, source); let mut p = new_parser_from_source_str(sess, cfg, name, source);
maybe_aborted(p.parse_expr(), p) maybe_aborted(p.parse_expr(), p)
} }
@ -115,7 +115,7 @@ pub fn parse_item_from_source_str(name: String,
source: String, source: String,
cfg: ast::CrateConfig, cfg: ast::CrateConfig,
sess: &ParseSess) sess: &ParseSess)
-> Option<Gc<ast::Item>> { -> Option<P<ast::Item>> {
let mut p = new_parser_from_source_str(sess, cfg, name, source); let mut p = new_parser_from_source_str(sess, cfg, name, source);
maybe_aborted(p.parse_item_with_outer_attributes(),p) maybe_aborted(p.parse_item_with_outer_attributes(),p)
} }
@ -124,7 +124,7 @@ pub fn parse_meta_from_source_str(name: String,
source: String, source: String,
cfg: ast::CrateConfig, cfg: ast::CrateConfig,
sess: &ParseSess) sess: &ParseSess)
-> Gc<ast::MetaItem> { -> P<ast::MetaItem> {
let mut p = new_parser_from_source_str(sess, cfg, name, source); let mut p = new_parser_from_source_str(sess, cfg, name, source);
maybe_aborted(p.parse_meta_item(),p) maybe_aborted(p.parse_meta_item(),p)
} }
@ -134,7 +134,7 @@ pub fn parse_stmt_from_source_str(name: String,
cfg: ast::CrateConfig, cfg: ast::CrateConfig,
attrs: Vec<ast::Attribute> , attrs: Vec<ast::Attribute> ,
sess: &ParseSess) sess: &ParseSess)
-> Gc<ast::Stmt> { -> P<ast::Stmt> {
let mut p = new_parser_from_source_str( let mut p = new_parser_from_source_str(
sess, sess,
cfg, cfg,
@ -722,7 +722,7 @@ mod test {
#[test] fn path_exprs_1() { #[test] fn path_exprs_1() {
assert!(string_to_expr("a".to_string()) == assert!(string_to_expr("a".to_string()) ==
box(GC) ast::Expr{ P(ast::Expr{
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprPath(ast::Path { node: ast::ExprPath(ast::Path {
span: sp(0, 1), span: sp(0, 1),
@ -736,12 +736,12 @@ mod test {
), ),
}), }),
span: sp(0, 1) span: sp(0, 1)
}) }))
} }
#[test] fn path_exprs_2 () { #[test] fn path_exprs_2 () {
assert!(string_to_expr("::a::b".to_string()) == assert!(string_to_expr("::a::b".to_string()) ==
box(GC) ast::Expr { P(ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprPath(ast::Path { node: ast::ExprPath(ast::Path {
span: sp(0, 6), span: sp(0, 6),
@ -760,7 +760,7 @@ mod test {
) )
}), }),
span: sp(0, 6) span: sp(0, 6)
}) }))
} }
#[should_fail] #[should_fail]
@ -953,9 +953,9 @@ mod test {
#[test] fn ret_expr() { #[test] fn ret_expr() {
assert!(string_to_expr("return d".to_string()) == assert!(string_to_expr("return d".to_string()) ==
box(GC) ast::Expr{ P(ast::Expr{
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node:ast::ExprRet(Some(box(GC) ast::Expr{ node:ast::ExprRet(Some(P(ast::Expr{
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node:ast::ExprPath(ast::Path{ node:ast::ExprPath(ast::Path{
span: sp(7, 8), span: sp(7, 8),
@ -969,15 +969,15 @@ mod test {
), ),
}), }),
span:sp(7,8) span:sp(7,8)
})), }))),
span:sp(0,8) span:sp(0,8)
}) }))
} }
#[test] fn parse_stmt_1 () { #[test] fn parse_stmt_1 () {
assert!(string_to_stmt("b;".to_string()) == assert!(string_to_stmt("b;".to_string()) ==
box(GC) Spanned{ P(Spanned{
node: ast::StmtExpr(box(GC) ast::Expr { node: ast::StmtExpr(P(ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprPath(ast::Path { node: ast::ExprPath(ast::Path {
span:sp(0,1), span:sp(0,1),
@ -990,9 +990,9 @@ mod test {
} }
), ),
}), }),
span: sp(0,1)}, span: sp(0,1)}),
ast::DUMMY_NODE_ID), ast::DUMMY_NODE_ID),
span: sp(0,1)}) span: sp(0,1)}))
} }
@ -1004,14 +1004,14 @@ mod test {
let sess = new_parse_sess(); let sess = new_parse_sess();
let mut parser = string_to_parser(&sess, "b".to_string()); let mut parser = string_to_parser(&sess, "b".to_string());
assert!(parser.parse_pat() assert!(parser.parse_pat()
== box(GC) ast::Pat{ == P(ast::Pat{
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::PatIdent(ast::BindByValue(ast::MutImmutable), node: ast::PatIdent(ast::BindByValue(ast::MutImmutable),
Spanned{ span:sp(0, 1), Spanned{ span:sp(0, 1),
node: str_to_ident("b") node: str_to_ident("b")
}, },
None), None),
span: sp(0,1)}); span: sp(0,1)}));
parser_done(parser); parser_done(parser);
} }
@ -1020,7 +1020,7 @@ mod test {
// this test depends on the intern order of "fn" and "int" // this test depends on the intern order of "fn" and "int"
assert!(string_to_item("fn a (b : int) { b; }".to_string()) == assert!(string_to_item("fn a (b : int) { b; }".to_string()) ==
Some( Some(
box(GC) ast::Item{ident:str_to_ident("a"), P(ast::Item{ident:str_to_ident("a"),
attrs:Vec::new(), attrs:Vec::new(),
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ItemFn(ast::P(ast::FnDecl { node: ast::ItemFn(ast::P(ast::FnDecl {
@ -1040,7 +1040,7 @@ mod test {
}, None, ast::DUMMY_NODE_ID), }, None, ast::DUMMY_NODE_ID),
span:sp(10,13) span:sp(10,13)
}), }),
pat: box(GC) ast::Pat { pat: P(ast::Pat {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::PatIdent( node: ast::PatIdent(
ast::BindByValue(ast::MutImmutable), ast::BindByValue(ast::MutImmutable),
@ -1050,7 +1050,7 @@ mod test {
None None
), ),
span: sp(6,7) span: sp(6,7)
}, }),
id: ast::DUMMY_NODE_ID id: ast::DUMMY_NODE_ID
}), }),
output: ast::P(ast::Ty{id: ast::DUMMY_NODE_ID, output: ast::P(ast::Ty{id: ast::DUMMY_NODE_ID,
@ -1071,8 +1071,8 @@ mod test {
}, },
ast::P(ast::Block { ast::P(ast::Block {
view_items: Vec::new(), view_items: Vec::new(),
stmts: vec!(box(GC) Spanned{ stmts: vec!(P(Spanned{
node: ast::StmtSemi(box(GC) ast::Expr{ node: ast::StmtSemi(P(ast::Expr{
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
node: ast::ExprPath( node: ast::ExprPath(
ast::Path{ ast::Path{
@ -1090,28 +1090,28 @@ mod test {
} }
), ),
}), }),
span: sp(17,18)}, span: sp(17,18)}),
ast::DUMMY_NODE_ID), ast::DUMMY_NODE_ID),
span: sp(17,19)}), span: sp(17,19)})),
expr: None, expr: None,
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
rules: ast::DefaultBlock, // no idea rules: ast::DefaultBlock, // no idea
span: sp(15,21), span: sp(15,21),
})), })),
vis: ast::Inherited, vis: ast::Inherited,
span: sp(0,21)})); span: sp(0,21)})));
} }
#[test] fn parse_exprs () { #[test] fn parse_exprs () {
// just make sure that they parse.... // just make sure that they parse....
string_to_expr("3 + 4".to_string()); string_to_expr("3 + 4".to_string());
string_to_expr("a::z.froob(b,box(GC)(987+3))".to_string()); string_to_expr("a::z.froob(b,&(987+3))".to_string());
} }
#[test] fn attrs_fix_bug () { #[test] fn attrs_fix_bug () {
string_to_item("pub fn mk_file_writer(path: &Path, flags: &[FileFlag]) string_to_item("pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
-> Result<Gc<Writer>, String> { -> Result<Box<Writer>, String> {
#[cfg(windows)] #[cfg(windows)]
fn wb() -> c_int { fn wb() -> c_int {
(O_WRONLY | libc::consts::os::extra::O_BINARY) as c_int (O_WRONLY | libc::consts::os::extra::O_BINARY) as c_int

View file

@ -21,8 +21,7 @@ use ast::{Expr, ExprLit, LitNil};
use codemap::{Span, respan}; use codemap::{Span, respan};
use parse::parser; use parse::parser;
use parse::token; use parse::token;
use ptr::P;
use std::gc::{Gc, GC};
/// The specific types of unsupported syntax /// The specific types of unsupported syntax
#[deriving(PartialEq, Eq, Hash)] #[deriving(PartialEq, Eq, Hash)]
@ -44,7 +43,7 @@ pub trait ParserObsoleteMethods {
fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax); fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax);
/// Reports an obsolete syntax non-fatal error, and returns /// Reports an obsolete syntax non-fatal error, and returns
/// a placeholder expression /// a placeholder expression
fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> Gc<Expr>; fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> P<Expr>;
fn report(&mut self, fn report(&mut self,
sp: Span, sp: Span,
kind: ObsoleteSyntax, kind: ObsoleteSyntax,
@ -105,9 +104,9 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> {
/// Reports an obsolete syntax non-fatal error, and returns /// Reports an obsolete syntax non-fatal error, and returns
/// a placeholder expression /// a placeholder expression
fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> Gc<Expr> { fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> P<Expr> {
self.obsolete(sp, kind); self.obsolete(sp, kind);
self.mk_expr(sp.lo, sp.hi, ExprLit(box(GC) respan(sp, LitNil))) self.mk_expr(sp.lo, sp.hi, ExprLit(P(respan(sp, LitNil))))
} }
fn report(&mut self, fn report(&mut self,

File diff suppressed because it is too large Load diff

View file

@ -9,15 +9,15 @@
// except according to those terms. // except according to those terms.
use ast; use ast;
use ast::{P, Ident, Name, Mrk}; use ast::{Ident, Name, Mrk};
use ext::mtwt; use ext::mtwt;
use parse::token; use parse::token;
use ptr::P;
use util::interner::{RcStr, StrInterner}; use util::interner::{RcStr, StrInterner};
use util::interner; use util::interner;
use serialize::{Decodable, Decoder, Encodable, Encoder}; use serialize::{Decodable, Decoder, Encodable, Encoder};
use std::fmt; use std::fmt;
use std::gc::Gc;
use std::mem; use std::mem;
use std::path::BytesContainer; use std::path::BytesContainer;
use std::rc::Rc; use std::rc::Rc;
@ -115,19 +115,19 @@ pub enum Token {
#[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash)] #[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash)]
/// For interpolation during macro expansion. /// For interpolation during macro expansion.
pub enum Nonterminal { pub enum Nonterminal {
NtItem(Gc<ast::Item>), NtItem( P<ast::Item>),
NtBlock(P<ast::Block>), NtBlock(P<ast::Block>),
NtStmt(Gc<ast::Stmt>), NtStmt( P<ast::Stmt>),
NtPat( Gc<ast::Pat>), NtPat( P<ast::Pat>),
NtExpr(Gc<ast::Expr>), NtExpr( P<ast::Expr>),
NtTy( P<ast::Ty>), NtTy( P<ast::Ty>),
/// See IDENT, above, for meaning of bool in NtIdent: /// See IDENT, above, for meaning of bool in NtIdent:
NtIdent(Box<Ident>, bool), NtIdent(Box<Ident>, bool),
/// Stuff inside brackets for attributes /// Stuff inside brackets for attributes
NtMeta(Gc<ast::MetaItem>), NtMeta( P<ast::MetaItem>),
NtPath(Box<ast::Path>), NtPath(Box<ast::Path>),
NtTT( Gc<ast::TokenTree>), // needs Gc'd to break a circularity NtTT( P<ast::TokenTree>), // needs P'ed to break a circularity
NtMatchers(Vec<ast::Matcher> ) NtMatchers(Vec<ast::Matcher>)
} }
impl fmt::Show for Nonterminal { impl fmt::Show for Nonterminal {

View file

@ -10,7 +10,7 @@
use abi; use abi;
use ast::{FnMutUnboxedClosureKind, FnOnceUnboxedClosureKind}; use ast::{FnMutUnboxedClosureKind, FnOnceUnboxedClosureKind};
use ast::{FnUnboxedClosureKind, MethodImplItem, P}; use ast::{FnUnboxedClosureKind, MethodImplItem};
use ast::{RegionTyParamBound, TraitTyParamBound, UnboxedClosureKind}; use ast::{RegionTyParamBound, TraitTyParamBound, UnboxedClosureKind};
use ast::{UnboxedFnTyParamBound, RequiredMethod, ProvidedMethod}; use ast::{UnboxedFnTyParamBound, RequiredMethod, ProvidedMethod};
use ast; use ast;
@ -26,8 +26,8 @@ use parse;
use print::pp::{break_offset, word, space, zerobreak, hardbreak}; use print::pp::{break_offset, word, space, zerobreak, hardbreak};
use print::pp::{Breaks, Consistent, Inconsistent, eof}; use print::pp::{Breaks, Consistent, Inconsistent, eof};
use print::pp; use print::pp;
use ptr::P;
use std::gc::Gc;
use std::io::{IoResult, MemWriter}; use std::io::{IoResult, MemWriter};
use std::io; use std::io;
use std::mem; use std::mem;
@ -246,7 +246,7 @@ pub fn ident_to_string(id: &ast::Ident) -> String {
} }
pub fn fun_to_string(decl: &ast::FnDecl, fn_style: ast::FnStyle, name: ast::Ident, pub fn fun_to_string(decl: &ast::FnDecl, fn_style: ast::FnStyle, name: ast::Ident,
opt_explicit_self: Option<ast::ExplicitSelf_>, opt_explicit_self: Option<&ast::ExplicitSelf_>,
generics: &ast::Generics) -> String { generics: &ast::Generics) -> String {
$to_string(|s| { $to_string(|s| {
try!(s.print_fn(decl, Some(fn_style), abi::Rust, try!(s.print_fn(decl, Some(fn_style), abi::Rust,
@ -278,7 +278,7 @@ pub fn lit_to_string(l: &ast::Lit) -> String {
$to_string(|s| s.print_literal(l)) $to_string(|s| s.print_literal(l))
} }
pub fn explicit_self_to_string(explicit_self: ast::ExplicitSelf_) -> String { pub fn explicit_self_to_string(explicit_self: &ast::ExplicitSelf_) -> String {
$to_string(|s| s.print_explicit_self(explicit_self, ast::MutImmutable).map(|_| {})) $to_string(|s| s.print_explicit_self(explicit_self, ast::MutImmutable).map(|_| {}))
} }
@ -502,7 +502,7 @@ impl<'a> State<'a> {
} }
pub fn commasep_exprs(&mut self, b: Breaks, pub fn commasep_exprs(&mut self, b: Breaks,
exprs: &[Gc<ast::Expr>]) -> IoResult<()> { exprs: &[P<ast::Expr>]) -> IoResult<()> {
self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&**e), |e| e.span) self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&**e), |e| e.span)
} }
@ -574,7 +574,7 @@ impl<'a> State<'a> {
ast::TyTup(ref elts) => { ast::TyTup(ref elts) => {
try!(self.popen()); try!(self.popen());
try!(self.commasep(Inconsistent, elts.as_slice(), try!(self.commasep(Inconsistent, elts.as_slice(),
|s, ty| s.print_type_ref(ty))); |s, ty| s.print_type(&**ty)));
if elts.len() == 1 { if elts.len() == 1 {
try!(word(&mut self.s, ",")); try!(word(&mut self.s, ","));
} }
@ -585,7 +585,7 @@ impl<'a> State<'a> {
try!(self.print_type(&**typ)); try!(self.print_type(&**typ));
try!(self.pclose()); try!(self.pclose());
} }
ast::TyBareFn(f) => { ast::TyBareFn(ref f) => {
let generics = ast::Generics { let generics = ast::Generics {
lifetimes: f.lifetimes.clone(), lifetimes: f.lifetimes.clone(),
ty_params: OwnedSlice::empty(), ty_params: OwnedSlice::empty(),
@ -605,7 +605,7 @@ impl<'a> State<'a> {
None, None,
None)); None));
} }
ast::TyClosure(f) => { ast::TyClosure(ref f) => {
let generics = ast::Generics { let generics = ast::Generics {
lifetimes: f.lifetimes.clone(), lifetimes: f.lifetimes.clone(),
ty_params: OwnedSlice::empty(), ty_params: OwnedSlice::empty(),
@ -645,7 +645,7 @@ impl<'a> State<'a> {
None, None,
None)); None));
} }
ast::TyUnboxedFn(f) => { ast::TyUnboxedFn(ref f) => {
try!(self.print_ty_fn(None, try!(self.print_ty_fn(None,
None, None,
ast::NormalFn, ast::NormalFn,
@ -679,10 +679,6 @@ impl<'a> State<'a> {
self.end() self.end()
} }
pub fn print_type_ref(&mut self, ty: &P<ast::Ty>) -> IoResult<()> {
self.print_type(&**ty)
}
pub fn print_foreign_item(&mut self, pub fn print_foreign_item(&mut self,
item: &ast::ForeignItem) -> IoResult<()> { item: &ast::ForeignItem) -> IoResult<()> {
try!(self.hardbreak_if_not_bol()); try!(self.hardbreak_if_not_bol());
@ -794,10 +790,8 @@ impl<'a> State<'a> {
if struct_def.is_virtual { if struct_def.is_virtual {
try!(self.word_space("virtual")); try!(self.word_space("virtual"));
} }
try!(self.head(visibility_qualified(item.vis, try!(self.head(visibility_qualified(item.vis,"struct").as_slice()));
"struct").as_slice())); try!(self.print_struct(&**struct_def, generics, item.ident, item.span));
try!(self.print_struct(&**struct_def, generics, item.ident,
item.span));
} }
ast::ItemImpl(ref generics, ast::ItemImpl(ref generics,
@ -828,8 +822,8 @@ impl<'a> State<'a> {
try!(self.print_inner_attributes(item.attrs.as_slice())); try!(self.print_inner_attributes(item.attrs.as_slice()));
for impl_item in impl_items.iter() { for impl_item in impl_items.iter() {
match *impl_item { match *impl_item {
ast::MethodImplItem(meth) => { ast::MethodImplItem(ref meth) => {
try!(self.print_method(&*meth)); try!(self.print_method(&**meth));
} }
} }
} }
@ -1068,7 +1062,7 @@ impl<'a> State<'a> {
Some(m.ident), Some(m.ident),
&OwnedSlice::empty(), &OwnedSlice::empty(),
Some(&m.generics), Some(&m.generics),
Some(m.explicit_self.node), Some(&m.explicit_self.node),
None)); None));
word(&mut self.s, ";") word(&mut self.s, ";")
} }
@ -1097,18 +1091,18 @@ impl<'a> State<'a> {
abi, abi,
ref explicit_self, ref explicit_self,
fn_style, fn_style,
decl, ref decl,
body, ref body,
vis) => { vis) => {
try!(self.print_fn(&*decl, try!(self.print_fn(&**decl,
Some(fn_style), Some(fn_style),
abi, abi,
ident, ident,
generics, generics,
Some(explicit_self.node), Some(&explicit_self.node),
vis)); vis));
try!(word(&mut self.s, " ")); try!(word(&mut self.s, " "));
self.print_block_with_attrs(&*body, meth.attrs.as_slice()) self.print_block_with_attrs(&**body, meth.attrs.as_slice())
}, },
ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _), ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
..}) => { ..}) => {
@ -1199,7 +1193,7 @@ impl<'a> State<'a> {
} }
} }
} }
if parse::classify::stmt_ends_with_semi(st) { if parse::classify::stmt_ends_with_semi(&st.node) {
try!(word(&mut self.s, ";")); try!(word(&mut self.s, ";"));
} }
self.maybe_print_trailing_comment(st.span, None) self.maybe_print_trailing_comment(st.span, None)
@ -1257,19 +1251,19 @@ impl<'a> State<'a> {
self.ann.post(self, NodeBlock(blk)) self.ann.post(self, NodeBlock(blk))
} }
fn print_else(&mut self, els: Option<Gc<ast::Expr>>) -> IoResult<()> { fn print_else(&mut self, els: Option<&ast::Expr>) -> IoResult<()> {
match els { match els {
Some(_else) => { Some(_else) => {
match _else.node { match _else.node {
// "another else-if" // "another else-if"
ast::ExprIf(ref i, ref t, e) => { ast::ExprIf(ref i, ref then, ref e) => {
try!(self.cbox(indent_unit - 1u)); try!(self.cbox(indent_unit - 1u));
try!(self.ibox(0u)); try!(self.ibox(0u));
try!(word(&mut self.s, " else if ")); try!(word(&mut self.s, " else if "));
try!(self.print_expr(&**i)); try!(self.print_expr(&**i));
try!(space(&mut self.s)); try!(space(&mut self.s));
try!(self.print_block(&**t)); try!(self.print_block(&**then));
self.print_else(e) self.print_else(e.as_ref().map(|e| &**e))
} }
// "final else" // "final else"
ast::ExprBlock(ref b) => { ast::ExprBlock(ref b) => {
@ -1289,7 +1283,7 @@ impl<'a> State<'a> {
} }
pub fn print_if(&mut self, test: &ast::Expr, blk: &ast::Block, pub fn print_if(&mut self, test: &ast::Expr, blk: &ast::Block,
elseopt: Option<Gc<ast::Expr>>, chk: bool) -> IoResult<()> { elseopt: Option<&ast::Expr>, chk: bool) -> IoResult<()> {
try!(self.head("if")); try!(self.head("if"));
if chk { try!(self.word_nbsp("check")); } if chk { try!(self.word_nbsp("check")); }
try!(self.print_expr(test)); try!(self.print_expr(test));
@ -1312,7 +1306,7 @@ impl<'a> State<'a> {
} }
fn print_call_post(&mut self, args: &[Gc<ast::Expr>]) -> IoResult<()> { fn print_call_post(&mut self, args: &[P<ast::Expr>]) -> IoResult<()> {
try!(self.popen()); try!(self.popen());
try!(self.commasep_exprs(Inconsistent, args)); try!(self.commasep_exprs(Inconsistent, args));
self.pclose() self.pclose()
@ -1361,7 +1355,7 @@ impl<'a> State<'a> {
try!(self.end()); try!(self.end());
} }
ast::ExprStruct(ref path, ref fields, wth) => { ast::ExprStruct(ref path, ref fields, ref wth) => {
try!(self.print_path(path, true)); try!(self.print_path(path, true));
try!(word(&mut self.s, "{")); try!(word(&mut self.s, "{"));
try!(self.commasep_cmnt( try!(self.commasep_cmnt(
@ -1375,7 +1369,7 @@ impl<'a> State<'a> {
s.end() s.end()
}, },
|f| f.span)); |f| f.span));
match wth { match *wth {
Some(ref expr) => { Some(ref expr) => {
try!(self.ibox(indent_unit)); try!(self.ibox(indent_unit));
if !fields.is_empty() { if !fields.is_empty() {
@ -1410,7 +1404,7 @@ impl<'a> State<'a> {
if tys.len() > 0u { if tys.len() > 0u {
try!(word(&mut self.s, "::<")); try!(word(&mut self.s, "::<"));
try!(self.commasep(Inconsistent, tys.as_slice(), try!(self.commasep(Inconsistent, tys.as_slice(),
|s, ty| s.print_type_ref(ty))); |s, ty| s.print_type(&**ty)));
try!(word(&mut self.s, ">")); try!(word(&mut self.s, ">"));
} }
try!(self.print_call_post(base_args)); try!(self.print_call_post(base_args));
@ -1437,8 +1431,8 @@ impl<'a> State<'a> {
try!(self.word_space("as")); try!(self.word_space("as"));
try!(self.print_type(&**ty)); try!(self.print_type(&**ty));
} }
ast::ExprIf(ref test, ref blk, elseopt) => { ast::ExprIf(ref test, ref blk, ref elseopt) => {
try!(self.print_if(&**test, &**blk, elseopt, false)); try!(self.print_if(&**test, &**blk, elseopt.as_ref().map(|e| &**e), false));
} }
ast::ExprWhile(ref test, ref blk, opt_ident) => { ast::ExprWhile(ref test, ref blk, opt_ident) => {
for ident in opt_ident.iter() { for ident in opt_ident.iter() {
@ -1500,13 +1494,13 @@ impl<'a> State<'a> {
try!(self.print_block_unclosed(&**body)); try!(self.print_block_unclosed(&**body));
} else { } else {
// we extract the block, so as not to create another set of boxes // we extract the block, so as not to create another set of boxes
match body.expr.unwrap().node { match body.expr.as_ref().unwrap().node {
ast::ExprBlock(blk) => { ast::ExprBlock(ref blk) => {
try!(self.print_block_unclosed(&*blk)); try!(self.print_block_unclosed(&**blk));
} }
_ => { _ => {
// this is a bare expression // this is a bare expression
try!(self.print_expr(&*body.expr.unwrap())); try!(self.print_expr(&**body.expr.as_ref().unwrap()));
try!(self.end()); // need to close a box try!(self.end()); // need to close a box
} }
} }
@ -1532,13 +1526,13 @@ impl<'a> State<'a> {
try!(self.print_block_unclosed(&**body)); try!(self.print_block_unclosed(&**body));
} else { } else {
// we extract the block, so as not to create another set of boxes // we extract the block, so as not to create another set of boxes
match body.expr.unwrap().node { match body.expr.as_ref().unwrap().node {
ast::ExprBlock(ref blk) => { ast::ExprBlock(ref blk) => {
try!(self.print_block_unclosed(&**blk)); try!(self.print_block_unclosed(&**blk));
} }
_ => { _ => {
// this is a bare expression // this is a bare expression
try!(self.print_expr(&*body.expr.unwrap())); try!(self.print_expr(body.expr.as_ref().map(|e| &**e).unwrap()));
try!(self.end()); // need to close a box try!(self.end()); // need to close a box
} }
} }
@ -1560,13 +1554,13 @@ impl<'a> State<'a> {
assert!(body.stmts.is_empty()); assert!(body.stmts.is_empty());
assert!(body.expr.is_some()); assert!(body.expr.is_some());
// we extract the block, so as not to create another set of boxes // we extract the block, so as not to create another set of boxes
match body.expr.unwrap().node { match body.expr.as_ref().unwrap().node {
ast::ExprBlock(ref blk) => { ast::ExprBlock(ref blk) => {
try!(self.print_block_unclosed(&**blk)); try!(self.print_block_unclosed(&**blk));
} }
_ => { _ => {
// this is a bare expression // this is a bare expression
try!(self.print_expr(&*body.expr.unwrap())); try!(self.print_expr(body.expr.as_ref().map(|e| &**e).unwrap()));
try!(self.end()); // need to close a box try!(self.end()); // need to close a box
} }
} }
@ -1603,7 +1597,7 @@ impl<'a> State<'a> {
try!(word(&mut self.s, "::<")); try!(word(&mut self.s, "::<"));
try!(self.commasep( try!(self.commasep(
Inconsistent, tys.as_slice(), Inconsistent, tys.as_slice(),
|s, ty| s.print_type_ref(ty))); |s, ty| s.print_type(&**ty)));
try!(word(&mut self.s, ">")); try!(word(&mut self.s, ">"));
} }
} }
@ -1615,7 +1609,7 @@ impl<'a> State<'a> {
try!(word(&mut self.s, "::<")); try!(word(&mut self.s, "::<"));
try!(self.commasep( try!(self.commasep(
Inconsistent, tys.as_slice(), Inconsistent, tys.as_slice(),
|s, ty| s.print_type_ref(ty))); |s, ty| s.print_type(&**ty)));
try!(word(&mut self.s, ">")); try!(word(&mut self.s, ">"));
} }
} }
@ -1809,7 +1803,7 @@ impl<'a> State<'a> {
try!(self.commasep( try!(self.commasep(
Inconsistent, Inconsistent,
segment.types.as_slice(), segment.types.as_slice(),
|s, ty| s.print_type_ref(ty))); |s, ty| s.print_type(&**ty)));
} }
try!(word(&mut self.s, ">")) try!(word(&mut self.s, ">"))
@ -1841,7 +1835,7 @@ impl<'a> State<'a> {
match pat.node { match pat.node {
ast::PatWild(ast::PatWildSingle) => try!(word(&mut self.s, "_")), ast::PatWild(ast::PatWildSingle) => try!(word(&mut self.s, "_")),
ast::PatWild(ast::PatWildMulti) => try!(word(&mut self.s, "..")), ast::PatWild(ast::PatWildMulti) => try!(word(&mut self.s, "..")),
ast::PatIdent(binding_mode, ref path1, sub) => { ast::PatIdent(binding_mode, ref path1, ref sub) => {
match binding_mode { match binding_mode {
ast::BindByRef(mutbl) => { ast::BindByRef(mutbl) => {
try!(self.word_nbsp("ref")); try!(self.word_nbsp("ref"));
@ -1853,7 +1847,7 @@ impl<'a> State<'a> {
} }
} }
try!(self.print_ident(path1.node)); try!(self.print_ident(path1.node));
match sub { match *sub {
Some(ref p) => { Some(ref p) => {
try!(word(&mut self.s, "@")); try!(word(&mut self.s, "@"));
try!(self.print_pat(&**p)); try!(self.print_pat(&**p));
@ -1921,7 +1915,7 @@ impl<'a> State<'a> {
try!(word(&mut self.s, "..")); try!(word(&mut self.s, ".."));
try!(self.print_expr(&**end)); try!(self.print_expr(&**end));
} }
ast::PatVec(ref before, slice, ref after) => { ast::PatVec(ref before, ref slice, ref after) => {
try!(word(&mut self.s, "[")); try!(word(&mut self.s, "["));
try!(self.commasep(Inconsistent, try!(self.commasep(Inconsistent,
before.as_slice(), before.as_slice(),
@ -1994,10 +1988,10 @@ impl<'a> State<'a> {
// Returns whether it printed anything // Returns whether it printed anything
fn print_explicit_self(&mut self, fn print_explicit_self(&mut self,
explicit_self: ast::ExplicitSelf_, explicit_self: &ast::ExplicitSelf_,
mutbl: ast::Mutability) -> IoResult<bool> { mutbl: ast::Mutability) -> IoResult<bool> {
try!(self.print_mutability(mutbl)); try!(self.print_mutability(mutbl));
match explicit_self { match *explicit_self {
ast::SelfStatic => { return Ok(false); } ast::SelfStatic => { return Ok(false); }
ast::SelfValue(_) => { ast::SelfValue(_) => {
try!(word(&mut self.s, "self")); try!(word(&mut self.s, "self"));
@ -2023,7 +2017,7 @@ impl<'a> State<'a> {
abi: abi::Abi, abi: abi::Abi,
name: ast::Ident, name: ast::Ident,
generics: &ast::Generics, generics: &ast::Generics,
opt_explicit_self: Option<ast::ExplicitSelf_>, opt_explicit_self: Option<&ast::ExplicitSelf_>,
vis: ast::Visibility) -> IoResult<()> { vis: ast::Visibility) -> IoResult<()> {
try!(self.head("")); try!(self.head(""));
try!(self.print_fn_header_info(opt_explicit_self, fn_style, abi, vis)); try!(self.print_fn_header_info(opt_explicit_self, fn_style, abi, vis));
@ -2035,7 +2029,7 @@ impl<'a> State<'a> {
} }
pub fn print_fn_args(&mut self, decl: &ast::FnDecl, pub fn print_fn_args(&mut self, decl: &ast::FnDecl,
opt_explicit_self: Option<ast::ExplicitSelf_>) opt_explicit_self: Option<&ast::ExplicitSelf_>)
-> IoResult<()> { -> IoResult<()> {
// It is unfortunate to duplicate the commasep logic, but we want the // It is unfortunate to duplicate the commasep logic, but we want the
// self type and the args all in the same box. // self type and the args all in the same box.
@ -2043,7 +2037,7 @@ impl<'a> State<'a> {
let mut first = true; let mut first = true;
for &explicit_self in opt_explicit_self.iter() { for &explicit_self in opt_explicit_self.iter() {
let m = match explicit_self { let m = match explicit_self {
ast::SelfStatic => ast::MutImmutable, &ast::SelfStatic => ast::MutImmutable,
_ => match decl.inputs.get(0).pat.node { _ => match decl.inputs.get(0).pat.node {
ast::PatIdent(ast::BindByValue(m), _, _) => m, ast::PatIdent(ast::BindByValue(m), _, _) => m,
_ => ast::MutImmutable _ => ast::MutImmutable
@ -2068,7 +2062,7 @@ impl<'a> State<'a> {
} }
pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl, pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl,
opt_explicit_self: Option<ast::ExplicitSelf_>) opt_explicit_self: Option<&ast::ExplicitSelf_>)
-> IoResult<()> { -> IoResult<()> {
try!(self.popen()); try!(self.popen());
try!(self.print_fn_args(decl, opt_explicit_self)); try!(self.print_fn_args(decl, opt_explicit_self));
@ -2413,7 +2407,7 @@ impl<'a> State<'a> {
id: Option<ast::Ident>, id: Option<ast::Ident>,
bounds: &OwnedSlice<ast::TyParamBound>, bounds: &OwnedSlice<ast::TyParamBound>,
generics: Option<&ast::Generics>, generics: Option<&ast::Generics>,
opt_explicit_self: Option<ast::ExplicitSelf_>, opt_explicit_self: Option<&ast::ExplicitSelf_>,
opt_unboxed_closure_kind: opt_unboxed_closure_kind:
Option<ast::UnboxedClosureKind>) Option<ast::UnboxedClosureKind>)
-> IoResult<()> { -> IoResult<()> {
@ -2754,7 +2748,7 @@ impl<'a> State<'a> {
} }
pub fn print_fn_header_info(&mut self, pub fn print_fn_header_info(&mut self,
_opt_explicit_self: Option<ast::ExplicitSelf_>, _opt_explicit_self: Option<&ast::ExplicitSelf_>,
opt_fn_style: Option<ast::FnStyle>, opt_fn_style: Option<ast::FnStyle>,
abi: abi::Abi, abi: abi::Abi,
vis: ast::Visibility) -> IoResult<()> { vis: ast::Visibility) -> IoResult<()> {

View file

@ -9,6 +9,7 @@
// except according to those terms. // except according to those terms.
use ast; use ast;
use ast::P;
use parse::{new_parse_sess}; use parse::{new_parse_sess};
use parse::{ParseSess,string_to_filemap,filemap_to_tts}; use parse::{ParseSess,string_to_filemap,filemap_to_tts};
use parse::{new_parser_from_source_str}; use parse::{new_parser_from_source_str};
@ -48,21 +49,21 @@ pub fn string_to_crate (source_str : String) -> ast::Crate {
} }
/// Parse a string, return an expr /// Parse a string, return an expr
pub fn string_to_expr (source_str : String) -> Gc<ast::Expr> { pub fn string_to_expr (source_str : String) -> P<ast::Expr> {
with_error_checking_parse(source_str, |p| { with_error_checking_parse(source_str, |p| {
p.parse_expr() p.parse_expr()
}) })
} }
/// Parse a string, return an item /// Parse a string, return an item
pub fn string_to_item (source_str : String) -> Option<Gc<ast::Item>> { pub fn string_to_item (source_str : String) -> Option<P<ast::Item>> {
with_error_checking_parse(source_str, |p| { with_error_checking_parse(source_str, |p| {
p.parse_item(Vec::new()) p.parse_item(Vec::new())
}) })
} }
/// Parse a string, return a stmt /// Parse a string, return a stmt
pub fn string_to_stmt(source_str : String) -> Gc<ast::Stmt> { pub fn string_to_stmt(source_str : String) -> P<ast::Stmt> {
with_error_checking_parse(source_str, |p| { with_error_checking_parse(source_str, |p| {
p.parse_stmt(Vec::new()) p.parse_stmt(Vec::new())
}) })
@ -70,7 +71,7 @@ pub fn string_to_stmt(source_str : String) -> Gc<ast::Stmt> {
/// Parse a string, return a pat. Uses "irrefutable"... which doesn't /// Parse a string, return a pat. Uses "irrefutable"... which doesn't
/// (currently) affect parsing. /// (currently) affect parsing.
pub fn string_to_pat(source_str: String) -> Gc<ast::Pat> { pub fn string_to_pat(source_str: String) -> P<ast::Pat> {
string_to_parser(&new_parse_sess(), source_str).parse_pat() string_to_parser(&new_parse_sess(), source_str).parse_pat()
} }

View file

@ -27,10 +27,9 @@ use abi::Abi;
use ast::*; use ast::*;
use ast; use ast;
use codemap::Span; use codemap::Span;
use ptr::P;
use owned_slice::OwnedSlice; use owned_slice::OwnedSlice;
use std::gc::Gc;
pub enum FnKind<'a> { pub enum FnKind<'a> {
/// fn foo() or extern "Abi" fn foo() /// fn foo() or extern "Abi" fn foo()
FkItemFn(Ident, &'a Generics, FnStyle, Abi), FkItemFn(Ident, &'a Generics, FnStyle, Abi),
@ -121,16 +120,8 @@ pub fn walk_inlined_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v InlinedI
match *item { match *item {
IIItem(ref i) => visitor.visit_item(&**i), IIItem(ref i) => visitor.visit_item(&**i),
IIForeign(ref i) => visitor.visit_foreign_item(&**i), IIForeign(ref i) => visitor.visit_foreign_item(&**i),
IITraitItem(_, ref iti) => { IITraitItem(_, ref ti) => visitor.visit_trait_item(ti),
match *iti { IIImplItem(_, MethodImplItem(ref m)) => walk_method_helper(visitor, &**m)
ProvidedInlinedTraitItem(ref m) => {
walk_method_helper(visitor, &**m)
}
RequiredInlinedTraitItem(ref m) => {
walk_method_helper(visitor, &**m)
}
}
}
} }
} }
@ -644,14 +635,14 @@ pub fn walk_decl<'v, V: Visitor<'v>>(visitor: &mut V, declaration: &'v Decl) {
} }
pub fn walk_expr_opt<'v, V: Visitor<'v>>(visitor: &mut V, pub fn walk_expr_opt<'v, V: Visitor<'v>>(visitor: &mut V,
optional_expression: &'v Option<Gc<Expr>>) { optional_expression: &'v Option<P<Expr>>) {
match *optional_expression { match *optional_expression {
None => {} None => {}
Some(ref expression) => visitor.visit_expr(&**expression), Some(ref expression) => visitor.visit_expr(&**expression),
} }
} }
pub fn walk_exprs<'v, V: Visitor<'v>>(visitor: &mut V, expressions: &'v [Gc<Expr>]) { pub fn walk_exprs<'v, V: Visitor<'v>>(visitor: &mut V, expressions: &'v [P<Expr>]) {
for expression in expressions.iter() { for expression in expressions.iter() {
visitor.visit_expr(&**expression) visitor.visit_expr(&**expression)
} }