diff options
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/ast_map/blocks.rs | 28 | ||||
| -rw-r--r-- | src/libsyntax/ast_map/mod.rs | 22 | ||||
| -rw-r--r-- | src/libsyntax/ast_util.rs | 32 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic/mod.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 130 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 29 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 31 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 42 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 58 |
12 files changed, 162 insertions, 251 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 0a08b0b1207..657ffcaece9 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -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_::*; @@ -1084,8 +1083,7 @@ pub struct TraitItem { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum TraitItem_ { - RequiredMethod(MethodSig), - ProvidedMethod(Method), + MethodTraitItem(MethodSig, Option<P<Block>>), TypeTraitItem(TyParamBounds, Option<P<Ty>>), } @@ -1101,8 +1099,9 @@ pub struct ImplItem { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum ImplItem_ { - MethodImplItem(Method), + MethodImplItem(MethodSig, P<Block>), TypeImplItem(P<Ty>), + MacImplItem(Mac), } #[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Copy)] @@ -1417,14 +1416,6 @@ pub enum ExplicitSelf_ { pub type ExplicitSelf = Spanned<ExplicitSelf_>; #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum Method { - /// Represents a method declaration - MethDecl(MethodSig, P<Block>), - /// 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 diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs index 345ccf902cd..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.node { 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_sig().decl, + |_, _, sig: &'a ast::MethodSig, _, _| &sig.decl, |c: ClosureParts<'a>| c.decl) } pub fn span(self) -> Span { self.handle(|i: ItemFnParts| i.span, - |_, _, _: &'a ast::Method, span| span, + |_, _, _: &'a ast::MethodSig, _, span| span, |c: ClosureParts| c.span) } pub fn id(self) -> NodeId { self.handle(|i: ItemFnParts| i.id, - |id, _, _: &'a ast::Method, _| 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 = |_, ident, m: &'a ast::Method, _| { - visit::FkMethod(ident, 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(NodeId, ast::Ident, &'a ast::Method, Span) -> A, + M: FnOnce(NodeId, ast::Ident, &'a ast::MethodSig, &'a ast::Block, Span) -> A, C: FnOnce(ClosureParts<'a>) -> A, { match self.node { @@ -206,13 +205,18 @@ impl<'a> FnLikeNode<'a> { _ => panic!("item FnLikeNode that is not fn-like"), }, ast_map::NodeTraitItem(ti) => match ti.node { - ast::ProvidedMethod(ref m) => method(ti.id, ti.ident, m, ti.span), + 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.node { - ast::MethodImplItem(ref m) => method(ii.id, ii.ident, m, ii.span), - ast::TypeImplItem(_) => { + 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 606c6b640df..48bb044cb18 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -929,16 +929,10 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { } Some(NodeImplItem(ii)) => { match ii.node { - MethodImplItem(ref m) => { - match *m { - MethDecl(..) => - format!("method {} in {}{}", - token::get_ident(ii.ident), - map.path_to_string(id), id_str), - MethMac(ref mac) => - format!("method macro {}{}", - pprust::mac_to_string(mac), id_str) - } + MethodImplItem(..) => { + format!("method {} in {}{}", + token::get_ident(ii.ident), + map.path_to_string(id), id_str) } TypeImplItem(_) => { format!("assoc type {} in {}{}", @@ -946,13 +940,17 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { 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 { - RequiredMethod(_) => "required method", - ProvidedMethod(_) => "provided method", + MethodTraitItem(..) => "trait method", TypeTraitItem(..) => "assoc type", +// ConstTraitItem(..) => "assoc constant" }; format!("{} {} in {}{}", diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 91ddc8beec8..cec824e79ff 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -459,8 +459,8 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { visit::FkItemFn(_, generics, _, _) => { self.visit_generics_helper(generics) } - visit::FkMethod(_, m) => { - self.visit_generics_helper(&m.pe_sig().generics) + visit::FkMethod(_, sig) => { + self.visit_generics_helper(&sig.generics) } visit::FkFnBlock => {} } @@ -647,34 +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_sig<'a>(&'a self) -> &'a ast::MethodSig; - fn pe_body<'a>(&'a self) -> &'a ast::Block; -} - -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 { - $field_pat => $result, - MethMac(_) => { - panic!("expected an AST without macro invocations"); - } - } - } - } -} - - -impl PostExpansionMethod for Method { - mf_method! { pe_sig, &'a ast::MethodSig,MethDecl(ref sig, _), sig } - mf_method! { pe_body, &'a ast::Block,MethDecl(_, ref body), body } -} - #[cfg(test)] mod test { use ast::*; diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index cad5f97a4a5..35449bde0b2 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -228,8 +228,8 @@ pub trait MacResult { None } - /// Create zero or more methods. - fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> { + /// Create zero or more impl items. + fn make_impl_items(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> { None } @@ -275,7 +275,7 @@ make_MacEager! { expr: P<ast::Expr>, pat: P<ast::Pat>, items: SmallVector<P<ast::Item>>, - methods: SmallVector<P<ast::ImplItem>>, + impl_items: SmallVector<P<ast::ImplItem>>, stmt: P<ast::Stmt>, } @@ -288,8 +288,8 @@ impl MacResult for MacEager { self.items } - fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> { - 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>> { @@ -377,7 +377,7 @@ impl MacResult for DummyResult { Some(SmallVector::zero()) } } - fn make_methods(self: Box<DummyResult>) -> Option<SmallVector<P<ast::ImplItem>>> { + fn make_impl_items(self: Box<DummyResult>) -> Option<SmallVector<P<ast::ImplItem>>> { if self.expr_only { None } else { diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index d4b0f7d1dcb..58b6d96607d 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -724,13 +724,13 @@ impl<'a> MethodDef<'a> { span: trait_.span, vis: ast::Inherited, ident: method_ident, - node: ast::MethodImplItem(ast::MethDecl(ast::MethodSig { + node: ast::MethodImplItem(ast::MethodSig { generics: fn_generics, abi: abi, explicit_self: explicit_self, unsafety: ast::Unsafety::Normal, decl: fn_decl - }, body_block)) + }, body_block) }) } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index fa0b747f45b..830248b5682 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -25,7 +25,6 @@ use ext::base::*; use feature_gate::{self, Features}; use fold; use fold::*; -use owned_slice::OwnedSlice; use parse; use parse::token::{fresh_mark, fresh_name, intern}; use parse::token; @@ -1175,42 +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.node { - ast::ProvidedMethod(ast::MethMac(_)) => { - // HACK(eddyb): Expand method macros in a trait as if they were in an impl. - let ii = it.and_then(|ti| match ti.node { - ast::ProvidedMethod(m) => P(ast::ImplItem { - id: ti.id, - ident: ti.ident, - attrs: ti.attrs, - vis: ast::Inherited, - node: ast::MethodImplItem(m), - span: ti.span - }), + 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!() - }); - expand_method(ii, fld).into_iter().map(|ii| { - Annotatable::TraitItem(ii.and_then(|ii| P(ast::TraitItem { - id: ii.id, - ident: ii.ident, - attrs: ii.attrs, - node: match ii.node { - ast::MethodImplItem(m) => ast::ProvidedMethod(m), - ast::TypeImplItem(ty) => { - ast::TypeTraitItem(OwnedSlice::empty(), Some(ty)) - } - }, - span: ii.span - }))) - }).collect() - } - _ => { - fold::noop_fold_trait_item(it, fld).into_iter() - .map(|ti| Annotatable::TraitItem(ti)).collect() - } - }, + }, + span: fld.new_span(ti.span) + })), + _ => fold::noop_fold_trait_item(it, fld) + }.into_iter().map(Annotatable::TraitItem).collect(), + Annotatable::ImplItem(ii) => { - expand_method(ii, fld).into_iter().map(Annotatable::ImplItem).collect() + expand_impl_item(ii, fld).into_iter().map(Annotatable::ImplItem).collect() } }; @@ -1291,35 +1274,47 @@ fn expand_item_multi_modifier(mut it: Annotatable, expand_item_multi_modifier(it, fld) } -// expand an impl item if it's a method macro -fn expand_method(ii: P<ast::ImplItem>, fld: &mut MacroExpander) +fn expand_impl_item(ii: P<ast::ImplItem>, fld: &mut MacroExpander) -> SmallVector<P<ast::ImplItem>> { - let ii = fold::noop_fold_impl_item(ii, fld).expect_one("expected one impl item"); match ii.node { - ast::MethodImplItem(ast::MethMac(_)) => { + 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::MethodImplItem(ast::MethMac(mac)) => (ii.span, mac), + ast::MacImplItem(mac) => (ii.span, mac), _ => unreachable!() }); - let maybe_new_methods = + let maybe_new_items = expand_mac_invoc(mac, span, - |r| r.make_methods(), - |meths, mark| meths.move_map(|m| mark_method(m, mark)), + |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| expand_method(m, fld).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() } } - _ => SmallVector::one(ii) + _ => fold::noop_fold_impl_item(ii, fld) } } @@ -1328,7 +1323,7 @@ fn expand_method(ii: P<ast::ImplItem>, fld: &mut MacroExpander) /// 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 = @@ -1342,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>, @@ -1391,23 +1400,6 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { expand_arm(arm, self) } - fn fold_method(&mut self, m: ast::Method) -> ast::Method { - match m { - ast::MethDecl(sig, body) => { - let (rewritten_fn_decl, rewritten_body) - = expand_and_rename_fn_decl_and_block(sig.decl, body, self); - ast::MethDecl(ast::MethodSig { - generics: self.fold_generics(sig.generics), - abi: sig.abi, - explicit_self: self.fold_explicit_self(sig.explicit_self), - unsafety: sig.unsafety, - decl: rewritten_fn_decl - }, rewritten_body) - } - ast::MethMac(mac) => ast::MethMac(mac) - } - } - 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() @@ -1561,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(ii: P<ast::ImplItem>, m: Mrk) -> P<ast::ImplItem> { +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 method") + .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/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index dad50af9a91..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,16 +82,14 @@ impl<'a> MacResult for ParserAnyMacro<'a> { Some(ret) } - fn make_methods(self: Box<ParserAnyMacro<'a>>) - -> Option<SmallVector<P<ast::ImplItem>>> { + 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 d7982ef8399..105a61d0857 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -110,10 +110,6 @@ pub trait Folder : Sized { noop_fold_fn_decl(d, self) } - fn fold_method(&mut self, m: Method) -> Method { - noop_fold_method(m, self) - } - fn fold_block(&mut self, b: P<Block>) -> P<Block> { noop_fold_block(b, self) } @@ -977,8 +973,10 @@ pub fn noop_fold_trait_item<T: Folder>(i: P<TraitItem>, folder: &mut T) ident: folder.fold_ident(ident), attrs: fold_attrs(attrs, folder), node: match node { - RequiredMethod(sig) => RequiredMethod(noop_fold_method_sig(sig, folder)), - ProvidedMethod(m) => ProvidedMethod(folder.fold_method(m)), + 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))) @@ -996,8 +994,12 @@ pub fn noop_fold_impl_item<T: Folder>(i: P<ImplItem>, folder: &mut T) attrs: fold_attrs(attrs, folder), vis: vis, node: match node { - MethodImplItem(m) => MethodImplItem(folder.fold_method(m)), - TypeImplItem(ty) => TypeImplItem(folder.fold_ty(ty)) + 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) })) @@ -1099,17 +1101,6 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: P<ForeignItem>, folder: &mut T) -> }) } -// Default fold over a method. -pub fn noop_fold_method<T: Folder>(method: Method, folder: &mut T) -> Method { - match method { - MethDecl(sig, body) => { - MethDecl(noop_fold_method_sig(sig, folder), - folder.fold_block(body)) - }, - MethMac(mac) => MethMac(folder.fold_mac(mac)) - } -} - pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> MethodSig { MethodSig { generics: folder.fold_generics(sig.generics), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2e77bd6df18..9f851e5de19 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -13,7 +13,7 @@ pub use self::PathParsingMode::*; use abi; 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}; @@ -42,8 +42,7 @@ 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}; @@ -1349,18 +1348,18 @@ impl<'a> Parser<'a> { }; let hi = p.last_span.hi; - let node = match p.token { + let body = match p.token { token::Semi => { p.bump(); debug!("parse_trait_methods(): parsing required method"); - RequiredMethod(sig) + None } token::OpenDelim(token::Brace) => { debug!("parse_trait_methods(): parsing provided method"); let (inner_attrs, body) = p.parse_inner_attrs_and_block(); attrs.push_all(&inner_attrs[..]); - ProvidedMethod(ast::MethDecl(sig, body)) + Some(body) } _ => { @@ -1374,7 +1373,7 @@ impl<'a> Parser<'a> { id: ast::DUMMY_NODE_ID, ident: ident, attrs: attrs, - node: node, + node: ast::MethodTraitItem(sig, body), span: mk_sp(lo, hi), }) } @@ -4682,11 +4681,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<ImplItem> { + /// 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) { @@ -4733,7 +4736,7 @@ 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(); @@ -4753,7 +4756,7 @@ impl<'a> Parser<'a> { let body_span = body.span; let mut new_attrs = attrs; new_attrs.push_all(&inner_attrs[..]); - (ast::MethDecl(ast::MethodSig { + (MethodImplItem(ast::MethodSig { generics: generics, abi: abi, explicit_self: explicit_self, @@ -4767,7 +4770,7 @@ impl<'a> Parser<'a> { attrs: new_attrs, vis: vis, ident: ident, - node: MethodImplItem(method_), + node: method_, span: mk_sp(lo, hi), }) } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 20c8df42993..07303ba51ff 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1251,12 +1251,17 @@ impl<'a> State<'a> { try!(self.maybe_print_comment(ti.span.lo)); try!(self.print_outer_attributes(&ti.attrs)); match ti.node { - ast::RequiredMethod(ref sig) => { + ast::MethodTraitItem(ref sig, ref body) => { + if body.is_some() { + try!(self.head("")); + } try!(self.print_method_sig(ti.ident, sig, ast::Inherited)); - word(&mut self.s, ";") - } - ast::ProvidedMethod(ref m) => { - self.print_method(ti.ident, &ti.attrs, ast::Inherited, m) + 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), @@ -1270,30 +1275,17 @@ impl<'a> State<'a> { try!(self.maybe_print_comment(ii.span.lo)); try!(self.print_outer_attributes(&ii.attrs)); match ii.node { - ast::MethodImplItem(ref m) => { - self.print_method(ii.ident, &ii.attrs, ii.vis, m) + 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)) } - } - } - - pub fn print_method(&mut self, - ident: ast::Ident, - attrs: &[ast::Attribute], - vis: ast::Visibility, - meth: &ast::Method) - -> io::Result<()> { - match *meth { - ast::MethDecl(ref sig, ref body) => { - try!(self.head("")); - try!(self.print_method_sig(ident, sig, vis)); - try!(self.nbsp()); - self.print_block_with_attrs(&**body, attrs) - }, - ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _), - ..}) => { + 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, "! ")); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 4375e17ce0b..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 Method), + FkMethod(Ident, &'a MethodSig), /// |x, y| ... /// proc(x, y) ... @@ -592,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 -fn walk_method_helper<'v, V: Visitor<'v>>(visitor: &mut V, - id: NodeId, - ident: Ident, - span: Span, - method: &'v Method) { - match *method { - MethDecl(ref sig, ref body) => { - visitor.visit_ident(span, ident); - visitor.visit_fn(FkMethod(ident, method), - &sig.decl, - body, - span, - id); - }, - 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, @@ -625,14 +603,9 @@ pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V, FkItemFn(_, generics, _, _) => { visitor.visit_generics(generics); } - FkMethod(_, method) => { - match *method { - MethDecl(ref sig, _) => { - visitor.visit_generics(&sig.generics); - visitor.visit_explicit_self(&sig.explicit_self); - } - MethMac(ref mac) => visitor.visit_mac(mac) - } + FkMethod(_, sig) => { + visitor.visit_generics(&sig.generics); + visitor.visit_explicit_self(&sig.explicit_self); } FkFnBlock(..) => {} } @@ -646,17 +619,14 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai visitor.visit_attribute(attr); } match trait_item.node { - RequiredMethod(ref sig) => { + MethodTraitItem(ref sig, None) => { visitor.visit_explicit_self(&sig.explicit_self); visitor.visit_generics(&sig.generics); walk_fn_decl(visitor, &sig.decl); } - ProvidedMethod(ref method) => { - walk_method_helper(visitor, - trait_item.id, - trait_item.ident, - trait_item.span, - method); + 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); @@ -671,16 +641,16 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt visitor.visit_attribute(attr); } match impl_item.node { - MethodImplItem(ref method) => { - walk_method_helper(visitor, - impl_item.id, - impl_item.ident, - impl_item.span, - method); + 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); + } } } |
