diff options
| author | bors <bors@rust-lang.org> | 2015-03-12 20:13:23 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-03-12 20:13:23 +0000 |
| commit | c9b03c24ec346e6405883032094f47805ef9c43e (patch) | |
| tree | cbb2bb6a0cd2a2e65b2cacd87d31bd8737f02e7d /src/libsyntax | |
| parent | 538840bc2d1b634a2a34b2c8bd72d99894058b66 (diff) | |
| parent | 9da918548d77182ca64f375fb6da24036d5ad60c (diff) | |
| download | rust-c9b03c24ec346e6405883032094f47805ef9c43e.tar.gz rust-c9b03c24ec346e6405883032094f47805ef9c43e.zip | |
Auto merge of #23265 - eddyb:meth-ast-refactor, r=nikomatsakis
The end result is that common fields (id, name, attributes, etc.) are stored in now-structures `ImplItem` and `TraitItem`. The signature of a method is no longer duplicated between methods with a body (default/impl) and those without, they now share `MethodSig`. This is also a [breaking-change] because of minor bugfixes and changes to syntax extensions: * `pub fn` methods in a trait no longer parse - remove the `pub`, it has no meaning anymore * `MacResult::make_methods` is now `make_impl_items` and the return type has changed accordingly * `quote_method` is gone, because `P<ast::Method>` doesn't exist and it couldn't represent a full method anyways - could be replaced by `quote_impl_item`/`quote_trait_item` in the future, but I do hope we realize how silly that combinatorial macro expansion is and settle on a single `quote` macro + some type hints - or just no types at all (only token-trees) r? @nikomatsakis This is necessary (hopefully also sufficient) for associated constants.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 82 | ||||
| -rw-r--r-- | src/libsyntax/ast_map/blocks.rs | 32 | ||||
| -rw-r--r-- | src/libsyntax/ast_map/mod.rs | 269 | ||||
| -rw-r--r-- | src/libsyntax/ast_util.rs | 124 | ||||
| -rw-r--r-- | src/libsyntax/config.rs | 23 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 63 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic/mod.rs | 42 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 168 | ||||
| -rw-r--r-- | src/libsyntax/ext/quote.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 178 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 155 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 209 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 121 |
14 files changed, 503 insertions, 983 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 550ce3bb8c8..657ffcaece9 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -22,7 +22,7 @@ pub use self::Expr_::*; pub use self::FloatTy::*; pub use self::FunctionRetTy::*; pub use self::ForeignItem_::*; -pub use self::ImplItem::*; +pub use self::ImplItem_::*; pub use self::InlinedItem::*; pub use self::IntTy::*; pub use self::Item_::*; @@ -33,7 +33,6 @@ pub use self::LocalSource::*; pub use self::Mac_::*; pub use self::MacStmtStyle::*; pub use self::MetaItem_::*; -pub use self::Method_::*; pub use self::Mutability::*; pub use self::Pat_::*; pub use self::PathListItem_::*; @@ -44,7 +43,7 @@ pub use self::Stmt_::*; pub use self::StrStyle::*; pub use self::StructFieldKind::*; pub use self::TokenTree::*; -pub use self::TraitItem::*; +pub use self::TraitItem_::*; pub use self::Ty_::*; pub use self::TyParamBound::*; pub use self::UintTy::*; @@ -1058,20 +1057,15 @@ pub struct TypeField { pub span: Span, } -/// Represents a required method in a trait declaration, -/// one without a default implementation +/// Represents a method's signature in a trait declaration, +/// or in an implementation. #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct TypeMethod { - pub ident: Ident, - pub attrs: Vec<Attribute>, +pub struct MethodSig { pub unsafety: Unsafety, pub abi: Abi, pub decl: P<FnDecl>, pub generics: Generics, pub explicit_self: ExplicitSelf, - pub id: NodeId, - pub span: Span, - pub vis: Visibility, } /// Represents a method declaration in a trait declaration, possibly including @@ -1079,32 +1073,35 @@ pub struct TypeMethod { /// doesn't have an implementation, just a signature) or provided (meaning it /// has a default implementation). #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum TraitItem { - RequiredMethod(TypeMethod), - ProvidedMethod(P<Method>), - TypeTraitItem(P<AssociatedType>), -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum ImplItem { - MethodImplItem(P<Method>), - TypeImplItem(P<Typedef>), +pub struct TraitItem { + pub id: NodeId, + pub ident: Ident, + pub attrs: Vec<Attribute>, + pub node: TraitItem_, + pub span: Span, } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct AssociatedType { - pub attrs: Vec<Attribute>, - pub ty_param: TyParam, +pub enum TraitItem_ { + MethodTraitItem(MethodSig, Option<P<Block>>), + TypeTraitItem(TyParamBounds, Option<P<Ty>>), } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct Typedef { +pub struct ImplItem { pub id: NodeId, - pub span: Span, pub ident: Ident, pub vis: Visibility, pub attrs: Vec<Attribute>, - pub typ: P<Ty>, + pub node: ImplItem_, + pub span: Span, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum ImplItem_ { + MethodImplItem(MethodSig, P<Block>), + TypeImplItem(P<Ty>), + MacImplItem(Mac), } #[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Copy)] @@ -1419,29 +1416,6 @@ pub enum ExplicitSelf_ { pub type ExplicitSelf = Spanned<ExplicitSelf_>; #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct Method { - pub attrs: Vec<Attribute>, - pub id: NodeId, - pub span: Span, - pub node: Method_, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum Method_ { - /// Represents a method declaration - MethDecl(Ident, - Generics, - Abi, - ExplicitSelf, - Unsafety, - P<FnDecl>, - P<Block>, - Visibility), - /// Represents a macro in method position - MethMac(Mac), -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct Mod { /// A span from the first token past `{` to the last token until `}`. /// For `mod foo;`, the inner span ranges from the first token @@ -1659,7 +1633,7 @@ pub enum Item_ { ItemTrait(Unsafety, Generics, TyParamBounds, - Vec<TraitItem>), + Vec<P<TraitItem>>), // Default trait implementations // `impl Trait for ..` @@ -1669,7 +1643,7 @@ pub enum Item_ { Generics, Option<TraitRef>, // (optional) trait this impl implements P<Ty>, // self - Vec<ImplItem>), + Vec<P<ImplItem>>), /// A macro invocation (which includes macro definition) ItemMac(Mac), } @@ -1726,8 +1700,8 @@ impl ForeignItem_ { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum InlinedItem { IIItem(P<Item>), - IITraitItem(DefId /* impl id */, TraitItem), - IIImplItem(DefId /* impl id */, ImplItem), + IITraitItem(DefId /* impl id */, P<TraitItem>), + IIImplItem(DefId /* impl id */, P<ImplItem>), IIForeign(P<ForeignItem>), } diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs index 1a537c7a5b8..16a339cdcb5 100644 --- a/src/libsyntax/ast_map/blocks.rs +++ b/src/libsyntax/ast_map/blocks.rs @@ -28,7 +28,6 @@ use ast::{Block, FnDecl, NodeId}; use ast; use ast_map::{Node}; use ast_map; -use ast_util::PostExpansionMethod; use codemap::Span; use visit; @@ -65,7 +64,7 @@ impl MaybeFnLike for ast::Item { impl MaybeFnLike for ast::TraitItem { fn is_fn_like(&self) -> bool { - match *self { ast::ProvidedMethod(_) => true, _ => false, } + match self.node { ast::MethodTraitItem(_, Some(_)) => true, _ => false, } } } @@ -156,25 +155,25 @@ impl<'a> FnLikeNode<'a> { pub fn body(self) -> &'a Block { self.handle(|i: ItemFnParts<'a>| &*i.body, - |m: &'a ast::Method| m.pe_body(), + |_, _, _: &'a ast::MethodSig, body: &'a ast::Block, _| body, |c: ClosureParts<'a>| c.body) } pub fn decl(self) -> &'a FnDecl { self.handle(|i: ItemFnParts<'a>| &*i.decl, - |m: &'a ast::Method| m.pe_fn_decl(), + |_, _, sig: &'a ast::MethodSig, _, _| &sig.decl, |c: ClosureParts<'a>| c.decl) } pub fn span(self) -> Span { self.handle(|i: ItemFnParts| i.span, - |m: &'a ast::Method| m.span, + |_, _, _: &'a ast::MethodSig, _, span| span, |c: ClosureParts| c.span) } pub fn id(self) -> NodeId { self.handle(|i: ItemFnParts| i.id, - |m: &'a ast::Method| m.id, + |id, _, _: &'a ast::MethodSig, _, _| id, |c: ClosureParts| c.id) } @@ -185,15 +184,15 @@ impl<'a> FnLikeNode<'a> { let closure = |_: ClosureParts| { visit::FkFnBlock }; - let method = |m: &'a ast::Method| { - visit::FkMethod(m.pe_ident(), m.pe_generics(), m) + let method = |_, ident, sig: &'a ast::MethodSig, _, _| { + visit::FkMethod(ident, sig) }; self.handle(item, method, closure) } fn handle<A, I, M, C>(self, item_fn: I, method: M, closure: C) -> A where I: FnOnce(ItemFnParts<'a>) -> A, - M: FnOnce(&'a ast::Method) -> A, + M: FnOnce(NodeId, ast::Ident, &'a ast::MethodSig, &'a ast::Block, Span) -> A, C: FnOnce(ClosureParts<'a>) -> A, { match self.node { @@ -205,14 +204,19 @@ impl<'a> FnLikeNode<'a> { }), _ => panic!("item FnLikeNode that is not fn-like"), }, - ast_map::NodeTraitItem(t) => match *t { - ast::ProvidedMethod(ref m) => method(&**m), + ast_map::NodeTraitItem(ti) => match ti.node { + ast::MethodTraitItem(ref sig, Some(ref body)) => { + method(ti.id, ti.ident, sig, body, ti.span) + } _ => panic!("trait method FnLikeNode that is not fn-like"), }, ast_map::NodeImplItem(ii) => { - match *ii { - ast::MethodImplItem(ref m) => method(&**m), - ast::TypeImplItem(_) => { + match ii.node { + ast::MethodImplItem(ref sig, ref body) => { + method(ii.id, ii.ident, sig, body, ii.span) + } + ast::TypeImplItem(_) | + ast::MacImplItem(_) => { panic!("impl method FnLikeNode that is not fn-like") } } diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index b96d735d92d..48bb044cb18 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -19,7 +19,6 @@ use codemap::{DUMMY_SP, Span, Spanned}; use fold::Folder; use parse::token; use print::pprust; -use ptr::P; use visit::{self, Visitor}; use arena::TypedArena; @@ -375,35 +374,8 @@ impl<'ast> Map<'ast> { } } NodeForeignItem(i) => PathName(i.ident.name), - NodeImplItem(ii) => { - match *ii { - MethodImplItem(ref m) => { - match m.node { - MethDecl(ident, _, _, _, _, _, _, _) => { - PathName(ident.name) - } - MethMac(_) => { - panic!("no path elem for {:?}", node) - } - } - } - TypeImplItem(ref t) => PathName(t.ident.name), - } - }, - NodeTraitItem(tm) => match *tm { - RequiredMethod(ref m) => PathName(m.ident.name), - ProvidedMethod(ref m) => { - match m.node { - MethDecl(ident, _, _, _, _, _, _, _) => { - PathName(ident.name) - } - MethMac(_) => panic!("no path elem for {:?}", node), - } - } - TypeTraitItem(ref m) => { - PathName(m.ty_param.ident.name) - } - }, + NodeImplItem(ii) => PathName(ii.ident.name), + NodeTraitItem(ti) => PathName(ti.ident.name), NodeVariant(v) => PathName(v.node.name.name), _ => panic!("no path elem for {:?}", node) } @@ -459,21 +431,12 @@ impl<'ast> Map<'ast> { /// Given a node ID, get a list of of attributes associated with the AST /// corresponding to the Node ID - pub fn attrs(&self, id: NodeId) -> &[Attribute] { + pub fn attrs(&self, id: NodeId) -> &'ast [Attribute] { let attrs = match self.find(id) { Some(NodeItem(i)) => Some(&i.attrs[..]), Some(NodeForeignItem(fi)) => Some(&fi.attrs[..]), - Some(NodeTraitItem(ref tm)) => match **tm { - RequiredMethod(ref type_m) => Some(&type_m.attrs[..]), - ProvidedMethod(ref m) => Some(&m.attrs[..]), - TypeTraitItem(ref typ) => Some(&typ.attrs[..]), - }, - Some(NodeImplItem(ref ii)) => { - match **ii { - MethodImplItem(ref m) => Some(&m.attrs[..]), - TypeImplItem(ref t) => Some(&t.attrs[..]), - } - } + Some(NodeTraitItem(ref ti)) => Some(&ti.attrs[..]), + Some(NodeImplItem(ref ii)) => Some(&ii.attrs[..]), Some(NodeVariant(ref v)) => Some(&v.node.attrs[..]), // unit/tuple structs take the attributes straight from // the struct definition. @@ -506,19 +469,8 @@ impl<'ast> Map<'ast> { let sp = match self.find(id) { Some(NodeItem(item)) => item.span, Some(NodeForeignItem(foreign_item)) => foreign_item.span, - Some(NodeTraitItem(trait_method)) => { - match *trait_method { - RequiredMethod(ref type_method) => type_method.span, - ProvidedMethod(ref method) => method.span, - TypeTraitItem(ref typedef) => typedef.ty_param.span, - } - } - Some(NodeImplItem(ref impl_item)) => { - match **impl_item { - MethodImplItem(ref method) => method.span, - TypeImplItem(ref typedef) => typedef.span, - } - } + Some(NodeTraitItem(trait_method)) => trait_method.span, + Some(NodeImplItem(ref impl_item)) => impl_item.span, Some(NodeVariant(variant)) => variant.span, Some(NodeExpr(expr)) => expr.span, Some(NodeStmt(stmt)) => stmt.span, @@ -651,31 +603,8 @@ impl<T:Named> Named for Spanned<T> { fn name(&self) -> Name { self.node.name() } impl Named for Item { fn name(&self) -> Name { self.ident.name } } impl Named for ForeignItem { fn name(&self) -> Name { self.ident.name } } impl Named for Variant_ { fn name(&self) -> Name { self.name.name } } -impl Named for TraitItem { - fn name(&self) -> Name { - match *self { - RequiredMethod(ref tm) => tm.ident.name, - ProvidedMethod(ref m) => m.name(), - TypeTraitItem(ref at) => at.ty_param.ident.name, - } - } -} -impl Named for ImplItem { - fn name(&self) -> Name { - match *self { - MethodImplItem(ref m) => m.name(), - TypeImplItem(ref td) => td.ident.name, - } - } -} -impl Named for Method { - fn name(&self) -> Name { - match self.node { - MethDecl(i, _, _, _, _, _, _, _) => i.name, - MethMac(_) => panic!("encountered unexpanded method macro."), - } - } -} +impl Named for TraitItem { fn name(&self) -> Name { self.ident.name } } +impl Named for ImplItem { fn name(&self) -> Name { self.ident.name } } pub trait FoldOps { fn new_id(&self, id: NodeId) -> NodeId { @@ -740,15 +669,8 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { self.parent = i.id; match i.node { ItemImpl(_, _, _, _, _, ref impl_items) => { - for impl_item in impl_items { - match *impl_item { - MethodImplItem(ref m) => { - self.insert(m.id, NodeImplItem(impl_item)); - } - TypeImplItem(ref t) => { - self.insert(t.id, NodeImplItem(impl_item)); - } - } + for ii in impl_items { + self.insert(ii.id, NodeImplItem(ii)); } } ItemEnum(ref enum_definition, _) => { @@ -777,18 +699,8 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { } } - for tm in trait_items { - match *tm { - RequiredMethod(ref m) => { - self.insert(m.id, NodeTraitItem(tm)); - } - ProvidedMethod(ref m) => { - self.insert(m.id, NodeTraitItem(tm)); - } - TypeTraitItem(ref typ) => { - self.insert(typ.ty_param.id, NodeTraitItem(tm)); - } - } + for ti in trait_items { + self.insert(ti.id, NodeTraitItem(ti)); } } _ => {} @@ -797,6 +709,20 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { self.parent = parent; } + fn visit_trait_item(&mut self, ti: &'ast TraitItem) { + let parent = self.parent; + self.parent = ti.id; + visit::walk_trait_item(self, ti); + self.parent = parent; + } + + fn visit_impl_item(&mut self, ii: &'ast ImplItem) { + let parent = self.parent; + self.parent = ii.id; + visit::walk_impl_item(self, ii); + self.parent = parent; + } + fn visit_pat(&mut self, pat: &'ast Pat) { self.insert(pat.id, match pat.node { // Note: this is at least *potentially* a pattern... @@ -816,29 +742,10 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { visit::walk_stmt(self, stmt); } - fn visit_ty_method(&mut self, m: &'ast TypeMethod) { - let parent = self.parent; - self.parent = m.id; - self.visit_fn_decl(&*m.decl); - visit::walk_ty_method(self, m); - self.parent = parent; - } - fn visit_fn(&mut self, fk: visit::FnKind<'ast>, fd: &'ast FnDecl, - b: &'ast Block, s: Span, id: NodeId) { - match fk { - visit::FkMethod(..) => { - let parent = self.parent; - self.parent = id; - self.visit_fn_decl(fd); - visit::walk_fn(self, fk, fd, b, s); - self.parent = parent; - } - _ => { - self.visit_fn_decl(fd); - visit::walk_fn(self, fk, fd, b, s); - } - } + b: &'ast Block, s: Span, _: NodeId) { + self.visit_fn_decl(fd); + visit::walk_fn(self, fk, fd, b, s); } fn visit_ty(&mut self, ty: &'ast Ty) { @@ -920,33 +827,14 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, let mut fld = IdAndSpanUpdater { fold_ops: fold_ops }; let ii = match ii { IIItem(i) => IIItem(fld.fold_item(i).expect_one("expected one item")), - IITraitItem(d, ti) => match ti { - ProvidedMethod(m) => { - IITraitItem(fld.fold_ops.new_def_id(d), - ProvidedMethod(fld.fold_method(m) - .expect_one("expected one method"))) - } - RequiredMethod(ty_m) => { - IITraitItem(fld.fold_ops.new_def_id(d), - RequiredMethod(fld.fold_type_method(ty_m))) - } - TypeTraitItem(at) => { - IITraitItem( - fld.fold_ops.new_def_id(d), - TypeTraitItem(P(fld.fold_associated_type((*at).clone())))) - } - }, - IIImplItem(d, m) => match m { - MethodImplItem(m) => { - IIImplItem(fld.fold_ops.new_def_id(d), - MethodImplItem(fld.fold_method(m) - .expect_one("expected one method"))) - } - TypeImplItem(t) => { - IIImplItem(fld.fold_ops.new_def_id(d), - TypeImplItem(P(fld.fold_typedef((*t).clone())))) - } - }, + IITraitItem(d, ti) => { + IITraitItem(fld.fold_ops.new_def_id(d), + fld.fold_trait_item(ti).expect_one("expected one trait item")) + } + IIImplItem(d, ii) => { + IIImplItem(fld.fold_ops.new_def_id(d), + fld.fold_impl_item(ii).expect_one("expected one impl item")) + } IIForeign(i) => IIForeign(fld.fold_foreign_item(i)) }; @@ -968,25 +856,14 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, // add it to the table now. Likewise with foreign items. match ii_parent.ii { IIItem(_) => {} - IITraitItem(_, ref trait_item) => { - let trait_item_id = match *trait_item { - ProvidedMethod(ref m) => m.id, - RequiredMethod(ref m) => m.id, - TypeTraitItem(ref ty) => ty.ty_param.id, - }; - - collector.insert(trait_item_id, NodeTraitItem(trait_item)); + IITraitItem(_, ref ti) => { + collector.insert(ti.id, NodeTraitItem(ti)); } - IIImplItem(_, ref impl_item) => { - let impl_item_id = match *impl_item { - MethodImplItem(ref m) => m.id, - TypeImplItem(ref ti) => ti.id, - }; - - collector.insert(impl_item_id, NodeImplItem(impl_item)); + IIImplItem(_, ref ii) => { + collector.insert(ii.id, NodeImplItem(ii)); } IIForeign(ref i) => { - collector.insert(i.id, NodeForeignItem(&**i)); + collector.insert(i.id, NodeForeignItem(i)); } } *map.map.borrow_mut() = collector.map; @@ -1002,8 +879,8 @@ impl<'a> NodePrinter for pprust::State<'a> { match *node { NodeItem(a) => self.print_item(&*a), NodeForeignItem(a) => self.print_foreign_item(&*a), - NodeTraitItem(a) => self.print_trait_method(&*a), - NodeImplItem(a) => self.print_impl_item(&*a), + NodeTraitItem(a) => self.print_trait_item(a), + NodeImplItem(a) => self.print_impl_item(a), NodeVariant(a) => self.print_variant(&*a), NodeExpr(a) => self.print_expr(&*a), NodeStmt(a) => self.print_stmt(&*a), @@ -1050,44 +927,38 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { let path_str = map.path_to_str_with_ident(id, item.ident); format!("foreign item {}{}", path_str, id_str) } - Some(NodeImplItem(ref ii)) => { - match **ii { - MethodImplItem(ref m) => { - match m.node { - MethDecl(ident, _, _, _, _, _, _, _) => - format!("method {} in {}{}", - token::get_ident(ident), - map.path_to_string(id), id_str), - MethMac(ref mac) => - format!("method macro {}{}", - pprust::mac_to_string(mac), id_str) - } - } - TypeImplItem(ref t) => { - format!("typedef {} in {}{}", - token::get_ident(t.ident), - map.path_to_string(id), - id_str) - } - } - } - Some(NodeTraitItem(ref tm)) => { - match **tm { - RequiredMethod(_) | ProvidedMethod(_) => { - let m = ast_util::trait_item_to_ty_method(&**tm); + Some(NodeImplItem(ii)) => { + match ii.node { + MethodImplItem(..) => { format!("method {} in {}{}", - token::get_ident(m.ident), - map.path_to_string(id), - id_str) + token::get_ident(ii.ident), + map.path_to_string(id), id_str) } - TypeTraitItem(ref t) => { - format!("type item {} in {}{}", - token::get_ident(t.ty_param.ident), + TypeImplItem(_) => { + format!("assoc type {} in {}{}", + token::get_ident(ii.ident), map.path_to_string(id), id_str) } + MacImplItem(ref mac) => { + format!("method macro {}{}", + pprust::mac_to_string(mac), id_str) + } } } + Some(NodeTraitItem(ti)) => { + let kind = match ti.node { + MethodTraitItem(..) => "trait method", + TypeTraitItem(..) => "assoc type", +// ConstTraitItem(..) => "assoc constant" + }; + + format!("{} {} in {}{}", + kind, + token::get_ident(ti.ident), + map.path_to_string(id), + id_str) + } Some(NodeVariant(ref variant)) => { format!("variant {} in {}{}", token::get_ident(variant.node.name), diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 26d7562cdb2..cec824e79ff 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::Abi; use ast::*; use ast; use ast_util; @@ -268,62 +267,6 @@ pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: Option<&Ty>) -> Ident token::gensym_ident(&pretty[..]) } -pub fn trait_method_to_ty_method(method: &Method) -> TypeMethod { - match method.node { - MethDecl(ident, - ref generics, - abi, - ref explicit_self, - unsafety, - ref decl, - _, - vis) => { - TypeMethod { - ident: ident, - attrs: method.attrs.clone(), - unsafety: unsafety, - decl: (*decl).clone(), - generics: generics.clone(), - explicit_self: (*explicit_self).clone(), - id: method.id, - span: method.span, - vis: vis, - abi: abi, - } - }, - MethMac(_) => panic!("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), - TypeTraitItem(_) => { - panic!("trait_method_to_ty_method(): expected method but found \ - typedef") - } - } -} - -pub fn split_trait_methods(trait_methods: &[TraitItem]) - -> (Vec<TypeMethod>, Vec<P<Method>> ) { - let mut reqd = Vec::new(); - let mut provd = Vec::new(); - for trt_method in trait_methods { - match *trt_method { - RequiredMethod(ref tm) => reqd.push((*tm).clone()), - ProvidedMethod(ref m) => provd.push((*m).clone()), - TypeTraitItem(_) => {} - } - }; - (reqd, provd) -} - pub fn struct_field_visibility(field: ast::StructField) -> Visibility { match field.node.kind { ast::NamedField(_, v) | ast::UnnamedField(v) => v @@ -513,10 +456,12 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { self.operation.visit_id(node_id); match function_kind { - visit::FkItemFn(_, generics, _, _) | - visit::FkMethod(_, generics, _) => { + visit::FkItemFn(_, generics, _, _) => { self.visit_generics_helper(generics) } + visit::FkMethod(_, sig) => { + self.visit_generics_helper(&sig.generics) + } visit::FkFnBlock => {} } @@ -552,13 +497,14 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { visit::walk_struct_def(self, struct_def); } - fn visit_trait_item(&mut self, tm: &ast::TraitItem) { - match *tm { - ast::RequiredMethod(ref m) => self.operation.visit_id(m.id), - ast::ProvidedMethod(ref m) => self.operation.visit_id(m.id), - ast::TypeTraitItem(ref typ) => self.operation.visit_id(typ.ty_param.id), - } - visit::walk_trait_item(self, tm); + fn visit_trait_item(&mut self, ti: &ast::TraitItem) { + self.operation.visit_id(ti.id); + visit::walk_trait_item(self, ti); + } + + fn visit_impl_item(&mut self, ii: &ast::ImplItem) { + self.operation.visit_id(ii.id); + visit::walk_impl_item(self, ii); } fn visit_lifetime_ref(&mut self, lifetime: &Lifetime) { @@ -701,52 +647,6 @@ pub fn lit_is_str(lit: &Lit) -> bool { } } -/// Macro invocations are guaranteed not to occur after expansion is complete. -/// Extracting fields of a method requires a dynamic check to make sure that it's -/// not a macro invocation. This check is guaranteed to succeed, assuming -/// that the invocations are indeed gone. -pub trait PostExpansionMethod { - fn pe_ident(&self) -> ast::Ident; - fn pe_generics<'a>(&'a self) -> &'a ast::Generics; - fn pe_abi(&self) -> Abi; - fn pe_explicit_self<'a>(&'a self) -> &'a ast::ExplicitSelf; - fn pe_unsafety(&self) -> ast::Unsafety; - fn pe_fn_decl<'a>(&'a self) -> &'a ast::FnDecl; - fn pe_body<'a>(&'a self) -> &'a ast::Block; - fn pe_vis(&self) -> ast::Visibility; -} - -macro_rules! mf_method{ - ($meth_name:ident, $field_ty:ty, $field_pat:pat, $result:expr) => { - fn $meth_name<'a>(&'a self) -> $field_ty { - match self.node { - $field_pat => $result, - MethMac(_) => { - panic!("expected an AST without macro invocations"); - } - } - } - } -} - - -impl PostExpansionMethod for Method { - mf_method! { pe_ident,ast::Ident,MethDecl(ident,_,_,_,_,_,_,_),ident } - mf_method! { - pe_generics,&'a ast::Generics, - MethDecl(_,ref generics,_,_,_,_,_,_),generics - } - mf_method! { pe_abi,Abi,MethDecl(_,_,abi,_,_,_,_,_),abi } - mf_method! { - pe_explicit_self,&'a ast::ExplicitSelf, - MethDecl(_,_,_,ref explicit_self,_,_,_,_),explicit_self - } - mf_method! { pe_unsafety,ast::Unsafety,MethDecl(_,_,_,_,unsafety,_,_,_),unsafety } - mf_method! { pe_fn_decl,&'a ast::FnDecl,MethDecl(_,_,_,_,_,ref decl,_,_),&**decl } - mf_method! { pe_body,&'a ast::Block,MethDecl(_,_,_,_,_,_,ref body,_),&**body } - mf_method! { pe_vis,ast::Visibility,MethDecl(_,_,_,_,_,_,_,vis),vis } -} - #[cfg(test)] mod test { use ast::*; diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index dfe3477bddc..489a7721d7b 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -118,13 +118,13 @@ fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_ let item = match item { ast::ItemImpl(u, o, a, b, c, impl_items) => { let impl_items = impl_items.into_iter() - .filter(|ii| impl_item_in_cfg(cx, ii)) + .filter(|ii| (cx.in_cfg)(&ii.attrs)) .collect(); ast::ItemImpl(u, o, a, b, c, impl_items) } ast::ItemTrait(u, a, b, methods) => { let methods = methods.into_iter() - .filter(|m| trait_method_in_cfg(cx, m)) + .filter(|ti| (cx.in_cfg)(&ti.attrs)) .collect(); ast::ItemTrait(u, a, b, methods) } @@ -246,25 +246,6 @@ fn foreign_item_in_cfg<F>(cx: &mut Context<F>, item: &ast::ForeignItem) -> bool return (cx.in_cfg)(&item.attrs); } -fn trait_method_in_cfg<F>(cx: &mut Context<F>, meth: &ast::TraitItem) -> bool where - F: FnMut(&[ast::Attribute]) -> bool -{ - match *meth { - ast::RequiredMethod(ref meth) => (cx.in_cfg)(&meth.attrs), - ast::ProvidedMethod(ref meth) => (cx.in_cfg)(&meth.attrs), - ast::TypeTraitItem(ref typ) => (cx.in_cfg)(&typ.attrs), - } -} - -fn impl_item_in_cfg<F>(cx: &mut Context<F>, impl_item: &ast::ImplItem) -> bool where - F: FnMut(&[ast::Attribute]) -> bool -{ - match *impl_item { - ast::MethodImplItem(ref meth) => (cx.in_cfg)(&meth.attrs), - ast::TypeImplItem(ref typ) => (cx.in_cfg)(&typ.attrs), - } -} - // Determine if an item should be translated in the current crate // configuration based on the item's attributes fn in_cfg(diagnostic: &SpanHandler, cfg: &[P<ast::MetaItem>], attrs: &[ast::Attribute]) -> bool { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 8aeafe419da..35449bde0b2 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -77,51 +77,31 @@ impl<F> ItemModifier for F #[derive(Debug,Clone)] pub enum Annotatable { Item(P<ast::Item>), - TraitItem(ast::TraitItem), - ImplItem(ast::ImplItem), + TraitItem(P<ast::TraitItem>), + ImplItem(P<ast::ImplItem>), } impl Annotatable { pub fn attrs(&self) -> &[ast::Attribute] { match *self { Annotatable::Item(ref i) => &i.attrs, - Annotatable::TraitItem(ref i) => match *i { - ast::TraitItem::RequiredMethod(ref tm) => &tm.attrs, - ast::TraitItem::ProvidedMethod(ref m) => &m.attrs, - ast::TraitItem::TypeTraitItem(ref at) => &at.attrs, - }, - Annotatable::ImplItem(ref i) => match *i { - ast::ImplItem::MethodImplItem(ref m) => &m.attrs, - ast::ImplItem::TypeImplItem(ref t) => &t.attrs, - } + Annotatable::TraitItem(ref ti) => &ti.attrs, + Annotatable::ImplItem(ref ii) => &ii.attrs, } } pub fn fold_attrs(self, attrs: Vec<ast::Attribute>) -> Annotatable { match self { - Annotatable::Item(i) => Annotatable::Item(P(ast::Item { + Annotatable::Item(i) => Annotatable::Item(i.map(|i| ast::Item { attrs: attrs, - ..(*i).clone() + ..i + })), + Annotatable::TraitItem(i) => Annotatable::TraitItem(i.map(|ti| { + ast::TraitItem { attrs: attrs, ..ti } + })), + Annotatable::ImplItem(i) => Annotatable::ImplItem(i.map(|ii| { + ast::ImplItem { attrs: attrs, ..ii } })), - Annotatable::TraitItem(i) => match i { - ast::TraitItem::RequiredMethod(tm) => Annotatable::TraitItem( - ast::TraitItem::RequiredMethod( - ast::TypeMethod { attrs: attrs, ..tm })), - ast::TraitItem::ProvidedMethod(m) => Annotatable::TraitItem( - ast::TraitItem::ProvidedMethod(P( - ast::Method { attrs: attrs, ..(*m).clone() }))), - ast::TraitItem::TypeTraitItem(at) => Annotatable::TraitItem( - ast::TraitItem::TypeTraitItem(P( - ast::AssociatedType { attrs: attrs, ..(*at).clone() }))), - }, - Annotatable::ImplItem(i) => match i { - ast::ImplItem::MethodImplItem(m) => Annotatable::ImplItem( - ast::ImplItem::MethodImplItem(P( - ast::Method { attrs: attrs, ..(*m).clone() }))), - ast::ImplItem::TypeImplItem(t) => Annotatable::ImplItem( - ast::ImplItem::TypeImplItem(P( - ast::Typedef { attrs: attrs, ..(*t).clone() }))), - } } } @@ -132,14 +112,14 @@ impl Annotatable { } } - pub fn expect_trait_item(self) -> ast::TraitItem { + pub fn expect_trait_item(self) -> P<ast::TraitItem> { match self { Annotatable::TraitItem(i) => i, _ => panic!("expected Item") } } - pub fn expect_impl_item(self) -> ast::ImplItem { + pub fn expect_impl_item(self) -> P<ast::ImplItem> { match self { Annotatable::ImplItem(i) => i, _ => panic!("expected Item") @@ -248,8 +228,8 @@ pub trait MacResult { None } - /// Create zero or more methods. - fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::Method>>> { + /// Create zero or more impl items. + fn make_impl_items(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> { None } @@ -295,7 +275,7 @@ make_MacEager! { expr: P<ast::Expr>, pat: P<ast::Pat>, items: SmallVector<P<ast::Item>>, - methods: SmallVector<P<ast::Method>>, + impl_items: SmallVector<P<ast::ImplItem>>, stmt: P<ast::Stmt>, } @@ -308,8 +288,8 @@ impl MacResult for MacEager { self.items } - fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::Method>>> { - self.methods + fn make_impl_items(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> { + self.impl_items } fn make_stmt(self: Box<Self>) -> Option<P<ast::Stmt>> { @@ -397,7 +377,7 @@ impl MacResult for DummyResult { Some(SmallVector::zero()) } } - fn make_methods(self: Box<DummyResult>) -> Option<SmallVector<P<ast::Method>>> { + fn make_impl_items(self: Box<DummyResult>) -> Option<SmallVector<P<ast::ImplItem>>> { if self.expr_only { None } else { @@ -505,9 +485,6 @@ fn initial_syntax_expander_table<'feat>(ecfg: &expand::ExpansionConfig<'feat>) syntax_expanders.insert(intern("quote_ty"), builtin_normal_expander( ext::quote::expand_quote_ty)); - syntax_expanders.insert(intern("quote_method"), - builtin_normal_expander( - ext::quote::expand_quote_method)); syntax_expanders.insert(intern("quote_item"), builtin_normal_expander( ext::quote::expand_quote_item)); diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index 9cd965a8138..58b6d96607d 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -386,22 +386,22 @@ impl<'a> TraitDef<'a> { cx: &mut ExtCtxt, type_ident: Ident, generics: &Generics, - methods: Vec<P<ast::Method>>) -> P<ast::Item> { + methods: Vec<P<ast::ImplItem>>) -> P<ast::Item> { let trait_path = self.path.to_path(cx, self.span, type_ident, generics); - // Transform associated types from `deriving::ty::Ty` into `ast::Typedef` + // Transform associated types from `deriving::ty::Ty` into `ast::ImplItem` let associated_types = self.associated_types.iter().map(|&(ident, ref type_def)| { - P(ast::Typedef { + P(ast::ImplItem { id: ast::DUMMY_NODE_ID, span: self.span, ident: ident, vis: ast::Inherited, attrs: Vec::new(), - typ: type_def.to_ty(cx, + node: ast::TypeImplItem(type_def.to_ty(cx, self.span, type_ident, generics - ), + )), }) }); @@ -510,14 +510,7 @@ impl<'a> TraitDef<'a> { trait_generics, opt_trait_ref, self_type, - methods.into_iter() - .map(|method| { - ast::MethodImplItem(method) - }).chain( - associated_types.map(|type_| { - ast::TypeImplItem(type_) - }) - ).collect())) + methods.into_iter().chain(associated_types).collect())) } fn expand_struct_def(&self, @@ -702,7 +695,7 @@ impl<'a> MethodDef<'a> { abi: Abi, explicit_self: ast::ExplicitSelf, arg_types: Vec<(Ident, P<ast::Ty>)> , - body: P<Expr>) -> P<ast::Method> { + body: P<Expr>) -> P<ast::ImplItem> { // create the generics that aren't for Self let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics); @@ -725,18 +718,19 @@ impl<'a> MethodDef<'a> { let body_block = cx.block_expr(body); // Create the method. - P(ast::Method { - attrs: self.attributes.clone(), + P(ast::ImplItem { id: ast::DUMMY_NODE_ID, + attrs: self.attributes.clone(), span: trait_.span, - node: ast::MethDecl(method_ident, - fn_generics, - abi, - explicit_self, - ast::Unsafety::Normal, - fn_decl, - body_block, - ast::Inherited) + vis: ast::Inherited, + ident: method_ident, + node: ast::MethodImplItem(ast::MethodSig { + generics: fn_generics, + abi: abi, + explicit_self: explicit_self, + unsafety: ast::Unsafety::Normal, + decl: fn_decl + }, body_block) }) } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 6883395933e..ee2cf9017bb 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1174,29 +1174,26 @@ fn expand_annotatable(a: Annotatable, noop_fold_item(it, fld).into_iter().map(|i| Annotatable::Item(i)).collect() } }, - Annotatable::TraitItem(it) => match it { - ast::TraitItem::ProvidedMethod(m) => { - expand_method(m, fld).into_iter().map(|m| - Annotatable::TraitItem(ast::TraitItem::ProvidedMethod(m))).collect() - } - ast::TraitItem::RequiredMethod(m) => { - SmallVector::one(Annotatable::TraitItem( - ast::TraitItem::RequiredMethod(fld.fold_type_method(m)))) - } - ast::TraitItem::TypeTraitItem(t) => { - SmallVector::one(Annotatable::TraitItem( - ast::TraitItem::TypeTraitItem(P(fld.fold_associated_type((*t).clone()))))) - } - }, - Annotatable::ImplItem(it) => match it { - ast::ImplItem::MethodImplItem(m) => { - expand_method(m, fld).into_iter().map(|m| - Annotatable::ImplItem(ast::ImplItem::MethodImplItem(m))).collect() - } - ast::ImplItem::TypeImplItem(t) => { - SmallVector::one(Annotatable::ImplItem( - ast::ImplItem::TypeImplItem(P(fld.fold_typedef((*t).clone()))))) - } + + Annotatable::TraitItem(it) => match it.node { + ast::MethodTraitItem(_, Some(_)) => SmallVector::one(it.map(|ti| ast::TraitItem { + id: ti.id, + ident: ti.ident, + attrs: ti.attrs, + node: match ti.node { + ast::MethodTraitItem(sig, Some(body)) => { + let (sig, body) = expand_and_rename_method(sig, body, fld); + ast::MethodTraitItem(sig, Some(body)) + } + _ => unreachable!() + }, + span: fld.new_span(ti.span) + })), + _ => fold::noop_fold_trait_item(it, fld) + }.into_iter().map(Annotatable::TraitItem).collect(), + + Annotatable::ImplItem(ii) => { + expand_impl_item(ii, fld).into_iter().map(Annotatable::ImplItem).collect() } }; @@ -1204,21 +1201,6 @@ fn expand_annotatable(a: Annotatable, new_items } -fn expand_trait_item(i: ast::TraitItem, - fld: &mut MacroExpander) - -> SmallVector<ast::TraitItem> { - expand_annotatable(Annotatable::TraitItem(i), fld) - .into_iter().map(|i| i.expect_trait_item()).collect() - -} - -fn expand_impl_item(i: ast::ImplItem, - fld: &mut MacroExpander) - -> SmallVector<ast::ImplItem> { - expand_annotatable(Annotatable::ImplItem(i), fld) - .into_iter().map(|i| i.expect_impl_item()).collect() -} - // partition the attributes into ItemModifiers and others fn modifiers(attrs: &Vec<ast::Attribute>, fld: &MacroExpander) @@ -1292,54 +1274,48 @@ fn expand_item_multi_modifier(mut it: Annotatable, expand_item_multi_modifier(it, fld) } -// expand a method -fn expand_method(m: P<ast::Method>, fld: &mut MacroExpander) -> SmallVector<P<ast::Method>> { - m.and_then(|m| match m.node { - ast::MethDecl(ident, - generics, - abi, - explicit_self, - fn_style, - decl, - body, - vis) => { - let id = fld.new_id(m.id); - let (rewritten_fn_decl, rewritten_body) - = expand_and_rename_fn_decl_and_block(decl, body, fld); - SmallVector::one(P(ast::Method { - attrs: fold::fold_attrs(m.attrs, fld), - id: id, - span: fld.new_span(m.span), - node: ast::MethDecl(fld.fold_ident(ident), - noop_fold_generics(generics, fld), - abi, - fld.fold_explicit_self(explicit_self), - fn_style, - rewritten_fn_decl, - rewritten_body, - vis) - })) - }, - ast::MethMac(mac) => { - let maybe_new_methods = - expand_mac_invoc(mac, m.span, - |r| r.make_methods(), - |meths, mark| meths.move_map(|m| mark_method(m, mark)), +fn expand_impl_item(ii: P<ast::ImplItem>, fld: &mut MacroExpander) + -> SmallVector<P<ast::ImplItem>> { + match ii.node { + ast::MethodImplItem(..) => SmallVector::one(ii.map(|ii| ast::ImplItem { + id: ii.id, + ident: ii.ident, + attrs: ii.attrs, + vis: ii.vis, + node: match ii.node { + ast::MethodImplItem(sig, body) => { + let (sig, body) = expand_and_rename_method(sig, body, fld); + ast::MethodImplItem(sig, body) + } + _ => unreachable!() + }, + span: fld.new_span(ii.span) + })), + ast::MacImplItem(_) => { + let (span, mac) = ii.and_then(|ii| match ii.node { + ast::MacImplItem(mac) => (ii.span, mac), + _ => unreachable!() + }); + let maybe_new_items = + expand_mac_invoc(mac, span, + |r| r.make_impl_items(), + |meths, mark| meths.move_map(|m| mark_impl_item(m, mark)), fld); - match maybe_new_methods { - Some(methods) => { + match maybe_new_items { + Some(impl_items) => { // expand again if necessary - let new_methods = methods.into_iter() - .flat_map(|m| fld.fold_method(m).into_iter()) - .collect(); + let new_items = impl_items.into_iter().flat_map(|ii| { + expand_impl_item(ii, fld).into_iter() + }).collect(); fld.cx.bt_pop(); - new_methods + new_items } None => SmallVector::zero() } } - }) + _ => fold::noop_fold_impl_item(ii, fld) + } } /// Given a fn_decl and a block and a MacroExpander, expand the fn_decl, then use the @@ -1347,7 +1323,7 @@ fn expand_method(m: P<ast::Method>, fld: &mut MacroExpander) -> SmallVector<P<as /// the block, returning both the new FnDecl and the new Block. fn expand_and_rename_fn_decl_and_block(fn_decl: P<ast::FnDecl>, block: P<ast::Block>, fld: &mut MacroExpander) - -> (P<ast::FnDecl>, P<ast::Block>) { + -> (P<ast::FnDecl>, P<ast::Block>) { let expanded_decl = fld.fold_fn_decl(fn_decl); let idents = fn_decl_arg_bindings(&*expanded_decl); let renames = @@ -1361,6 +1337,20 @@ fn expand_and_rename_fn_decl_and_block(fn_decl: P<ast::FnDecl>, block: P<ast::Bl (rewritten_fn_decl,rewritten_body) } +fn expand_and_rename_method(sig: ast::MethodSig, body: P<ast::Block>, + fld: &mut MacroExpander) + -> (ast::MethodSig, P<ast::Block>) { + let (rewritten_fn_decl, rewritten_body) + = expand_and_rename_fn_decl_and_block(sig.decl, body, fld); + (ast::MethodSig { + generics: fld.fold_generics(sig.generics), + abi: sig.abi, + explicit_self: fld.fold_explicit_self(sig.explicit_self), + unsafety: sig.unsafety, + decl: rewritten_fn_decl + }, rewritten_body) +} + /// A tree-folder that performs macro expansion pub struct MacroExpander<'a, 'b:'a> { pub cx: &'a mut ExtCtxt<'b>, @@ -1410,16 +1400,14 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { expand_arm(arm, self) } - fn fold_trait_item(&mut self, i: ast::TraitItem) -> SmallVector<ast::TraitItem> { - expand_trait_item(i, self) - } - - fn fold_impl_item(&mut self, i: ast::ImplItem) -> SmallVector<ast::ImplItem> { - expand_impl_item(i, self) + fn fold_trait_item(&mut self, i: P<ast::TraitItem>) -> SmallVector<P<ast::TraitItem>> { + expand_annotatable(Annotatable::TraitItem(i), self) + .into_iter().map(|i| i.expect_trait_item()).collect() } - fn fold_method(&mut self, method: P<ast::Method>) -> SmallVector<P<ast::Method>> { - expand_method(method, self) + fn fold_impl_item(&mut self, i: P<ast::ImplItem>) -> SmallVector<P<ast::ImplItem>> { + expand_annotatable(Annotatable::ImplItem(i), self) + .into_iter().map(|i| i.expect_impl_item()).collect() } fn fold_ty(&mut self, t: P<ast::Ty>) -> P<ast::Ty> { @@ -1565,9 +1553,9 @@ fn mark_item(expr: P<ast::Item>, m: Mrk) -> P<ast::Item> { } // apply a given mark to the given item. Used following the expansion of a macro. -fn mark_method(expr: P<ast::Method>, m: Mrk) -> P<ast::Method> { - Marker{mark:m}.fold_method(expr) - .expect_one("marking an item didn't return exactly one method") +fn mark_impl_item(ii: P<ast::ImplItem>, m: Mrk) -> P<ast::ImplItem> { + Marker{mark:m}.fold_impl_item(ii) + .expect_one("marking an impl item didn't return exactly one impl item") } /// Check that there are no macro invocations left in the AST: diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 737648cd90c..48c045ee4f9 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -176,7 +176,6 @@ pub mod rt { impl_to_source! { ast::Arg, arg_to_string } impl_to_source! { Generics, generics_to_string } impl_to_source! { P<ast::Item>, item_to_string } - impl_to_source! { P<ast::Method>, method_to_string } impl_to_source! { P<ast::Stmt>, stmt_to_string } impl_to_source! { P<ast::Expr>, expr_to_string } impl_to_source! { P<ast::Pat>, pat_to_string } @@ -311,7 +310,6 @@ pub mod rt { impl_to_tokens! { P<ast::Item> } impl_to_tokens! { P<ast::Pat> } impl_to_tokens! { ast::Arm } - impl_to_tokens! { P<ast::Method> } impl_to_tokens_lifetime! { &'a [P<ast::Item>] } impl_to_tokens! { ast::Ty } impl_to_tokens_lifetime! { &'a [ast::Ty] } @@ -446,15 +444,6 @@ pub fn expand_quote_ty(cx: &mut ExtCtxt, base::MacEager::expr(expanded) } -pub fn expand_quote_method(cx: &mut ExtCtxt, - sp: Span, - tts: &[ast::TokenTree]) - -> Box<base::MacResult+'static> { - let expanded = expand_parse_call(cx, sp, "parse_method_with_outer_attributes", - vec!(), tts); - base::MacEager::expr(expanded) -} - pub fn expand_quote_stmt(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 644c6cd7e28..7575d4b5ecd 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -71,7 +71,7 @@ impl<'a> MacResult for ParserAnyMacro<'a> { loop { let mut parser = self.parser.borrow_mut(); // so... do outer attributes attached to the macro invocation - // just disappear? This question applies to make_methods, as + // just disappear? This question applies to make_impl_items, as // well. match parser.parse_item_with_outer_attributes() { Some(item) => ret.push(item), @@ -82,15 +82,14 @@ impl<'a> MacResult for ParserAnyMacro<'a> { Some(ret) } - fn make_methods(self: Box<ParserAnyMacro<'a>>) -> Option<SmallVector<P<ast::Method>>> { + fn make_impl_items(self: Box<ParserAnyMacro<'a>>) + -> Option<SmallVector<P<ast::ImplItem>>> { let mut ret = SmallVector::zero(); loop { let mut parser = self.parser.borrow_mut(); match parser.token { token::Eof => break, - _ => { - ret.push(parser.parse_method_with_outer_attributes()); - } + _ => ret.push(parser.parse_impl_item_with_outer_attributes()) } } self.ensure_complete_parse(false); diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 959e3bdb314..105a61d0857 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -98,11 +98,11 @@ pub trait Folder : Sized { noop_fold_item_underscore(i, self) } - fn fold_trait_item(&mut self, i: TraitItem) -> SmallVector<TraitItem> { + fn fold_trait_item(&mut self, i: P<TraitItem>) -> SmallVector<P<TraitItem>> { noop_fold_trait_item(i, self) } - fn fold_impl_item(&mut self, i: ImplItem) -> SmallVector<ImplItem> { + fn fold_impl_item(&mut self, i: P<ImplItem>) -> SmallVector<P<ImplItem>> { noop_fold_impl_item(i, self) } @@ -110,14 +110,6 @@ pub trait Folder : Sized { noop_fold_fn_decl(d, self) } - fn fold_type_method(&mut self, m: TypeMethod) -> TypeMethod { - noop_fold_type_method(m, self) - } - - fn fold_method(&mut self, m: P<Method>) -> SmallVector<P<Method>> { - noop_fold_method(m, self) - } - fn fold_block(&mut self, b: P<Block>) -> P<Block> { noop_fold_block(b, self) } @@ -315,15 +307,6 @@ pub trait Folder : Sized { noop_fold_where_predicate(where_predicate, self) } - fn fold_typedef(&mut self, typedef: Typedef) -> Typedef { - noop_fold_typedef(typedef, self) - } - - fn fold_associated_type(&mut self, associated_type: AssociatedType) - -> AssociatedType { - noop_fold_associated_type(associated_type, self) - } - fn new_id(&mut self, i: NodeId) -> NodeId { i } @@ -829,41 +812,6 @@ pub fn noop_fold_where_predicate<T: Folder>( } } -pub fn noop_fold_typedef<T>(t: Typedef, folder: &mut T) - -> Typedef - where T: Folder { - let new_id = folder.new_id(t.id); - let new_span = folder.new_span(t.span); - let new_attrs = t.attrs.iter().flat_map(|attr| { - folder.fold_attribute((*attr).clone()).into_iter() - }).collect(); - let new_ident = folder.fold_ident(t.ident); - let new_type = folder.fold_ty(t.typ); - ast::Typedef { - ident: new_ident, - typ: new_type, - id: new_id, - span: new_span, - vis: t.vis, - attrs: new_attrs, - } -} - -pub fn noop_fold_associated_type<T>(at: AssociatedType, folder: &mut T) - -> AssociatedType - where T: Folder -{ - let new_attrs = at.attrs - .iter() - .flat_map(|attr| folder.fold_attribute((*attr).clone()).into_iter()) - .collect(); - let new_param = folder.fold_ty_param(at.ty_param); - ast::AssociatedType { - attrs: new_attrs, - ty_param: new_param, - } -} - pub fn noop_fold_struct_def<T: Folder>(struct_def: P<StructDef>, fld: &mut T) -> P<StructDef> { struct_def.map(|StructDef { fields, ctor_id }| StructDef { fields: fields.move_map(|f| fld.fold_struct_field(f)), @@ -1018,61 +966,43 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ { } } -pub fn noop_fold_trait_item<T: Folder>(i: TraitItem, folder: &mut T) -> SmallVector<TraitItem> { - match i { - RequiredMethod(m) => { - SmallVector::one(RequiredMethod( - folder.fold_type_method(m))) - } - ProvidedMethod(method) => { - folder.fold_method(method).into_iter() - .map(|m| ProvidedMethod(m)).collect() - } - TypeTraitItem(at) => { - SmallVector::one(TypeTraitItem(P( - folder.fold_associated_type( - (*at).clone())))) - } - } -} - -pub fn noop_fold_impl_item<T: Folder>(i: ImplItem, folder: &mut T) -> SmallVector<ImplItem> { - match i { - MethodImplItem(ref x) => { - folder.fold_method((*x).clone()).into_iter().map(|m| MethodImplItem(m)).collect() - } - TypeImplItem(ref t) => { - SmallVector::one(TypeImplItem( - P(folder.fold_typedef((**t).clone())))) - } - } +pub fn noop_fold_trait_item<T: Folder>(i: P<TraitItem>, folder: &mut T) + -> SmallVector<P<TraitItem>> { + SmallVector::one(i.map(|TraitItem {id, ident, attrs, node, span}| TraitItem { + id: folder.new_id(id), + ident: folder.fold_ident(ident), + attrs: fold_attrs(attrs, folder), + node: match node { + MethodTraitItem(sig, body) => { + MethodTraitItem(noop_fold_method_sig(sig, folder), + body.map(|x| folder.fold_block(x))) + } + TypeTraitItem(bounds, default) => { + TypeTraitItem(folder.fold_bounds(bounds), + default.map(|x| folder.fold_ty(x))) + } + }, + span: folder.new_span(span) + })) } -pub fn noop_fold_type_method<T: Folder>(m: TypeMethod, fld: &mut T) -> TypeMethod { - let TypeMethod { - id, - ident, - attrs, - unsafety, - abi, - decl, - generics, - explicit_self, - vis, - span - } = m; - TypeMethod { - id: fld.new_id(id), - ident: fld.fold_ident(ident), - attrs: fold_attrs(attrs, fld), - unsafety: unsafety, - abi: abi, - decl: fld.fold_fn_decl(decl), - generics: fld.fold_generics(generics), - explicit_self: fld.fold_explicit_self(explicit_self), +pub fn noop_fold_impl_item<T: Folder>(i: P<ImplItem>, folder: &mut T) + -> SmallVector<P<ImplItem>> { + SmallVector::one(i.map(|ImplItem {id, ident, attrs, node, vis, span}| ImplItem { + id: folder.new_id(id), + ident: folder.fold_ident(ident), + attrs: fold_attrs(attrs, folder), vis: vis, - span: fld.new_span(span) - } + node: match node { + MethodImplItem(sig, body) => { + MethodImplItem(noop_fold_method_sig(sig, folder), + folder.fold_block(body)) + } + TypeImplItem(ty) => TypeImplItem(folder.fold_ty(ty)), + MacImplItem(mac) => MacImplItem(folder.fold_mac(mac)) + }, + span: folder.new_span(span) + })) } pub fn noop_fold_mod<T: Folder>(Mod {inner, items}: Mod, folder: &mut T) -> Mod { @@ -1171,34 +1101,14 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: P<ForeignItem>, folder: &mut T) -> }) } -// Default fold over a method. -// Invariant: produces exactly one method. -pub fn noop_fold_method<T: Folder>(m: P<Method>, folder: &mut T) -> SmallVector<P<Method>> { - SmallVector::one(m.map(|Method {id, attrs, node, span}| Method { - id: folder.new_id(id), - attrs: fold_attrs(attrs, folder), - node: match node { - MethDecl(ident, - generics, - abi, - explicit_self, - unsafety, - decl, - body, - vis) => { - MethDecl(folder.fold_ident(ident), - folder.fold_generics(generics), - abi, - folder.fold_explicit_self(explicit_self), - unsafety, - folder.fold_fn_decl(decl), - folder.fold_block(body), - vis) - }, - MethMac(mac) => MethMac(folder.fold_mac(mac)), - }, - span: folder.new_span(span) - })) +pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> MethodSig { + MethodSig { + generics: folder.fold_generics(sig.generics), + abi: sig.abi, + explicit_self: folder.fold_explicit_self(sig.explicit_self), + unsafety: sig.unsafety, + decl: folder.fold_fn_decl(sig.decl) + } } pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ea413ac0dc8..39c43ff1e75 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -11,9 +11,9 @@ pub use self::PathParsingMode::*; use abi; -use ast::{AssociatedType, BareFnTy}; +use ast::{BareFnTy}; use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; -use ast::{ProvidedMethod, Public, Unsafety}; +use ast::{Public, Unsafety}; use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue}; use ast::{BiBitAnd, BiBitOr, BiBitXor, BiRem, BiLt, BiGt, Block}; use ast::{BlockCheckMode, CaptureByRef, CaptureByValue, CaptureClause}; @@ -38,12 +38,11 @@ use ast::{LitBool, LitChar, LitByte, LitBinary}; use ast::{LitStr, LitInt, Local, LocalLet}; use ast::{MacStmtWithBraces, MacStmtWithSemicolon, MacStmtWithoutBraces}; use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, MatchSource}; -use ast::{Method, MutTy, BiMul, Mutability}; +use ast::{MutTy, BiMul, Mutability}; use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, NodeId, UnNot}; use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct}; use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle}; -use ast::{PolyTraitRef}; -use ast::{QSelf, RequiredMethod}; +use ast::{PolyTraitRef, QSelf}; use ast::{Return, BiShl, BiShr, Stmt, StmtDecl}; use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField}; use ast::{StructVariantKind, BiSub, StrStyle}; @@ -51,11 +50,10 @@ use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue}; use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef}; use ast::{TtDelimited, TtSequence, TtToken}; use ast::{TupleVariantKind, Ty, Ty_, TypeBinding}; -use ast::{TyFixedLengthVec, TyBareFn}; -use ast::{TyTypeof, TyInfer, TypeMethod}; +use ast::{TyFixedLengthVec, TyBareFn, TyTypeof, TyInfer}; use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr}; use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq}; -use ast::{TypeImplItem, TypeTraitItem, Typedef,}; +use ast::{TypeImplItem, TypeTraitItem}; use ast::{UnnamedField, UnsafeBlock}; use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; use ast::{Visibility, WhereClause}; @@ -1244,52 +1242,53 @@ impl<'a> Parser<'a> { /// Parses `type Foo;` in a trait declaration only. The `type` keyword has /// already been parsed. - fn parse_associated_type(&mut self, attrs: Vec<Attribute>) - -> AssociatedType - { - let ty_param = self.parse_ty_param(); + fn parse_assoc_ty_in_trait(&mut self, attrs: Vec<Attribute>) + -> P<TraitItem> { + let TyParam {id, ident, bounds, default, span} = self.parse_ty_param(); self.expect(&token::Semi); - AssociatedType { + P(TraitItem { + id: id, + ident: ident, attrs: attrs, - ty_param: ty_param, - } + node: TypeTraitItem(bounds, default), + span: span, + }) } /// Parses `type Foo = TYPE;` in an implementation declaration only. The /// `type` keyword has already been parsed. - fn parse_typedef(&mut self, attrs: Vec<Attribute>, vis: Visibility) - -> Typedef { + fn parse_assoc_ty_in_impl(&mut self, attrs: Vec<Attribute>, vis: Visibility) + -> P<ImplItem> { let lo = self.span.lo; let ident = self.parse_ident(); self.expect(&token::Eq); let typ = self.parse_ty_sum(); let hi = self.span.hi; self.expect(&token::Semi); - Typedef { + P(ImplItem { id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi), ident: ident, vis: vis, attrs: attrs, - typ: typ, - } + node: TypeImplItem(typ), + }) } /// Parse the items in a trait declaration - pub fn parse_trait_items(&mut self) -> Vec<TraitItem> { + pub fn parse_trait_items(&mut self) -> Vec<P<TraitItem>> { self.parse_unspanned_seq( &token::OpenDelim(token::Brace), &token::CloseDelim(token::Brace), seq_sep_none(), |p| { - let attrs = p.parse_outer_attributes(); + let mut attrs = p.parse_outer_attributes(); if p.eat_keyword(keywords::Type) { - TypeTraitItem(P(p.parse_associated_type(attrs))) + p.parse_assoc_ty_in_trait(attrs) } else { let lo = p.span.lo; - let vis = p.parse_visibility(); let style = p.parse_unsafety(); let abi = if p.eat_keyword(keywords::Extern) { p.parse_opt_abi().unwrap_or(abi::C) @@ -1309,44 +1308,27 @@ impl<'a> Parser<'a> { }); p.parse_where_clause(&mut generics); + let sig = ast::MethodSig { + unsafety: style, + decl: d, + generics: generics, + abi: abi, + explicit_self: explicit_self, + }; let hi = p.last_span.hi; - match p.token { + let body = match p.token { token::Semi => { p.bump(); debug!("parse_trait_methods(): parsing required method"); - RequiredMethod(TypeMethod { - ident: ident, - attrs: attrs, - unsafety: style, - decl: d, - generics: generics, - abi: abi, - explicit_self: explicit_self, - id: ast::DUMMY_NODE_ID, - span: mk_sp(lo, hi), - vis: vis, - }) + None } token::OpenDelim(token::Brace) => { debug!("parse_trait_methods(): parsing provided method"); let (inner_attrs, body) = p.parse_inner_attrs_and_block(); - let mut attrs = attrs; attrs.push_all(&inner_attrs[..]); - ProvidedMethod(P(ast::Method { - attrs: attrs, - id: ast::DUMMY_NODE_ID, - span: mk_sp(lo, hi), - node: ast::MethDecl(ident, - generics, - abi, - explicit_self, - style, - d, - body, - vis) - })) + Some(body) } _ => { @@ -1354,7 +1336,15 @@ impl<'a> Parser<'a> { p.fatal(&format!("expected `;` or `{{`, found `{}`", token_str)[..]) } - } + }; + + P(TraitItem { + id: ast::DUMMY_NODE_ID, + ident: ident, + attrs: attrs, + node: ast::MethodTraitItem(sig, body), + span: mk_sp(lo, hi), + }) } }) } @@ -4635,11 +4625,15 @@ impl<'a> Parser<'a> { (ident, ItemFn(decl, unsafety, abi, generics, body), Some(inner_attrs)) } - /// Parse a method in a trait impl - pub fn parse_method_with_outer_attributes(&mut self) -> P<Method> { + /// Parse an impl item. + pub fn parse_impl_item_with_outer_attributes(&mut self) -> P<ImplItem> { let attrs = self.parse_outer_attributes(); - let visa = self.parse_visibility(); - self.parse_method(attrs, visa) + let vis = self.parse_visibility(); + if self.eat_keyword(keywords::Type) { + self.parse_assoc_ty_in_impl(attrs, vis) + } else { + self.parse_method(attrs, vis) + } } fn complain_if_pub_macro(&mut self, visa: Visibility, span: Span) { @@ -4656,12 +4650,12 @@ impl<'a> Parser<'a> { /// Parse a method in a trait impl, starting with `attrs` attributes. pub fn parse_method(&mut self, attrs: Vec<Attribute>, - visa: Visibility) - -> P<Method> { + vis: Visibility) + -> P<ImplItem> { let lo = self.span.lo; // code copied from parse_macro_use_or_failure... abstraction! - let (method_, hi, new_attrs) = { + let (method_, hi, new_attrs, ident) = { if !self.token.is_any_keyword() && self.look_ahead(1, |t| *t == token::Not) && (self.look_ahead(2, |t| *t == token::OpenDelim(token::Paren)) @@ -4669,7 +4663,7 @@ impl<'a> Parser<'a> { // method macro. let last_span = self.last_span; - self.complain_if_pub_macro(visa, last_span); + self.complain_if_pub_macro(vis, last_span); let pth = self.parse_path(NoTypesAllowed); self.expect(&token::Not); @@ -4686,7 +4680,8 @@ impl<'a> Parser<'a> { if delim != token::Brace { self.expect(&token::Semi) } - (ast::MethMac(m), self.span.hi, attrs) + (ast::MacImplItem(m), self.span.hi, attrs, + token::special_idents::invalid) } else { let unsafety = self.parse_unsafety(); let abi = if self.eat_keyword(keywords::Extern) { @@ -4705,22 +4700,22 @@ impl<'a> Parser<'a> { let body_span = body.span; let mut new_attrs = attrs; new_attrs.push_all(&inner_attrs[..]); - (ast::MethDecl(ident, - generics, - abi, - explicit_self, - unsafety, - decl, - body, - visa), - body_span.hi, new_attrs) + (MethodImplItem(ast::MethodSig { + generics: generics, + abi: abi, + explicit_self: explicit_self, + unsafety: unsafety, + decl: decl + }, body), body_span.hi, new_attrs, ident) } }; - P(ast::Method { - attrs: new_attrs, + P(ImplItem { id: ast::DUMMY_NODE_ID, - span: mk_sp(lo, hi), + attrs: new_attrs, + vis: vis, + ident: ident, node: method_, + span: mk_sp(lo, hi), }) } @@ -4752,7 +4747,7 @@ impl<'a> Parser<'a> { (ident, ItemTrait(unsafety, tps, bounds, meths), None) } - fn parse_impl_items(&mut self) -> (Vec<ImplItem>, Vec<Attribute>) { + fn parse_impl_items(&mut self) -> (Vec<P<ImplItem>>, Vec<Attribute>) { let mut impl_items = Vec::new(); self.expect(&token::OpenDelim(token::Brace)); let (inner_attrs, mut method_attrs) = @@ -4764,15 +4759,11 @@ impl<'a> Parser<'a> { } let vis = self.parse_visibility(); - if self.eat_keyword(keywords::Type) { - impl_items.push(TypeImplItem(P(self.parse_typedef( - method_attrs, - vis)))) + impl_items.push(if self.eat_keyword(keywords::Type) { + self.parse_assoc_ty_in_impl(method_attrs, vis) } else { - impl_items.push(MethodImplItem(self.parse_method( - method_attrs, - vis))); - } + self.parse_method(method_attrs, vis) + }); method_attrs = vec![]; } (impl_items, inner_attrs) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 883c2295a36..07303ba51ff 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -12,8 +12,7 @@ pub use self::AnnNode::*; use abi; use ast; -use ast::{MethodImplItem, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; -use ast::{RequiredMethod, ProvidedMethod, TypeImplItem, TypeTraitItem}; +use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; use ast_util; use attr; use owned_slice::OwnedSlice; @@ -360,14 +359,6 @@ pub fn generics_to_string(generics: &ast::Generics) -> String { $to_string(|s| s.print_generics(generics)) } -pub fn ty_method_to_string(p: &ast::TypeMethod) -> String { - $to_string(|s| s.print_ty_method(p)) -} - -pub fn method_to_string(p: &ast::Method) -> String { - $to_string(|s| s.print_method(p)) -} - pub fn fn_block_to_string(p: &ast::FnDecl) -> String { $to_string(|s| s.print_fn_block_args(p)) } @@ -384,8 +375,9 @@ pub fn fun_to_string(decl: &ast::FnDecl, unsafety: ast::Unsafety, name: ast::Ide opt_explicit_self: Option<&ast::ExplicitSelf_>, generics: &ast::Generics) -> String { $to_string(|s| { - try!(s.print_fn(decl, Some(unsafety), abi::Rust, - name, generics, opt_explicit_self, ast::Inherited)); + try!(s.head("")); + try!(s.print_fn(decl, unsafety, abi::Rust, Some(name), + generics, opt_explicit_self, ast::Inherited)); try!(s.end()); // Close the head box s.end() // Close the outer box }) @@ -768,8 +760,10 @@ impl<'a> State<'a> { try!(self.print_outer_attributes(&item.attrs)); match item.node { ast::ForeignItemFn(ref decl, ref generics) => { - try!(self.print_fn(&**decl, None, abi::Rust, item.ident, generics, - None, item.vis)); + try!(self.head("")); + try!(self.print_fn(&**decl, ast::Unsafety::Normal, + abi::Rust, Some(item.ident), + generics, None, item.vis)); try!(self.end()); // end head-ibox try!(word(&mut self.s, ";")); self.end() // end the outer fn box @@ -790,23 +784,24 @@ impl<'a> State<'a> { } } - fn print_associated_type(&mut self, typedef: &ast::AssociatedType) - -> io::Result<()> - { - try!(self.print_outer_attributes(&typedef.attrs)); + fn print_associated_type(&mut self, + ident: ast::Ident, + bounds: Option<&ast::TyParamBounds>, + ty: Option<&ast::Ty>) + -> io::Result<()> { try!(self.word_space("type")); - try!(self.print_ty_param(&typedef.ty_param)); + try!(self.print_ident(ident)); + if let Some(bounds) = bounds { + try!(self.print_bounds(":", bounds)); + } + if let Some(ty) = ty { + try!(space(&mut self.s)); + try!(self.word_space("=")); + try!(self.print_type(ty)); + } word(&mut self.s, ";") } - fn print_typedef(&mut self, typedef: &ast::Typedef) -> io::Result<()> { - try!(self.word_space("type")); - try!(self.print_ident(typedef.ident)); - try!(space(&mut self.s)); - try!(self.word_space("=")); - try!(self.print_type(&*typedef.typ)); - word(&mut self.s, ";") - } /// Pretty-print an item pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> { @@ -869,11 +864,12 @@ impl<'a> State<'a> { try!(self.end()); // end the outer cbox } ast::ItemFn(ref decl, unsafety, abi, ref typarams, ref body) => { + try!(self.head("")); try!(self.print_fn( - &**decl, - Some(unsafety), + decl, + unsafety, abi, - item.ident, + Some(item.ident), typarams, None, item.vis @@ -977,18 +973,11 @@ impl<'a> State<'a> { try!(self.bopen()); try!(self.print_inner_attributes(&item.attrs)); for impl_item in impl_items { - match *impl_item { - ast::MethodImplItem(ref meth) => { - try!(self.print_method(&**meth)); - } - ast::TypeImplItem(ref typ) => { - try!(self.print_typedef(&**typ)); - } - } + try!(self.print_impl_item(impl_item)); } try!(self.bclose(item.span)); } - ast::ItemTrait(unsafety, ref generics, ref bounds, ref methods) => { + ast::ItemTrait(unsafety, ref generics, ref bounds, ref trait_items) => { try!(self.head("")); try!(self.print_visibility(item.vis)); try!(self.print_unsafety(unsafety)); @@ -1009,8 +998,8 @@ impl<'a> State<'a> { try!(self.print_where_clause(generics)); try!(word(&mut self.s, " ")); try!(self.bopen()); - for meth in methods { - try!(self.print_trait_method(meth)); + for trait_item in trait_items { + try!(self.print_trait_item(trait_item)); } try!(self.bclose(item.span)); } @@ -1242,60 +1231,61 @@ impl<'a> State<'a> { } } - pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> io::Result<()> { - try!(self.hardbreak_if_not_bol()); - try!(self.maybe_print_comment(m.span.lo)); - try!(self.print_outer_attributes(&m.attrs)); - try!(self.print_ty_fn(m.abi, - m.unsafety, - &*m.decl, - Some(m.ident), - &m.generics, - Some(&m.explicit_self.node))); - word(&mut self.s, ";") + pub fn print_method_sig(&mut self, + ident: ast::Ident, + m: &ast::MethodSig, + vis: ast::Visibility) + -> io::Result<()> { + self.print_fn(&m.decl, + m.unsafety, + m.abi, + Some(ident), + &m.generics, + Some(&m.explicit_self.node), + vis) } - pub fn print_trait_method(&mut self, - m: &ast::TraitItem) -> io::Result<()> { - match *m { - RequiredMethod(ref ty_m) => self.print_ty_method(ty_m), - ProvidedMethod(ref m) => self.print_method(&**m), - TypeTraitItem(ref t) => self.print_associated_type(&**t), + pub fn print_trait_item(&mut self, ti: &ast::TraitItem) + -> io::Result<()> { + try!(self.hardbreak_if_not_bol()); + try!(self.maybe_print_comment(ti.span.lo)); + try!(self.print_outer_attributes(&ti.attrs)); + match ti.node { + ast::MethodTraitItem(ref sig, ref body) => { + if body.is_some() { + try!(self.head("")); + } + try!(self.print_method_sig(ti.ident, sig, ast::Inherited)); + if let Some(ref body) = *body { + try!(self.nbsp()); + self.print_block_with_attrs(body, &ti.attrs) + } else { + word(&mut self.s, ";") + } + } + ast::TypeTraitItem(ref bounds, ref default) => { + self.print_associated_type(ti.ident, Some(bounds), + default.as_ref().map(|ty| &**ty)) + } } } pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> io::Result<()> { - match *ii { - MethodImplItem(ref m) => self.print_method(&**m), - TypeImplItem(ref td) => self.print_typedef(&**td), - } - } - - pub fn print_method(&mut self, meth: &ast::Method) -> io::Result<()> { try!(self.hardbreak_if_not_bol()); - try!(self.maybe_print_comment(meth.span.lo)); - try!(self.print_outer_attributes(&meth.attrs)); - match meth.node { - ast::MethDecl(ident, - ref generics, - abi, - ref explicit_self, - unsafety, - ref decl, - ref body, - vis) => { - try!(self.print_fn(&**decl, - Some(unsafety), - abi, - ident, - generics, - Some(&explicit_self.node), - vis)); - try!(word(&mut self.s, " ")); - self.print_block_with_attrs(&**body, &meth.attrs) - }, - ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _), - ..}) => { + try!(self.maybe_print_comment(ii.span.lo)); + try!(self.print_outer_attributes(&ii.attrs)); + match ii.node { + ast::MethodImplItem(ref sig, ref body) => { + try!(self.head("")); + try!(self.print_method_sig(ii.ident, sig, ii.vis)); + try!(self.nbsp()); + self.print_block_with_attrs(body, &ii.attrs) + } + ast::TypeImplItem(ref ty) => { + self.print_associated_type(ii.ident, None, Some(ty)) + } + ast::MacImplItem(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _), + ..}) => { // code copied from ItemMac: try!(self.print_path(pth, false, 0)); try!(word(&mut self.s, "! ")); @@ -2326,16 +2316,18 @@ impl<'a> State<'a> { pub fn print_fn(&mut self, decl: &ast::FnDecl, - unsafety: Option<ast::Unsafety>, + unsafety: ast::Unsafety, abi: abi::Abi, - name: ast::Ident, + name: Option<ast::Ident>, generics: &ast::Generics, opt_explicit_self: Option<&ast::ExplicitSelf_>, vis: ast::Visibility) -> io::Result<()> { - try!(self.head("")); try!(self.print_fn_header_info(unsafety, abi, vis)); - try!(self.nbsp()); - try!(self.print_ident(name)); + + if let Some(name) = name { + try!(self.nbsp()); + try!(self.print_ident(name)); + } try!(self.print_generics(generics)); try!(self.print_fn_args_and_ret(decl, opt_explicit_self)); self.print_where_clause(generics) @@ -2702,25 +2694,14 @@ impl<'a> State<'a> { abi: abi::Abi, unsafety: ast::Unsafety, decl: &ast::FnDecl, - id: Option<ast::Ident>, + name: Option<ast::Ident>, generics: &ast::Generics, opt_explicit_self: Option<&ast::ExplicitSelf_>) -> io::Result<()> { try!(self.ibox(indent_unit)); - try!(self.print_fn_header_info(Some(unsafety), abi, ast::Inherited)); - - match id { - Some(id) => { - try!(word(&mut self.s, " ")); - try!(self.print_ident(id)); - } - _ => () - } - - try!(self.print_generics(generics)); - try!(zerobreak(&mut self.s)); - try!(self.print_fn_args_and_ret(decl, opt_explicit_self)); - try!(self.print_where_clause(generics)); + try!(self.print_fn(decl, unsafety, abi, name, + generics, opt_explicit_self, + ast::Inherited)); self.end() } @@ -2942,14 +2923,6 @@ impl<'a> State<'a> { } } - pub fn print_opt_unsafety(&mut self, - opt_unsafety: Option<ast::Unsafety>) -> io::Result<()> { - match opt_unsafety { - Some(unsafety) => self.print_unsafety(unsafety), - None => Ok(()) - } - } - pub fn print_opt_abi_and_extern_if_nondefault(&mut self, opt_abi: Option<abi::Abi>) -> io::Result<()> { @@ -2975,11 +2948,11 @@ impl<'a> State<'a> { } pub fn print_fn_header_info(&mut self, - opt_unsafety: Option<ast::Unsafety>, + unsafety: ast::Unsafety, abi: abi::Abi, vis: ast::Visibility) -> io::Result<()> { try!(word(&mut self.s, &visibility_qualified(vis, ""))); - try!(self.print_opt_unsafety(opt_unsafety)); + try!(self.print_unsafety(unsafety)); if abi != abi::Rust { try!(self.word_nbsp("extern")); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 33d8d56b4b1..638ddd3ea2e 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -38,7 +38,7 @@ pub enum FnKind<'a> { FkItemFn(Ident, &'a Generics, Unsafety, Abi), /// fn foo(&self) - FkMethod(Ident, &'a Generics, &'a Method), + FkMethod(Ident, &'a MethodSig), /// |x, y| ... /// proc(x, y) ... @@ -77,8 +77,8 @@ pub trait Visitor<'v> : Sized { fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, _: NodeId) { walk_fn(self, fk, fd, b, s) } - fn visit_ty_method(&mut self, t: &'v TypeMethod) { walk_ty_method(self, t) } - fn visit_trait_item(&mut self, t: &'v TraitItem) { walk_trait_item(self, t) } + fn visit_trait_item(&mut self, ti: &'v TraitItem) { walk_trait_item(self, ti) } + fn visit_impl_item(&mut self, ii: &'v ImplItem) { walk_impl_item(self, ii) } fn visit_trait_ref(&mut self, t: &'v TraitRef) { walk_trait_ref(self, t) } fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) { walk_ty_param_bound(self, bounds) @@ -143,13 +143,7 @@ pub fn walk_inlined_item<'v,V>(visitor: &mut V, item: &'v InlinedItem) IIItem(ref i) => visitor.visit_item(&**i), IIForeign(ref i) => visitor.visit_foreign_item(&**i), IITraitItem(_, ref ti) => visitor.visit_trait_item(ti), - IIImplItem(_, MethodImplItem(ref m)) => { - walk_method_helper(visitor, &**m) - } - IIImplItem(_, TypeImplItem(ref typedef)) => { - visitor.visit_ident(typedef.span, typedef.ident); - visitor.visit_ty(&*typedef.typ); - } + IIImplItem(_, ref ii) => visitor.visit_impl_item(ii), } } @@ -202,8 +196,6 @@ pub fn walk_explicit_self<'v, V: Visitor<'v>>(visitor: &mut V, } } -/// Like with walk_method_helper this doesn't correspond to a method -/// in Visitor, and so it gets a _helper suffix. pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v PolyTraitRef, _modifier: &'v TraitBoundModifier) @@ -213,8 +205,6 @@ pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V, visitor.visit_trait_ref(&trait_ref.trait_ref); } -/// Like with walk_method_helper this doesn't correspond to a method -/// in Visitor, and so it gets a _helper suffix. pub fn walk_trait_ref<'v,V>(visitor: &mut V, trait_ref: &'v TraitRef) where V: Visitor<'v> @@ -294,15 +284,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { } visitor.visit_ty(&**typ); for impl_item in impl_items { - match *impl_item { - MethodImplItem(ref method) => { - walk_method_helper(visitor, &**method) - } - TypeImplItem(ref typedef) => { - visitor.visit_ident(typedef.span, typedef.ident); - visitor.visit_ty(&*typedef.typ); - } - } + visitor.visit_impl_item(impl_item); } } ItemStruct(ref struct_definition, ref generics) => { @@ -561,15 +543,11 @@ pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, } } -pub fn walk_ty_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v TyParam) { - visitor.visit_ident(param.span, param.ident); - walk_ty_param_bounds_helper(visitor, ¶m.bounds); - walk_ty_opt(visitor, ¶m.default); -} - pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) { - for type_parameter in &*generics.ty_params { - walk_ty_param(visitor, type_parameter); + for param in &*generics.ty_params { + visitor.visit_ident(param.span, param.ident); + walk_ty_param_bounds_helper(visitor, ¶m.bounds); + walk_ty_opt(visitor, ¶m.default); } walk_lifetime_decls_helper(visitor, &generics.lifetimes); for predicate in &generics.where_clause.predicates { @@ -614,28 +592,6 @@ pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: & walk_fn_ret_ty(visitor, &function_declaration.output) } -// Note: there is no visit_method() method in the visitor, instead override -// visit_fn() and check for FkMethod(). I named this visit_method_helper() -// because it is not a default impl of any method, though I doubt that really -// clarifies anything. - Niko -pub fn walk_method_helper<'v, V: Visitor<'v>>(visitor: &mut V, method: &'v Method) { - match method.node { - MethDecl(ident, ref generics, _, _, _, ref decl, ref body, _) => { - visitor.visit_ident(method.span, ident); - visitor.visit_fn(FkMethod(ident, generics, method), - &**decl, - &**body, - method.span, - method.id); - for attr in &method.attrs { - visitor.visit_attribute(attr); - } - - }, - MethMac(ref mac) => visitor.visit_mac(mac) - } -} - pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'v>, function_declaration: &'v FnDecl, @@ -647,14 +603,9 @@ pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V, FkItemFn(_, generics, _, _) => { visitor.visit_generics(generics); } - FkMethod(_, generics, method) => { - visitor.visit_generics(generics); - match method.node { - MethDecl(_, _, _, ref explicit_self, _, _, _, _) => - visitor.visit_explicit_self(explicit_self), - MethMac(ref mac) => - visitor.visit_mac(mac) - } + FkMethod(_, sig) => { + visitor.visit_generics(&sig.generics); + visitor.visit_explicit_self(&sig.explicit_self); } FkFnBlock(..) => {} } @@ -662,25 +613,43 @@ pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V, visitor.visit_block(function_body) } -pub fn walk_ty_method<'v, V: Visitor<'v>>(visitor: &mut V, method_type: &'v TypeMethod) { - visitor.visit_ident(method_type.span, method_type.ident); - visitor.visit_explicit_self(&method_type.explicit_self); - for argument_type in &method_type.decl.inputs { - visitor.visit_ty(&*argument_type.ty) - } - visitor.visit_generics(&method_type.generics); - walk_fn_ret_ty(visitor, &method_type.decl.output); - for attr in &method_type.attrs { +pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) { + visitor.visit_ident(trait_item.span, trait_item.ident); + for attr in &trait_item.attrs { visitor.visit_attribute(attr); } + match trait_item.node { + MethodTraitItem(ref sig, None) => { + visitor.visit_explicit_self(&sig.explicit_self); + visitor.visit_generics(&sig.generics); + walk_fn_decl(visitor, &sig.decl); + } + MethodTraitItem(ref sig, Some(ref body)) => { + visitor.visit_fn(FkMethod(trait_item.ident, sig), &sig.decl, + body, trait_item.span, trait_item.id); + } + TypeTraitItem(ref bounds, ref default) => { + walk_ty_param_bounds_helper(visitor, bounds); + walk_ty_opt(visitor, default); + } + } } -pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_method: &'v TraitItem) { - match *trait_method { - RequiredMethod(ref method_type) => visitor.visit_ty_method(method_type), - ProvidedMethod(ref method) => walk_method_helper(visitor, &**method), - TypeTraitItem(ref associated_type) => { - walk_ty_param(visitor, &associated_type.ty_param); +pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) { + visitor.visit_ident(impl_item.span, impl_item.ident); + for attr in &impl_item.attrs { + visitor.visit_attribute(attr); + } + match impl_item.node { + MethodImplItem(ref sig, ref body) => { + visitor.visit_fn(FkMethod(impl_item.ident, sig), &sig.decl, + body, impl_item.span, impl_item.id); + } + TypeImplItem(ref ty) => { + visitor.visit_ty(ty); + } + MacImplItem(ref mac) => { + visitor.visit_mac(mac); } } } |
