diff options
| author | bors <bors@rust-lang.org> | 2014-08-14 19:11:18 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-08-14 19:11:18 +0000 |
| commit | a8c8e3f80fd0355b2bb91337c6ad0bb0a38d5485 (patch) | |
| tree | 6acf4c541c9321d8a304eb16f486b09755983c52 /src/libsyntax | |
| parent | 404978ea722c0257cc763540c93243e8a21f82ed (diff) | |
| parent | 9907fa4acc2af5b2b07d1362b3ceb29171954c58 (diff) | |
| download | rust-a8c8e3f80fd0355b2bb91337c6ad0bb0a38d5485.tar.gz rust-a8c8e3f80fd0355b2bb91337c6ad0bb0a38d5485.zip | |
auto merge of #16286 : pcwalton/rust/associated-items-groundwork, r=nikomatsakis
methods.
This paves the way to associated items by introducing an extra level of
abstraction ("impl-or-trait item") between traits/implementations and
methods. This new abstraction is encoded in the metadata and used
throughout the compiler where appropriate.
There are no functional changes; this is purely a refactoring.
r? @nick29581
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 23 | ||||
| -rw-r--r-- | src/libsyntax/ast_map/blocks.rs | 18 | ||||
| -rw-r--r-- | src/libsyntax/ast_map/mod.rs | 152 | ||||
| -rw-r--r-- | src/libsyntax/ast_util.rs | 75 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic/mod.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 25 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 40 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 29 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 33 |
9 files changed, 256 insertions, 148 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 7d9a23e91ba..1ff8ca10fff 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -767,9 +767,14 @@ pub struct TypeMethod { /// doesn't have an implementation, just a signature) or provided (meaning it /// has a default implementation). #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] -pub enum TraitMethod { - Required(TypeMethod), - Provided(Gc<Method>), +pub enum TraitItem { + RequiredMethod(TypeMethod), + ProvidedMethod(Gc<Method>), +} + +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] +pub enum ImplItem { + MethodImplItem(Gc<Method>), } #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)] @@ -1273,11 +1278,11 @@ pub enum Item_ { Option<TyParamBound>, // (optional) default bound not required for Self. // Currently, only Sized makes sense here. Vec<TraitRef> , - Vec<TraitMethod>), + Vec<TraitItem>), ItemImpl(Generics, Option<TraitRef>, // (optional) trait this impl implements P<Ty>, // self - Vec<Gc<Method>>), + Vec<ImplItem>), /// A macro invocation (which includes macro definition) ItemMac(Mac), } @@ -1311,10 +1316,16 @@ pub enum UnboxedClosureKind { #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum InlinedItem { IIItem(Gc<Item>), - IIMethod(DefId /* impl id */, bool /* is provided */, Gc<Method>), + IITraitItem(DefId /* impl id */, InlinedTraitItem), IIForeign(Gc<ForeignItem>), } +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] +pub enum InlinedTraitItem { + ProvidedInlinedTraitItem(Gc<Method>), + RequiredInlinedTraitItem(Gc<Method>), +} + #[cfg(test)] mod test { use serialize::json; diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs index 83af390c4ed..b00c6ce14b5 100644 --- a/src/libsyntax/ast_map/blocks.rs +++ b/src/libsyntax/ast_map/blocks.rs @@ -60,9 +60,9 @@ impl MaybeFnLike for ast::Item { } } -impl MaybeFnLike for ast::TraitMethod { +impl MaybeFnLike for ast::TraitItem { fn is_fn_like(&self) -> bool { - match *self { ast::Provided(_) => true, _ => false, } + match *self { ast::ProvidedMethod(_) => true, _ => false, } } } @@ -97,9 +97,9 @@ impl Code { match node { ast_map::NodeItem(item) if item.is_fn_like() => Some(FnLikeCode(new(node))), - ast_map::NodeTraitMethod(tm) if tm.is_fn_like() => + ast_map::NodeTraitItem(tm) if tm.is_fn_like() => Some(FnLikeCode(new(node))), - ast_map::NodeMethod(_) => + ast_map::NodeImplItem(_) => Some(FnLikeCode(new(node))), ast_map::NodeExpr(e) if e.is_fn_like() => Some(FnLikeCode(new(node))), @@ -200,11 +200,15 @@ impl FnLikeNode { }), _ => fail!("item FnLikeNode that is not fn-like"), }, - ast_map::NodeTraitMethod(ref t) => match **t { - ast::Provided(ref m) => method(&**m), + ast_map::NodeTraitItem(ref t) => match **t { + ast::ProvidedMethod(ref m) => method(&**m), _ => fail!("trait method FnLikeNode that is not fn-like"), }, - ast_map::NodeMethod(ref m) => method(&**m), + ast_map::NodeImplItem(ref ii) => { + match **ii { + ast::MethodImplItem(ref m) => method(&**m), + } + } ast_map::NodeExpr(ref e) => match e.node { ast::ExprFnBlock(_, ref decl, ref block) => closure(ClosureParts::new(*decl, *block, e.id, e.span)), diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index 881ee4fd8d1..78afa8441c5 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -99,8 +99,8 @@ pub fn path_to_string<PI: Iterator<PathElem>>(mut path: PI) -> String { pub enum Node { NodeItem(Gc<Item>), NodeForeignItem(Gc<ForeignItem>), - NodeTraitMethod(Gc<TraitMethod>), - NodeMethod(Gc<Method>), + NodeTraitItem(Gc<TraitItem>), + NodeImplItem(Gc<ImplItem>), NodeVariant(P<Variant>), NodeExpr(Gc<Expr>), NodeStmt(Gc<Stmt>), @@ -125,8 +125,8 @@ enum MapEntry { /// All the node types, with a parent ID. EntryItem(NodeId, Gc<Item>), EntryForeignItem(NodeId, Gc<ForeignItem>), - EntryTraitMethod(NodeId, Gc<TraitMethod>), - EntryMethod(NodeId, Gc<Method>), + EntryTraitItem(NodeId, Gc<TraitItem>), + EntryImplItem(NodeId, Gc<ImplItem>), EntryVariant(NodeId, P<Variant>), EntryExpr(NodeId, Gc<Expr>), EntryStmt(NodeId, Gc<Stmt>), @@ -144,7 +144,7 @@ enum MapEntry { struct InlinedParent { path: Vec<PathElem> , - /// Required by NodeTraitMethod and NodeMethod. + /// RequiredMethod by NodeTraitItem and NodeImplItem. def_id: DefId } @@ -153,8 +153,8 @@ impl MapEntry { Some(match *self { EntryItem(id, _) => id, EntryForeignItem(id, _) => id, - EntryTraitMethod(id, _) => id, - EntryMethod(id, _) => id, + EntryTraitItem(id, _) => id, + EntryImplItem(id, _) => id, EntryVariant(id, _) => id, EntryExpr(id, _) => id, EntryStmt(id, _) => id, @@ -172,8 +172,8 @@ impl MapEntry { Some(match *self { EntryItem(_, p) => NodeItem(p), EntryForeignItem(_, p) => NodeForeignItem(p), - EntryTraitMethod(_, p) => NodeTraitMethod(p), - EntryMethod(_, p) => NodeMethod(p), + EntryTraitItem(_, p) => NodeTraitItem(p), + EntryImplItem(_, p) => NodeImplItem(p), EntryVariant(_, p) => NodeVariant(p), EntryExpr(_, p) => NodeExpr(p), EntryStmt(_, p) => NodeStmt(p), @@ -324,13 +324,23 @@ impl Map { } } NodeForeignItem(i) => PathName(i.ident.name), - NodeMethod(m) => match m.node { - MethDecl(ident, _, _, _, _, _, _, _) => PathName(ident.name), - MethMac(_) => fail!("no path elem for {:?}", node) + NodeImplItem(ii) => { + match *ii { + MethodImplItem(ref m) => { + match m.node { + MethDecl(ident, _, _, _, _, _, _, _) => { + PathName(ident.name) + } + MethMac(_) => { + fail!("no path elem for {:?}", node) + } + } + } + } }, - NodeTraitMethod(tm) => match *tm { - Required(ref m) => PathName(m.ident.name), - Provided(m) => match m.node { + NodeTraitItem(tm) => match *tm { + RequiredMethod(ref m) => PathName(m.ident.name), + ProvidedMethod(m) => match m.node { MethDecl(ident, _, _, _, _, _, _, _) => { PathName(ident.name) } @@ -393,11 +403,15 @@ impl Map { let attrs = match node { NodeItem(ref i) => Some(i.attrs.as_slice()), NodeForeignItem(ref fi) => Some(fi.attrs.as_slice()), - NodeTraitMethod(ref tm) => match **tm { - Required(ref type_m) => Some(type_m.attrs.as_slice()), - Provided(ref m) => Some(m.attrs.as_slice()) + NodeTraitItem(ref tm) => match **tm { + RequiredMethod(ref type_m) => Some(type_m.attrs.as_slice()), + ProvidedMethod(ref m) => Some(m.attrs.as_slice()) }, - NodeMethod(ref m) => Some(m.attrs.as_slice()), + NodeImplItem(ref ii) => { + match **ii { + MethodImplItem(ref m) => Some(m.attrs.as_slice()), + } + } NodeVariant(ref v) => Some(v.node.attrs.as_slice()), // unit/tuple structs take the attributes straight from // the struct definition. @@ -428,13 +442,17 @@ impl Map { let sp = match self.find(id) { Some(NodeItem(item)) => item.span, Some(NodeForeignItem(foreign_item)) => foreign_item.span, - Some(NodeTraitMethod(trait_method)) => { + Some(NodeTraitItem(trait_method)) => { match *trait_method { - Required(ref type_method) => type_method.span, - Provided(ref method) => method.span, + RequiredMethod(ref type_method) => type_method.span, + ProvidedMethod(ref method) => method.span, + } + } + Some(NodeImplItem(ref impl_item)) => { + match **impl_item { + MethodImplItem(ref method) => method.span, } } - Some(NodeMethod(method)) => method.span, Some(NodeVariant(variant)) => variant.span, Some(NodeExpr(expr)) => expr.span, Some(NodeStmt(stmt)) => stmt.span, @@ -532,8 +550,8 @@ impl<'a,S:Str> Iterator<NodeId> for NodesMatchingSuffix<'a,S> { let (p, name) = match self.map.find_entry(idx) { Some(EntryItem(p, n)) => (p, n.name()), Some(EntryForeignItem(p, n)) => (p, n.name()), - Some(EntryTraitMethod(p, n)) => (p, n.name()), - Some(EntryMethod(p, n)) => (p, n.name()), + Some(EntryTraitItem(p, n)) => (p, n.name()), + Some(EntryImplItem(p, n)) => (p, n.name()), Some(EntryVariant(p, n)) => (p, n.name()), _ => continue, }; @@ -553,11 +571,18 @@ 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 TraitMethod { +impl Named for TraitItem { + fn name(&self) -> Name { + match *self { + RequiredMethod(ref tm) => tm.ident.name, + ProvidedMethod(m) => m.name(), + } + } +} +impl Named for ImplItem { fn name(&self) -> Name { match *self { - Required(ref tm) => tm.ident.name, - Provided(m) => m.name(), + MethodImplItem(ref m) => m.name(), } } } @@ -616,9 +641,15 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> { assert_eq!(self.parent, i.id); match i.node { - ItemImpl(_, _, _, ref ms) => { - for &m in ms.iter() { - self.insert(m.id, EntryMethod(self.parent, m)); + ItemImpl(_, _, _, ref impl_items) => { + for impl_item in impl_items.iter() { + match *impl_item { + MethodImplItem(m) => { + self.insert(m.id, + EntryImplItem(self.parent, + box(GC) *impl_item)); + } + } } } ItemEnum(ref enum_definition, _) => { @@ -649,13 +680,13 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> { for tm in methods.iter() { match *tm { - Required(ref m) => { - self.insert(m.id, EntryTraitMethod(self.parent, + RequiredMethod(ref m) => { + self.insert(m.id, EntryTraitItem(self.parent, box(GC) (*tm).clone())); } - Provided(m) => { - self.insert(m.id, EntryTraitMethod(self.parent, - box(GC) Provided(m))); + ProvidedMethod(m) => { + self.insert(m.id, EntryTraitItem(self.parent, + box(GC) ProvidedMethod(m))); } } } @@ -798,13 +829,18 @@ pub fn map_decoded_item<F: FoldOps>(map: &Map, let ii = fold(&mut cx); match ii { IIItem(_) => {} - IIMethod(impl_did, is_provided, m) => { - let entry = if is_provided { - EntryTraitMethod(cx.parent, box(GC) Provided(m)) - } else { - EntryMethod(cx.parent, m) + IITraitItem(impl_did, inlined_trait_item) => { + let (trait_item_id, entry) = match inlined_trait_item { + ProvidedInlinedTraitItem(m) => { + (m.id, + EntryTraitItem(cx.parent, box(GC) ProvidedMethod(m))) + } + RequiredInlinedTraitItem(m) => { + (m.id, + EntryImplItem(cx.parent, box(GC) MethodImplItem(m))) + } }; - cx.insert(m.id, entry); + cx.insert(trait_item_id, entry); def_id = impl_did; } IIForeign(i) => { @@ -829,8 +865,8 @@ impl<'a> NodePrinter for pprust::State<'a> { match *node { NodeItem(a) => self.print_item(&*a), NodeForeignItem(a) => self.print_foreign_item(&*a), - NodeTraitMethod(a) => self.print_trait_method(&*a), - NodeMethod(a) => self.print_method(&*a), + NodeTraitItem(a) => self.print_trait_method(&*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), @@ -870,17 +906,23 @@ fn node_id_to_string(map: &Map, id: NodeId) -> String { let path_str = map.path_to_str_with_ident(id, item.ident); format!("foreign item {} (id={})", path_str, id) } - Some(NodeMethod(m)) => match m.node { - MethDecl(ident, _, _, _, _, _, _, _) => - format!("method {} in {} (id={})", - token::get_ident(ident), - map.path_to_string(id), id), - MethMac(ref mac) => - format!("method macro {} (id={})", - pprust::mac_to_string(mac), id) - }, - Some(NodeTraitMethod(ref tm)) => { - let m = ast_util::trait_method_to_ty_method(&**tm); + Some(NodeImplItem(ref ii)) => { + match **ii { + MethodImplItem(ref m) => { + match m.node { + MethDecl(ident, _, _, _, _, _, _, _) => + format!("method {} in {} (id={})", + token::get_ident(ident), + map.path_to_string(id), id), + MethMac(ref mac) => + format!("method macro {} (id={})", + pprust::mac_to_string(mac), id) + } + } + } + } + Some(NodeTraitItem(ref tm)) => { + let m = ast_util::trait_item_to_ty_method(&**tm); format!("method {} in {} (id={})", token::get_ident(m.ident), map.path_to_string(id), id) diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index cf2b5bc4063..7689646d373 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -241,51 +241,52 @@ pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident { token::gensym_ident(pretty.as_slice()) } -/// extract a TypeMethod from a TraitMethod. if the TraitMethod is +pub fn trait_method_to_ty_method(method: &Method) -> TypeMethod { + match method.node { + MethDecl(ident, + ref generics, + abi, + explicit_self, + fn_style, + decl, + _, + vis) => { + TypeMethod { + ident: ident, + attrs: method.attrs.clone(), + fn_style: fn_style, + decl: decl, + generics: generics.clone(), + explicit_self: explicit_self, + id: method.id, + span: method.span, + vis: vis, + abi: abi, + } + }, + MethMac(_) => fail!("expected non-macro method declaration") + } +} + +/// extract a TypeMethod from a TraitItem. if the TraitItem is /// a default, pull out the useful fields to make a TypeMethod // // NB: to be used only after expansion is complete, and macros are gone. -pub fn trait_method_to_ty_method(method: &TraitMethod) -> TypeMethod { +pub fn trait_item_to_ty_method(method: &TraitItem) -> TypeMethod { match *method { - Required(ref m) => (*m).clone(), - Provided(m) => { - match m.node { - MethDecl(ident, - ref generics, - abi, - explicit_self, - fn_style, - decl, - _, - vis) => { - TypeMethod { - ident: ident, - attrs: m.attrs.clone(), - fn_style: fn_style, - decl: decl, - generics: generics.clone(), - explicit_self: explicit_self, - id: m.id, - span: m.span, - vis: vis, - abi: abi, - } - }, - MethMac(_) => fail!("expected non-macro method declaration") - } - - } + RequiredMethod(ref m) => (*m).clone(), + ProvidedMethod(ref m) => trait_method_to_ty_method(&**m), } } -pub fn split_trait_methods(trait_methods: &[TraitMethod]) +pub fn split_trait_methods(trait_methods: &[TraitItem]) -> (Vec<TypeMethod> , Vec<Gc<Method>> ) { let mut reqd = Vec::new(); let mut provd = Vec::new(); for trt_method in trait_methods.iter() { match *trt_method { - Required(ref tm) => reqd.push((*tm).clone()), - Provided(m) => provd.push(m) + RequiredMethod(ref tm) => reqd.push((*tm).clone()), + ProvidedMethod(m) => provd.push(m) } }; (reqd, provd) @@ -543,12 +544,12 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> { visit::walk_struct_def(self, struct_def, ()); } - fn visit_trait_method(&mut self, tm: &ast::TraitMethod, _: ()) { + fn visit_trait_item(&mut self, tm: &ast::TraitItem, _: ()) { match *tm { - ast::Required(ref m) => self.operation.visit_id(m.id), - ast::Provided(ref m) => self.operation.visit_id(m.id), + ast::RequiredMethod(ref m) => self.operation.visit_id(m.id), + ast::ProvidedMethod(ref m) => self.operation.visit_id(m.id), } - visit::walk_trait_method(self, tm, ()); + visit::walk_trait_item(self, tm, ()); } } diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index 5842ca4a0d5..7a8ee6d1416 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -452,8 +452,13 @@ impl<'a> TraitDef<'a> { self.span, ident, (vec!(attr)).append(self.attributes.as_slice()), - ast::ItemImpl(trait_generics, opt_trait_ref, - self_type, methods)) + ast::ItemImpl(trait_generics, + opt_trait_ref, + self_type, + methods.move_iter() + .map(|method| { + ast::MethodImplItem(method) + }).collect())) } fn expand_struct_def(&self, diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index cebe1862528..4ed2a3ed4c2 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -834,26 +834,37 @@ pub fn noop_fold_item_underscore<T: Folder>(i: &Item_, folder: &mut T) -> Item_ let struct_def = folder.fold_struct_def(*struct_def); ItemStruct(struct_def, folder.fold_generics(generics)) } - ItemImpl(ref generics, ref ifce, ty, ref methods) => { + ItemImpl(ref generics, ref ifce, ty, ref impl_items) => { ItemImpl(folder.fold_generics(generics), ifce.as_ref().map(|p| folder.fold_trait_ref(p)), folder.fold_ty(ty), - methods.iter().flat_map(|x| folder.fold_method(*x).move_iter()).collect() + impl_items.iter() + .flat_map(|impl_item| { + match *impl_item { + MethodImplItem(x) => { + folder.fold_method(x) + .move_iter() + .map(|x| MethodImplItem(x)) + } + } + }).collect() ) } ItemTrait(ref generics, ref unbound, ref traits, ref methods) => { let methods = methods.iter().flat_map(|method| { let r = match *method { - Required(ref m) => - SmallVector::one(Required(folder.fold_type_method(m))).move_iter(), - Provided(method) => { + RequiredMethod(ref m) => { + SmallVector::one(RequiredMethod( + folder.fold_type_method(m))).move_iter() + } + ProvidedMethod(method) => { // the awkward collect/iter idiom here is because // even though an iter and a map satisfy the same trait bound, // they're not actually the same type, so the method arms // don't unify. - let methods : SmallVector<ast::TraitMethod> = + let methods : SmallVector<ast::TraitItem> = folder.fold_method(method).move_iter() - .map(|m| Provided(m)).collect(); + .map(|m| ProvidedMethod(m)).collect(); methods.move_iter() } }; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f6db577a004..f272f7e1887 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -13,7 +13,7 @@ use abi; use ast::{BareFnTy, ClosureTy}; use ast::{StaticRegionTyParamBound, OtherRegionTyParamBound, TraitTyParamBound}; -use ast::{Provided, Public, FnStyle}; +use ast::{ProvidedMethod, Public, FnStyle}; use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue}; use ast::{BiBitAnd, BiBitOr, BiBitXor, Block}; use ast::{BlockCheckMode, UnBox}; @@ -33,23 +33,24 @@ use ast::{ExprVstoreUniq, Once, Many}; use ast::{FnUnboxedClosureKind, FnMutUnboxedClosureKind}; use ast::{FnOnceUnboxedClosureKind}; use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod}; -use ast::{Ident, NormalFn, Inherited, Item, Item_, ItemStatic}; +use ast::{Ident, NormalFn, Inherited, ImplItem, Item, Item_, ItemStatic}; use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl}; use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, Lit, Lit_}; use ast::{LitBool, LitChar, LitByte, LitBinary}; use ast::{LitNil, LitStr, LitInt, Local, LocalLet}; use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, Matcher, MatchNonterminal}; use ast::{MatchSeq, MatchTok, Method, MutTy, BiMul, Mutability}; +use ast::{MethodImplItem}; use ast::{NamedField, UnNeg, NoReturn, UnNot, P, Pat, PatEnum}; use ast::{PatIdent, PatLit, PatRange, PatRegion, PatStruct}; use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle}; -use ast::{BiRem, Required}; +use ast::{BiRem, RequiredMethod}; use ast::{RetStyle, Return, BiShl, BiShr, Stmt, StmtDecl}; use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField}; use ast::{StructVariantKind, BiSub}; use ast::StrStyle; use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue}; -use ast::{TokenTree, TraitMethod, TraitRef, TTDelim, TTSeq, TTTok}; +use ast::{TokenTree, TraitItem, TraitRef, TTDelim, TTSeq, TTTok}; use ast::{TTNonterminal, TupleVariantKind, Ty, Ty_, TyBot, TyBox}; use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn}; use ast::{TyTypeof, TyInfer, TypeMethod}; @@ -1238,7 +1239,7 @@ impl<'a> Parser<'a> { } /// Parse the methods in a trait declaration - pub fn parse_trait_methods(&mut self) -> Vec<TraitMethod> { + pub fn parse_trait_methods(&mut self) -> Vec<TraitItem> { self.parse_unspanned_seq( &token::LBRACE, &token::RBRACE, @@ -1276,7 +1277,7 @@ impl<'a> Parser<'a> { token::SEMI => { p.bump(); debug!("parse_trait_methods(): parsing required method"); - Required(TypeMethod { + RequiredMethod(TypeMethod { ident: ident, attrs: attrs, fn_style: style, @@ -1294,7 +1295,7 @@ impl<'a> Parser<'a> { let (inner_attrs, body) = p.parse_inner_attrs_and_block(); let attrs = attrs.append(inner_attrs.as_slice()); - Provided(box(GC) ast::Method { + ProvidedMethod(box(GC) ast::Method { attrs: attrs, id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi), @@ -4243,6 +4244,18 @@ impl<'a> Parser<'a> { (ident, ItemTrait(tps, sized, traits, meths), None) } + fn parse_impl_items(&mut self) -> (Vec<ImplItem>, Vec<Attribute>) { + let mut impl_items = Vec::new(); + self.expect(&token::LBRACE); + let (inner_attrs, next) = self.parse_inner_attrs_and_next(); + let mut method_attrs = Some(next); + while !self.eat(&token::RBRACE) { + impl_items.push(MethodImplItem(self.parse_method(method_attrs))); + method_attrs = None; + } + (impl_items, inner_attrs) + } + /// Parses two variants (with the region/type params always optional): /// impl<T> Foo { ... } /// impl<T> ToString for ~[T] { ... } @@ -4284,18 +4297,13 @@ impl<'a> Parser<'a> { None }; - let mut meths = Vec::new(); - self.expect(&token::LBRACE); - let (inner_attrs, next) = self.parse_inner_attrs_and_next(); - let mut method_attrs = Some(next); - while !self.eat(&token::RBRACE) { - meths.push(self.parse_method(method_attrs)); - method_attrs = None; - } + let (impl_items, attrs) = self.parse_impl_items(); let ident = ast_util::impl_pretty_name(&opt_trait, &*ty); - (ident, ItemImpl(generics, opt_trait, ty, meths), Some(inner_attrs)) + (ident, + ItemImpl(generics, opt_trait, ty, impl_items), + Some(attrs)) } /// Parse a::B<String,int> diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 4ee73406f03..c573cc0c0ad 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -10,9 +10,9 @@ use abi; use ast::{FnMutUnboxedClosureKind, FnOnceUnboxedClosureKind}; -use ast::{FnUnboxedClosureKind, P, OtherRegionTyParamBound}; +use ast::{FnUnboxedClosureKind, MethodImplItem, P, OtherRegionTyParamBound}; use ast::{StaticRegionTyParamBound, TraitTyParamBound, UnboxedClosureKind}; -use ast::{UnboxedFnTyParamBound, Required, Provided}; +use ast::{UnboxedFnTyParamBound, RequiredMethod, ProvidedMethod}; use ast; use ast_util; use owned_slice::OwnedSlice; @@ -787,7 +787,10 @@ impl<'a> State<'a> { item.span)); } - ast::ItemImpl(ref generics, ref opt_trait, ref ty, ref methods) => { + ast::ItemImpl(ref generics, + ref opt_trait, + ref ty, + ref impl_items) => { try!(self.head(visibility_qualified(item.vis, "impl").as_slice())); if generics.is_parameterized() { @@ -809,8 +812,12 @@ impl<'a> State<'a> { try!(space(&mut self.s)); try!(self.bopen()); try!(self.print_inner_attributes(item.attrs.as_slice())); - for meth in methods.iter() { - try!(self.print_method(&**meth)); + for impl_item in impl_items.iter() { + match *impl_item { + ast::MethodImplItem(meth) => { + try!(self.print_method(&*meth)); + } + } } try!(self.bclose(item.span)); } @@ -1061,10 +1068,16 @@ impl<'a> State<'a> { } pub fn print_trait_method(&mut self, - m: &ast::TraitMethod) -> IoResult<()> { + m: &ast::TraitItem) -> IoResult<()> { match *m { - Required(ref ty_m) => self.print_ty_method(ty_m), - Provided(ref m) => self.print_method(&**m) + RequiredMethod(ref ty_m) => self.print_ty_method(ty_m), + ProvidedMethod(ref m) => self.print_method(&**m) + } + } + + pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> IoResult<()> { + match *ii { + MethodImplItem(ref m) => self.print_method(&**m), } } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 79a870422a6..18cbf797d03 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -99,7 +99,7 @@ pub trait Visitor<E: Clone> { walk_fn(self, fk, fd, b, s, e) } fn visit_ty_method(&mut self, t: &TypeMethod, e: E) { walk_ty_method(self, t, e) } - fn visit_trait_method(&mut self, t: &TraitMethod, e: E) { walk_trait_method(self, t, e) } + fn visit_trait_item(&mut self, t: &TraitItem, e: E) { walk_trait_item(self, t, e) } fn visit_struct_def(&mut self, s: &StructDef, _: Ident, _: &Generics, _: NodeId, e: E) { walk_struct_def(self, s, e) } @@ -148,7 +148,16 @@ pub fn walk_inlined_item<E: Clone, V: Visitor<E>>(visitor: &mut V, match *item { IIItem(i) => visitor.visit_item(&*i, env), IIForeign(i) => visitor.visit_foreign_item(&*i, env), - IIMethod(_, _, m) => walk_method_helper(visitor, &*m, env), + IITraitItem(_, iti) => { + match iti { + ProvidedInlinedTraitItem(m) => { + walk_method_helper(visitor, &*m, env) + } + RequiredInlinedTraitItem(m) => { + walk_method_helper(visitor, &*m, env) + } + } + } } } @@ -269,7 +278,7 @@ pub fn walk_item<E: Clone, V: Visitor<E>>(visitor: &mut V, item: &Item, env: E) ItemImpl(ref type_parameters, ref trait_reference, typ, - ref methods) => { + ref impl_items) => { visitor.visit_generics(type_parameters, env.clone()); match *trait_reference { Some(ref trait_reference) => walk_trait_ref_helper(visitor, @@ -277,8 +286,12 @@ pub fn walk_item<E: Clone, V: Visitor<E>>(visitor: &mut V, item: &Item, env: E) None => () } visitor.visit_ty(&*typ, env.clone()); - for method in methods.iter() { - walk_method_helper(visitor, &**method, env.clone()) + for impl_item in impl_items.iter() { + match *impl_item { + MethodImplItem(method) => { + walk_method_helper(visitor, &*method, env.clone()) + } + } } } ItemStruct(ref struct_definition, ref generics) => { @@ -297,7 +310,7 @@ pub fn walk_item<E: Clone, V: Visitor<E>>(visitor: &mut V, item: &Item, env: E) env.clone()) } for method in methods.iter() { - visitor.visit_trait_method(method, env.clone()) + visitor.visit_trait_item(method, env.clone()) } } ItemMac(ref macro) => visitor.visit_mac(macro, env.clone()), @@ -626,14 +639,14 @@ pub fn walk_ty_method<E: Clone, V: Visitor<E>>(visitor: &mut V, } } -pub fn walk_trait_method<E: Clone, V: Visitor<E>>(visitor: &mut V, - trait_method: &TraitMethod, +pub fn walk_trait_item<E: Clone, V: Visitor<E>>(visitor: &mut V, + trait_method: &TraitItem, env: E) { match *trait_method { - Required(ref method_type) => { + RequiredMethod(ref method_type) => { visitor.visit_ty_method(method_type, env) } - Provided(ref method) => walk_method_helper(visitor, &**method, env), + ProvidedMethod(ref method) => walk_method_helper(visitor, &**method, env), } } |
