From f98b1763140e4c9b0f122bde2f5cbd24227554a2 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Tue, 10 Mar 2015 12:28:44 +0200 Subject: [PATCH] syntax: gather common fields of impl & trait items into their respective types. --- src/librustc/lint/context.rs | 41 ++- src/librustc/lint/mod.rs | 2 +- src/librustc/metadata/encoder.rs | 59 ++-- src/librustc/middle/astencode.rs | 63 +---- src/librustc/middle/dead.rs | 57 ++-- src/librustc/middle/effect.rs | 2 +- src/librustc/middle/infer/error_reporting.rs | 20 +- src/librustc/middle/reachable.rs | 25 +- src/librustc/middle/resolve_lifetime.rs | 21 +- src/librustc/middle/stability.rs | 49 +--- src/librustc/middle/ty.rs | 20 +- src/librustc/util/ppaux.rs | 14 +- src/librustc_back/svh.rs | 12 +- src/librustc_borrowck/borrowck/fragments.rs | 22 +- src/librustc_lint/builtin.rs | 127 ++++----- src/librustc_privacy/lib.rs | 118 +++----- src/librustc_resolve/build_reduced_graph.rs | 54 ++-- src/librustc_resolve/lib.rs | 35 ++- src/librustc_trans/save/mod.rs | 122 ++++----- src/librustc_trans/trans/base.rs | 79 +++--- src/librustc_trans/trans/debuginfo.rs | 24 +- src/librustc_trans/trans/inline.rs | 70 ++--- src/librustc_trans/trans/meth.rs | 36 +-- src/librustc_trans/trans/monomorphize.rs | 16 +- src/librustc_typeck/astconv.rs | 11 +- src/librustc_typeck/check/mod.rs | 62 ++--- src/librustc_typeck/check/wf.rs | 32 +-- src/librustc_typeck/coherence/mod.rs | 24 +- src/librustc_typeck/collect.rs | 226 ++++++++-------- src/librustdoc/clean/inline.rs | 18 +- src/librustdoc/clean/mod.rs | 208 +++++--------- src/librustdoc/fold.rs | 28 +- src/librustdoc/html/render.rs | 52 ++-- src/librustdoc/stability_summary.rs | 34 +-- src/libsyntax/ast.rs | 66 ++--- src/libsyntax/ast_map/blocks.rs | 24 +- src/libsyntax/ast_map/mod.rs | 253 +++++------------- src/libsyntax/ast_util.rs | 39 ++- src/libsyntax/config.rs | 23 +- src/libsyntax/ext/base.rs | 50 ++-- src/libsyntax/ext/deriving/generic/mod.rs | 46 ++-- src/libsyntax/ext/expand.rs | 145 +++++----- src/libsyntax/ext/quote.rs | 11 - src/libsyntax/ext/tt/macro_rules.rs | 3 +- src/libsyntax/fold.rs | 165 ++++-------- src/libsyntax/parse/parser.rs | 121 ++++----- src/libsyntax/print/pprust.rs | 115 ++++---- src/libsyntax/visit.rs | 127 +++++---- src/test/auxiliary/macro_crate_test.rs | 11 +- src/test/compile-fail/lint-missing-doc.rs | 4 +- src/test/compile-fail/unnecessary-private.rs | 2 +- src/test/compile-fail/useless-priv.rs | 5 +- src/test/parse-fail/issue-21153.rs | 2 +- .../trait-pub-assoc-ty.rs} | 9 +- src/test/parse-fail/trait-pub-method.rs | 15 ++ src/test/run-pass-fulldeps/quote-tokens.rs | 3 - 56 files changed, 1179 insertions(+), 1843 deletions(-) rename src/test/{compile-fail/useless-priv2.rs => parse-fail/trait-pub-assoc-ty.rs} (64%) create mode 100644 src/test/parse-fail/trait-pub-method.rs diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index a777e1f7f75e6..9aa6395b7b278 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -519,28 +519,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> { fn visit_fn(&mut self, fk: FnKind<'v>, decl: &'v ast::FnDecl, body: &'v ast::Block, span: Span, id: ast::NodeId) { - match fk { - visit::FkMethod(_, _, m) => { - self.with_lint_attrs(&m.attrs, |cx| { - run_lints!(cx, check_fn, fk, decl, body, span, id); - cx.visit_ids(|v| { - v.visit_fn(fk, decl, body, span, id); - }); - visit::walk_fn(cx, fk, decl, body, span); - }) - }, - _ => { - run_lints!(self, check_fn, fk, decl, body, span, id); - visit::walk_fn(self, fk, decl, body, span); - } - } - } - - fn visit_ty_method(&mut self, t: &ast::TypeMethod) { - self.with_lint_attrs(&t.attrs, |cx| { - run_lints!(cx, check_ty_method, t); - visit::walk_ty_method(cx, t); - }) + run_lints!(self, check_fn, fk, decl, body, span, id); + visit::walk_fn(self, fk, decl, body, span); } fn visit_struct_def(&mut self, @@ -611,9 +591,20 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> { visit::walk_generics(self, g); } - fn visit_trait_item(&mut self, m: &ast::TraitItem) { - run_lints!(self, check_trait_item, m); - visit::walk_trait_item(self, m); + fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) { + self.with_lint_attrs(&trait_item.attrs, |cx| { + run_lints!(cx, check_trait_item, trait_item); + cx.visit_ids(|v| v.visit_trait_item(trait_item)); + visit::walk_trait_item(cx, trait_item); + }); + } + + fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) { + self.with_lint_attrs(&impl_item.attrs, |cx| { + run_lints!(cx, check_impl_item, impl_item); + cx.visit_ids(|v| v.visit_impl_item(impl_item)); + visit::walk_impl_item(cx, impl_item); + }); } fn visit_opt_lifetime_ref(&mut self, sp: Span, lt: &Option) { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 506d20133bdc7..23f9cbc3a4b9c 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -143,8 +143,8 @@ pub trait LintPass { fn check_generics(&mut self, _: &Context, _: &ast::Generics) { } fn check_fn(&mut self, _: &Context, _: FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId) { } - fn check_ty_method(&mut self, _: &Context, _: &ast::TypeMethod) { } fn check_trait_item(&mut self, _: &Context, _: &ast::TraitItem) { } + fn check_impl_item(&mut self, _: &Context, _: &ast::ImplItem) { } fn check_struct_def(&mut self, _: &Context, _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { } fn check_struct_def_post(&mut self, _: &Context, diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 44c01eba2ce5e..0c220ab8766d2 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -808,7 +808,7 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, impl_path: PathElems, is_default_impl: bool, parent_id: NodeId, - ast_item_opt: Option<&ast::ImplItem>) { + impl_item_opt: Option<&ast::ImplItem>) { debug!("encode_info_for_method: {:?} {:?}", m.def_id, token::get_name(m.name)); @@ -826,21 +826,20 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, let elem = ast_map::PathName(m.name); encode_path(rbml_w, impl_path.chain(Some(elem).into_iter())); - match ast_item_opt { - Some(&ast::MethodImplItem(ref ast_method)) => { - encode_attributes(rbml_w, &ast_method.attrs); + if let Some(impl_item) = impl_item_opt { + if let ast::MethodImplItem(ref ast_method) = impl_item.node { + encode_attributes(rbml_w, &impl_item.attrs); let scheme = ty::lookup_item_type(ecx.tcx, m.def_id); let any_types = !scheme.generics.types.is_empty(); - if any_types || is_default_impl || attr::requests_inline(&ast_method.attrs) { + if any_types || is_default_impl || attr::requests_inline(&impl_item.attrs) { encode_inlined_item(ecx, rbml_w, IIImplItemRef(local_def(parent_id), - ast_item_opt.unwrap())); + impl_item)); } if !any_types { encode_symbol(ecx, rbml_w, m.def_id.node); } encode_method_argument_names(rbml_w, ast_method.pe_fn_decl()); } - Some(_) | None => {} } rbml_w.end_tag(); @@ -851,7 +850,7 @@ fn encode_info_for_associated_type(ecx: &EncodeContext, associated_type: &ty::AssociatedType, impl_path: PathElems, parent_id: NodeId, - typedef_opt: Option<&ast::Typedef>) { + impl_item_opt: Option<&ast::ImplItem>) { debug!("encode_info_for_associated_type({:?},{:?})", associated_type.def_id, token::get_name(associated_type.name)); @@ -873,9 +872,9 @@ fn encode_info_for_associated_type(ecx: &EncodeContext, let elem = ast_map::PathName(associated_type.name); encode_path(rbml_w, impl_path.chain(Some(elem).into_iter())); - if let Some(typedef) = typedef_opt { - encode_attributes(rbml_w, &typedef.attrs); - encode_type(ecx, rbml_w, ty::node_id_to_type(ecx.tcx, typedef.id)); + if let Some(ii) = impl_item_opt { + encode_attributes(rbml_w, &ii.attrs); + encode_type(ecx, rbml_w, ty::node_id_to_type(ecx.tcx, ii.id)); } rbml_w.end_tag(); @@ -1232,11 +1231,8 @@ fn encode_info_for_item(ecx: &EncodeContext, pos: rbml_w.mark_stable_position(), }); - let trait_item_type = - ty::impl_or_trait_item(tcx, trait_item_def_id.def_id()); - match (trait_item_type, ast_item) { - (ty::MethodTraitItem(ref method_type), - Some(&ast::MethodImplItem(_))) => { + match ty::impl_or_trait_item(tcx, trait_item_def_id.def_id()) { + ty::MethodTraitItem(ref method_type) => { encode_info_for_method(ecx, rbml_w, &**method_type, @@ -1245,31 +1241,13 @@ fn encode_info_for_item(ecx: &EncodeContext, item.id, ast_item) } - (ty::MethodTraitItem(ref method_type), _) => { - encode_info_for_method(ecx, - rbml_w, - &**method_type, - path.clone(), - false, - item.id, - None) - } - (ty::TypeTraitItem(ref associated_type), - Some(&ast::TypeImplItem(ref typedef))) => { - encode_info_for_associated_type(ecx, - rbml_w, - &**associated_type, - path.clone(), - item.id, - Some(typedef)) - } - (ty::TypeTraitItem(ref associated_type), _) => { + ty::TypeTraitItem(ref associated_type) => { encode_info_for_associated_type(ecx, rbml_w, &**associated_type, path.clone(), item.id, - None) + ast_item) } } } @@ -1393,25 +1371,22 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_bounds_and_type_for_item(rbml_w, ecx, item_def_id.def_id().local_id()); } }; - match *trait_item { + encode_attributes(rbml_w, &trait_item.attrs); + match trait_item.node { ast::RequiredMethod(ref m) => { - encode_attributes(rbml_w, &m.attrs); encode_trait_item(rbml_w); encode_item_sort(rbml_w, 'r'); encode_method_argument_names(rbml_w, &*m.decl); } ast::ProvidedMethod(ref m) => { - encode_attributes(rbml_w, &m.attrs); encode_trait_item(rbml_w); encode_item_sort(rbml_w, 'p'); encode_inlined_item(ecx, rbml_w, IITraitItemRef(def_id, trait_item)); encode_method_argument_names(rbml_w, &*m.pe_fn_decl()); } - ast::TypeTraitItem(ref associated_type) => { - encode_attributes(rbml_w, - &associated_type.attrs); + ast::TypeTraitItem(..) => { encode_item_sort(rbml_w, 't'); } } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 20b0307f47a32..fb5b934c2cd8d 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -32,7 +32,6 @@ use middle::ty::{self, Ty, MethodCall, MethodCallee, MethodOrigin}; use util::ppaux::ty_to_string; use syntax::{ast, ast_map, ast_util, codemap, fold}; -use syntax::ast_util::PostExpansionMethod; use syntax::codemap::Span; use syntax::fold::Folder; use syntax::parse::token; @@ -81,11 +80,8 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext, let id = match ii { e::IIItemRef(i) => i.id, e::IIForeignRef(i) => i.id, - e::IITraitItemRef(_, &ast::ProvidedMethod(ref m)) => m.id, - e::IITraitItemRef(_, &ast::RequiredMethod(ref m)) => m.id, - e::IITraitItemRef(_, &ast::TypeTraitItem(ref ti)) => ti.ty_param.id, - e::IIImplItemRef(_, &ast::MethodImplItem(ref m)) => m.id, - e::IIImplItemRef(_, &ast::TypeImplItem(ref ti)) => ti.id, + e::IITraitItemRef(_, ti) => ti.id, + e::IIImplItemRef(_, ii) => ii.id, }; debug!("> Encoding inlined item: {} ({:?})", ecx.tcx.map.path_to_string(id), @@ -157,19 +153,8 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata, let ident = match *ii { ast::IIItem(ref i) => i.ident, ast::IIForeign(ref i) => i.ident, - ast::IITraitItem(_, ref ti) => { - match *ti { - ast::ProvidedMethod(ref m) => m.pe_ident(), - ast::RequiredMethod(ref ty_m) => ty_m.ident, - ast::TypeTraitItem(ref ti) => ti.ty_param.ident, - } - }, - ast::IIImplItem(_, ref m) => { - match *m { - ast::MethodImplItem(ref m) => m.pe_ident(), - ast::TypeImplItem(ref ti) => ti.ident, - } - } + ast::IITraitItem(_, ref ti) => ti.ident, + ast::IIImplItem(_, ref ii) => ii.ident }; debug!("Fn named: {}", token::get_ident(ident)); debug!("< Decoded inlined fn: {}::{}", @@ -412,38 +397,16 @@ fn simplify_ast(ii: e::InlinedItemRef) -> ast::InlinedItem { .expect_one("expected one item")) } e::IITraitItemRef(d, ti) => { - ast::IITraitItem(d, match *ti { - ast::ProvidedMethod(ref m) => { - ast::ProvidedMethod( - fold::noop_fold_method(m.clone(), &mut fld) - .expect_one("noop_fold_method must produce \ - exactly one method")) - } - ast::RequiredMethod(ref ty_m) => { - ast::RequiredMethod( - fold::noop_fold_type_method(ty_m.clone(), &mut fld)) - } - ast::TypeTraitItem(ref associated_type) => { - ast::TypeTraitItem( - fold::noop_fold_associated_type( - (*associated_type).clone(), - &mut fld)) - } - }) + ast::IITraitItem(d, + fold::noop_fold_trait_item(P(ti.clone()), &mut fld) + .expect_one("noop_fold_trait_item must produce \ + exactly one trait item")) } - e::IIImplItemRef(d, m) => { - ast::IIImplItem(d, match *m { - ast::MethodImplItem(ref m) => { - ast::MethodImplItem( - fold::noop_fold_method(m.clone(), &mut fld) - .expect_one("noop_fold_method must produce \ - exactly one method")) - } - ast::TypeImplItem(ref td) => { - ast::TypeImplItem( - fold::noop_fold_typedef((*td).clone(), &mut fld)) - } - }) + e::IIImplItemRef(d, ii) => { + ast::IIImplItem(d, + fold::noop_fold_impl_item(P(ii.clone()), &mut fld) + .expect_one("noop_fold_impl_item must produce \ + exactly one impl item")) } e::IIForeignRef(i) => { ast::IIForeign(fold::noop_fold_foreign_item(P(i.clone()), &mut fld)) diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 37cb23ff4f030..6517378c75cd1 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -228,16 +228,11 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { _ => () } } - ast_map::NodeTraitItem(trait_method) => { - visit::walk_trait_item(self, trait_method); + ast_map::NodeTraitItem(trait_item) => { + visit::walk_trait_item(self, trait_item); } ast_map::NodeImplItem(impl_item) => { - match *impl_item { - ast::MethodImplItem(ref method) => { - visit::walk_method_helper(self, method); - } - ast::TypeImplItem(_) => {} - } + visit::walk_impl_item(self, impl_item); } ast_map::NodeForeignItem(foreign_item) => { visit::walk_foreign_item(self, &*foreign_item); @@ -355,11 +350,26 @@ impl<'v> Visitor<'v> for LifeSeeder { ast::ItemEnum(ref enum_def, _) if allow_dead_code => { self.worklist.extend(enum_def.variants.iter().map(|variant| variant.node.id)); } - ast::ItemImpl(_, _, _, Some(ref _trait_ref), _, ref impl_items) => { + ast::ItemTrait(_, _, _, ref trait_items) => { + for trait_item in trait_items { + match trait_item.node { + ast::ProvidedMethod(_) => { + if has_allow_dead_code_or_lang_attr(&trait_item.attrs) { + self.worklist.push(trait_item.id); + } + } + _ => {} + } + } + } + ast::ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => { for impl_item in impl_items { - match **impl_item { - ast::MethodImplItem(ref method) => { - self.worklist.push(method.id); + match impl_item.node { + ast::MethodImplItem(_) => { + if opt_trait.is_some() || + has_allow_dead_code_or_lang_attr(&impl_item.attrs) { + self.worklist.push(impl_item.id); + } } ast::TypeImplItem(_) => {} } @@ -369,21 +379,6 @@ impl<'v> Visitor<'v> for LifeSeeder { } visit::walk_item(self, item); } - - fn visit_fn(&mut self, fk: visit::FnKind<'v>, - _: &'v ast::FnDecl, block: &'v ast::Block, - _: codemap::Span, id: ast::NodeId) { - // Check for method here because methods are not ast::Item - match fk { - visit::FkMethod(_, _, method) => { - if has_allow_dead_code_or_lang_attr(&method.attrs) { - self.worklist.push(id); - } - } - _ => () - } - visit::walk_block(self, block); - } } fn create_and_seed_worklist(tcx: &ty::ctxt, @@ -561,7 +556,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> { span: codemap::Span, id: ast::NodeId) { // Have to warn method here because methods are not ast::Item match fk { - visit::FkMethod(name, _, _) => { + visit::FkMethod(name, _) => { if !self.symbol_is_live(id, None) { self.warn_dead_code(id, span, name, "method"); } @@ -582,12 +577,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> { // Overwrite so that we don't warn the trait method itself. fn visit_trait_item(&mut self, trait_method: &ast::TraitItem) { - match *trait_method { + match trait_method.node { ast::ProvidedMethod(ref method) => { - visit::walk_block(self, &*method.pe_body()) + visit::walk_block(self, method.pe_body()) } ast::RequiredMethod(_) | - ast::TypeTraitItem(_) => {} + ast::TypeTraitItem(..) => {} } } } diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 9c85b7748ab0c..5b5e5b6555b91 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -90,7 +90,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { let (is_item_fn, is_unsafe_fn) = match fn_kind { visit::FkItemFn(_, _, fn_style, _) => (true, fn_style == ast::Unsafety::Unsafe), - visit::FkMethod(_, _, method) => + visit::FkMethod(_, method) => (true, method.pe_unsafety() == ast::Unsafety::Unsafe), _ => (false, false), }; diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index a7f5c2c843711..cf3715bc3fbe8 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -846,28 +846,28 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { _ => None } } - ast_map::NodeImplItem(ref item) => { - match **item { + ast_map::NodeImplItem(item) => { + match item.node { ast::MethodImplItem(ref m) => { Some((m.pe_fn_decl(), m.pe_generics(), m.pe_unsafety(), - m.pe_ident(), + item.ident, Some(&m.pe_explicit_self().node), - m.span)) + item.span)) } ast::TypeImplItem(_) => None, } }, - ast_map::NodeTraitItem(ref item) => { - match **item { + ast_map::NodeTraitItem(item) => { + match item.node { ast::ProvidedMethod(ref m) => { Some((m.pe_fn_decl(), m.pe_generics(), m.pe_unsafety(), - m.pe_ident(), + item.ident, Some(&m.pe_explicit_self().node), - m.span)) + item.span)) } _ => None } @@ -1730,10 +1730,10 @@ fn lifetimes_in_scope(tcx: &ty::ctxt, _ => None }, ast_map::NodeImplItem(ii) => { - match *ii { + match ii.node { ast::MethodImplItem(ref m) => { taken.push_all(&m.pe_generics().lifetimes); - Some(m.id) + Some(ii.id) } ast::TypeImplItem(_) => None, } diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 35f904c2ee841..fd6b28fd2922f 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -54,8 +54,9 @@ fn item_might_be_inlined(item: &ast::Item) -> bool { } fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method, + impl_item: &ast::ImplItem, impl_src: ast::DefId) -> bool { - if attr::requests_inline(&method.attrs) || + if attr::requests_inline(&impl_item.attrs) || generics_require_inlining(method.pe_generics()) { return true } @@ -66,13 +67,13 @@ fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method, item_might_be_inlined(&*item) } Some(..) | None => { - tcx.sess.span_bug(method.span, "impl did is not an item") + tcx.sess.span_bug(impl_item.span, "impl did is not an item") } } } } else { - tcx.sess.span_bug(method.span, "found a foreign impl as a parent of a \ - local method") + tcx.sess.span_bug(impl_item.span, "found a foreign impl as a parent \ + of a local method") } } @@ -181,17 +182,17 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { } } Some(ast_map::NodeTraitItem(trait_method)) => { - match *trait_method { + match trait_method.node { ast::RequiredMethod(_) => false, ast::ProvidedMethod(_) => true, - ast::TypeTraitItem(_) => false, + ast::TypeTraitItem(..) => false, } } Some(ast_map::NodeImplItem(impl_item)) => { - match *impl_item { + match impl_item.node { ast::MethodImplItem(ref method) => { if generics_require_inlining(method.pe_generics()) || - attr::requests_inline(&method.attrs) { + attr::requests_inline(&impl_item.attrs) { true } else { let impl_did = self.tcx @@ -301,21 +302,21 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { } } ast_map::NodeTraitItem(trait_method) => { - match *trait_method { + match trait_method.node { ast::RequiredMethod(..) => { // Keep going, nothing to get exported } ast::ProvidedMethod(ref method) => { visit::walk_block(self, &*method.pe_body()); } - ast::TypeTraitItem(_) => {} + ast::TypeTraitItem(..) => {} } } ast_map::NodeImplItem(impl_item) => { - match *impl_item { + match impl_item.node { ast::MethodImplItem(ref method) => { let did = self.tcx.map.get_parent_did(search_item); - if method_might_be_inlined(self.tcx, method, did) { + if method_might_be_inlined(self.tcx, method, impl_item, did) { visit::walk_block(self, method.pe_body()) } } diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index a8a2887644a9d..e02f786128565 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -25,6 +25,7 @@ use middle::subst; use middle::ty; use std::fmt; use syntax::ast; +use syntax::ast_util::PostExpansionMethod; use syntax::codemap::Span; use syntax::parse::token::special_idents; use syntax::parse::token; @@ -142,12 +143,16 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl, b: &'v ast::Block, s: Span, _: ast::NodeId) { match fk { - visit::FkItemFn(_, generics, _, _) | - visit::FkMethod(_, generics, _) => { + visit::FkItemFn(_, generics, _, _) => { self.visit_early_late(subst::FnSpace, generics, |this| { visit::walk_fn(this, fk, fd, b, s) }) } + visit::FkMethod(_, m) => { + self.visit_early_late(subst::FnSpace, m.pe_generics(), |this| { + visit::walk_fn(this, fk, fd, b, s) + }) + } visit::FkFnBlock(..) => { visit::walk_fn(self, fk, fd, b, s) } @@ -185,10 +190,14 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { } } - fn visit_ty_method(&mut self, m: &ast::TypeMethod) { - self.visit_early_late( - subst::FnSpace, &m.generics, - |this| visit::walk_ty_method(this, m)) + fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) { + if let ast::RequiredMethod(ref m) = trait_item.node { + self.visit_early_late( + subst::FnSpace, &m.generics, + |this| visit::walk_trait_item(this, trait_item)) + } else { + visit::walk_trait_item(self, trait_item); + } } fn visit_block(&mut self, b: &ast::Block) { diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index d1a02ff82e544..01766b0de085f 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -22,10 +22,10 @@ use syntax::codemap::{Span, DUMMY_SP}; use syntax::{attr, visit}; use syntax::ast; use syntax::ast::{Attribute, Block, Crate, DefId, FnDecl, NodeId, Variant}; -use syntax::ast::{Item, TypeMethod, Method, Generics, StructField}; +use syntax::ast::{Item, Generics, StructField}; use syntax::ast_util::is_local; use syntax::attr::{Stability, AttrMetaMethods}; -use syntax::visit::{FnKind, FkMethod, Visitor}; +use syntax::visit::{FnKind, Visitor}; use syntax::feature_gate::emit_feature_warn; use util::nodemap::{NodeMap, DefIdMap, FnvHashSet, FnvHashMap}; use util::ppaux::Repr; @@ -123,32 +123,20 @@ impl<'a, 'v> Visitor<'v> for Annotator<'a> { } } - fn visit_fn(&mut self, fk: FnKind<'v>, _: &'v FnDecl, - _: &'v Block, sp: Span, _: NodeId) { - if let FkMethod(_, _, meth) = fk { - // Methods are not already annotated, so we annotate it - self.annotate(meth.id, true, &meth.attrs, sp, |_| {}, true); - } + fn visit_fn(&mut self, _: FnKind<'v>, _: &'v FnDecl, + _: &'v Block, _: Span, _: NodeId) { // Items defined in a function body have no reason to have // a stability attribute, so we don't recurse. } - fn visit_trait_item(&mut self, t: &ast::TraitItem) { - let (id, attrs, sp) = match *t { - ast::RequiredMethod(TypeMethod {id, ref attrs, span, ..}) => (id, attrs, span), - - // work around lack of pattern matching for @ types - ast::ProvidedMethod(ref method) => { - match *method { - Method {ref attrs, id, span, ..} => (id, attrs, span), - } - } + fn visit_trait_item(&mut self, ti: &ast::TraitItem) { + self.annotate(ti.id, true, &ti.attrs, ti.span, + |v| visit::walk_trait_item(v, ti), true); + } - ast::TypeTraitItem(ref typedef) => { - (typedef.ty_param.id, &typedef.attrs, typedef.ty_param.span) - } - }; - self.annotate(id, true, attrs, sp, |v| visit::walk_trait_item(v, t), true); + fn visit_impl_item(&mut self, ii: &ast::ImplItem) { + self.annotate(ii.id, true, &ii.attrs, ii.span, + |v| visit::walk_impl_item(v, ii), true); } fn visit_variant(&mut self, var: &Variant, g: &'v Generics) { @@ -335,22 +323,11 @@ pub fn check_item(tcx: &ty::ctxt, item: &ast::Item, warn_about_defns: bool, let trait_items = ty::trait_items(tcx, trait_did); for impl_item in impl_items { - let (ident, span) = match **impl_item { - ast::MethodImplItem(ref method) => { - (match method.node { - ast::MethDecl(ident, _, _, _, _, _, _, _) => ident, - ast::MethMac(..) => unreachable!(), - }, method.span) - } - ast::TypeImplItem(ref typedef) => { - (typedef.ident, typedef.span) - } - }; let item = trait_items.iter().find(|item| { - item.name() == ident.name + item.name() == impl_item.ident.name }).unwrap(); if warn_about_defns { - maybe_do_stability_check(tcx, item.def_id(), span, cb); + maybe_do_stability_check(tcx, item.def_id(), impl_item.span, cb); } } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index f6920dc52cdcc..32b85d8c0a9be 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2286,7 +2286,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx> { match cx.map.find(id) { Some(ast_map::NodeImplItem(ref impl_item)) => { - match **impl_item { + match impl_item.node { ast::MethodImplItem(ref method) => { let method_def_id = ast_util::local_def(id); match ty::impl_or_trait_item(cx, method_def_id) { @@ -2295,7 +2295,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { let method_bounds = &method_ty.predicates; construct_parameter_environment( cx, - method.span, + impl_item.span, method_generics, method_bounds, method.pe_body().id) @@ -2315,10 +2315,10 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { } } } - Some(ast_map::NodeTraitItem(trait_method)) => { - match *trait_method { - ast::RequiredMethod(ref required) => { - cx.sess.span_bug(required.span, + Some(ast_map::NodeTraitItem(trait_item)) => { + match trait_item.node { + ast::RequiredMethod(_) => { + cx.sess.span_bug(trait_item.span, "ParameterEnvironment::for_item(): can't create a parameter \ environment for required trait \ @@ -2332,7 +2332,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { let method_bounds = &method_ty.predicates; construct_parameter_environment( cx, - method.span, + trait_item.span, method_generics, method_bounds, method.pe_body().id) @@ -2345,7 +2345,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { } } } - ast::TypeTraitItem(_) => { + ast::TypeTraitItem(..) => { cx.sess.bug("ParameterEnvironment::from_item(): \ can't create a parameter environment \ for type trait items") @@ -5082,8 +5082,8 @@ pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) if is_local(id) { if let ItemTrait(_, _, _, ref ms) = cx.map.expect_item(id.node).node { ms.iter().filter_map(|ti| { - if let ast::ProvidedMethod(ref m) = **ti { - match impl_or_trait_item(cx, ast_util::local_def(m.id)) { + if let ast::ProvidedMethod(_) = ti.node { + match impl_or_trait_item(cx, ast_util::local_def(ti.id)) { MethodTraitItem(m) => Some(m), TypeTraitItem(_) => { cx.sess.bug("provided_trait_methods(): \ diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index f41d969c1a271..f1041809701e1 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -828,14 +828,12 @@ impl<'tcx> Repr<'tcx> for ty::TraitDef<'tcx> { impl<'tcx> Repr<'tcx> for ast::TraitItem { fn repr(&self, _tcx: &ctxt) -> String { - match *self { - ast::RequiredMethod(ref data) => format!("RequiredMethod({}, id={})", - data.ident, data.id), - ast::ProvidedMethod(ref data) => format!("ProvidedMethod(id={})", - data.id), - ast::TypeTraitItem(ref data) => format!("TypeTraitItem({}, id={})", - data.ty_param.ident, data.ty_param.id), - } + let kind = match self.node { + ast::RequiredMethod(_) => "RequiredMethod", + ast::ProvidedMethod(_) => "ProvidedMethod", + ast::TypeTraitItem(..) => "TypeTraitItem", + }; + format!("{}({}, id={})", kind, self.ident, self.id) } } diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs index e16df61c25c47..467b7c1ca3819 100644 --- a/src/librustc_back/svh.rs +++ b/src/librustc_back/svh.rs @@ -188,8 +188,8 @@ mod svh_visitor { SawTy, SawGenerics, SawFn, - SawTyMethod, - SawTraitMethod, + SawTraitItem, + SawImplItem, SawStructField, SawVariant, SawExplicitSelf, @@ -463,12 +463,12 @@ mod svh_visitor { SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s) } - fn visit_ty_method(&mut self, t: &TypeMethod) { - SawTyMethod.hash(self.st); visit::walk_ty_method(self, t) + fn visit_trait_item(&mut self, ti: &TraitItem) { + SawTraitItem.hash(self.st); visit::walk_trait_item(self, ti) } - fn visit_trait_item(&mut self, t: &TraitItem) { - SawTraitMethod.hash(self.st); visit::walk_trait_item(self, t) + fn visit_impl_item(&mut self, ii: &ImplItem) { + SawImplItem.hash(self.st); visit::walk_impl_item(self, ii) } fn visit_struct_field(&mut self, s: &StructField) { diff --git a/src/librustc_borrowck/borrowck/fragments.rs b/src/librustc_borrowck/borrowck/fragments.rs index 8cb4090bf3929..f3abcb4376c98 100644 --- a/src/librustc_borrowck/borrowck/fragments.rs +++ b/src/librustc_borrowck/borrowck/fragments.rs @@ -26,7 +26,6 @@ use rustc::util::ppaux::{Repr, UserString}; use std::mem; use std::rc::Rc; use syntax::ast; -use syntax::ast_map; use syntax::attr::AttrMetaMethods; use syntax::codemap::Span; @@ -119,24 +118,9 @@ pub fn instrument_move_fragments<'tcx>(this: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>, sp: Span, id: ast::NodeId) { - let (span_err, print) = { - let attrs : &[ast::Attribute]; - attrs = match tcx.map.find(id) { - Some(ast_map::NodeItem(ref item)) => - &item.attrs, - Some(ast_map::NodeImplItem(&ast::MethodImplItem(ref m))) => - &m.attrs, - Some(ast_map::NodeTraitItem(&ast::ProvidedMethod(ref m))) => - &m.attrs, - _ => &[], - }; - - let span_err = - attrs.iter().any(|a| a.check_name("rustc_move_fragments")); - let print = tcx.sess.opts.debugging_opts.print_move_fragments; - - (span_err, print) - }; + let span_err = tcx.map.attrs(id).iter() + .any(|a| a.check_name("rustc_move_fragments")); + let print = tcx.sess.opts.debugging_opts.print_move_fragments; if !span_err && !print { return; } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 99febcfe34621..259a9acadc6db 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -46,13 +46,12 @@ use std::{cmp, slice}; use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64}; use syntax::{abi, ast, ast_map}; -use syntax::ast_util::is_shift_binop; +use syntax::ast_util::{self, is_shift_binop, local_def}; use syntax::attr::{self, AttrMetaMethods}; use syntax::codemap::{self, Span}; use syntax::feature_gate::{KNOWN_ATTRIBUTES, AttributeType}; use syntax::parse::token; use syntax::ast::{TyIs, TyUs, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32, TyI64, TyU64}; -use syntax::ast_util; use syntax::ptr::P; use syntax::visit::{self, Visitor}; @@ -879,36 +878,18 @@ enum MethodContext { PlainImpl } -fn method_context(cx: &Context, m: &ast::Method) -> MethodContext { - let did = ast::DefId { - krate: ast::LOCAL_CRATE, - node: m.id - }; - - match cx.tcx.impl_or_trait_items.borrow().get(&did).cloned() { - None => cx.sess().span_bug(m.span, "missing method descriptor?!"), - Some(ty::MethodTraitItem(md)) => { - match md.container { - ty::TraitContainer(..) => MethodContext::TraitDefaultImpl, - ty::ImplContainer(cid) => { - match ty::impl_trait_ref(cx.tcx, cid) { - Some(..) => MethodContext::TraitImpl, - None => MethodContext::PlainImpl - } +fn method_context(cx: &Context, id: ast::NodeId, span: Span) -> MethodContext { + match cx.tcx.impl_or_trait_items.borrow().get(&local_def(id)) { + None => cx.sess().span_bug(span, "missing method descriptor?!"), + Some(item) => match item.container() { + ty::TraitContainer(..) => MethodContext::TraitDefaultImpl, + ty::ImplContainer(cid) => { + match ty::impl_trait_ref(cx.tcx, cid) { + Some(_) => MethodContext::TraitImpl, + None => MethodContext::PlainImpl } } - }, - Some(ty::TypeTraitItem(typedef)) => { - match typedef.container { - ty::TraitContainer(..) => MethodContext::TraitDefaultImpl, - ty::ImplContainer(cid) => { - match ty::impl_trait_ref(cx.tcx, cid) { - Some(..) => MethodContext::TraitImpl, - None => MethodContext::PlainImpl - } - } - } - }, + } } } @@ -999,9 +980,9 @@ impl LintPass for NonSnakeCase { fn check_fn(&mut self, cx: &Context, fk: visit::FnKind, _: &ast::FnDecl, - _: &ast::Block, span: Span, _: ast::NodeId) { + _: &ast::Block, span: Span, id: ast::NodeId) { match fk { - visit::FkMethod(ident, _, m) => match method_context(cx, m) { + visit::FkMethod(ident, _) => match method_context(cx, id, span) { MethodContext::PlainImpl => { self.check_snake_case(cx, "method", ident, span) }, @@ -1023,8 +1004,10 @@ impl LintPass for NonSnakeCase { } } - fn check_ty_method(&mut self, cx: &Context, t: &ast::TypeMethod) { - self.check_snake_case(cx, "trait method", t.ident, t.span); + fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) { + if let ast::RequiredMethod(_) = trait_item.node { + self.check_snake_case(cx, "trait method", trait_item.ident, trait_item.span); + } } fn check_lifetime_def(&mut self, cx: &Context, t: &ast::LifetimeDef) { @@ -1335,9 +1318,9 @@ impl LintPass for UnsafeCode { visit::FkItemFn(_, _, ast::Unsafety::Unsafe, _) => cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` function"), - visit::FkMethod(_, _, m) => { - if let ast::Method_::MethDecl(_, _, _, _, ast::Unsafety::Unsafe, _, _, _) = m.node { - cx.span_lint(UNSAFE_CODE, m.span, "implementation of an `unsafe` method") + visit::FkMethod(_, m) => { + if let ast::MethDecl(_, _, _, ast::Unsafety::Unsafe, _, _) = *m { + cx.span_lint(UNSAFE_CODE, span, "implementation of an `unsafe` method") } }, @@ -1345,9 +1328,12 @@ impl LintPass for UnsafeCode { } } - fn check_ty_method(&mut self, cx: &Context, ty_method: &ast::TypeMethod) { - if let ast::TypeMethod { unsafety: ast::Unsafety::Unsafe, span, ..} = *ty_method { - cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` method") + fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) { + if let ast::RequiredMethod(ref m) = trait_item.node { + if m.unsafety == ast::Unsafety::Unsafe { + cx.span_lint(UNSAFE_CODE, trait_item.span, + "declaration of an `unsafe` method") + } } } } @@ -1576,30 +1562,30 @@ impl LintPass for MissingDoc { self.check_missing_docs_attrs(cx, Some(it.id), &it.attrs, it.span, desc); } - fn check_fn(&mut self, cx: &Context, fk: visit::FnKind, _: &ast::FnDecl, - _: &ast::Block, _: Span, _: ast::NodeId) { - if let visit::FkMethod(_, _, m) = fk { - // If the method is an impl for a trait, don't doc. - if method_context(cx, m) == MethodContext::TraitImpl { - return; - } - - // Otherwise, doc according to privacy. This will also check - // doc for default methods defined on traits. - self.check_missing_docs_attrs(cx, Some(m.id), &m.attrs, m.span, "a method"); - } - } - - fn check_ty_method(&mut self, cx: &Context, tm: &ast::TypeMethod) { - self.check_missing_docs_attrs(cx, Some(tm.id), &tm.attrs, tm.span, "a type method"); + fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) { + let desc = match trait_item.node { + ast::ProvidedMethod(_) => "a default method", + ast::RequiredMethod(_) => "a trait method", + ast::TypeTraitItem(..) => "an associated type" + }; + self.check_missing_docs_attrs(cx, Some(trait_item.id), + &trait_item.attrs, + trait_item.span, desc); } - fn check_trait_item(&mut self, cx: &Context, it: &ast::TraitItem) { - if let ast::TraitItem::TypeTraitItem(ref ty) = *it { - let assoc_ty = &ty.ty_param; - self.check_missing_docs_attrs(cx, Some(assoc_ty.id), &ty.attrs, - assoc_ty.span, "an associated type"); + fn check_impl_item(&mut self, cx: &Context, impl_item: &ast::ImplItem) { + // If the method is an impl for a trait, don't doc. + if method_context(cx, impl_item.id, impl_item.span) == MethodContext::TraitImpl { + return; } + + let desc = match impl_item.node { + ast::MethodImplItem(_) => "a method", + ast::TypeImplItem(_) => "an associated type" + }; + self.check_missing_docs_attrs(cx, Some(impl_item.id), + &impl_item.attrs, + impl_item.span, desc); } fn check_struct_field(&mut self, cx: &Context, sf: &ast::StructField) { @@ -1644,10 +1630,7 @@ impl LintPass for MissingCopyImplementations { if !cx.exported_items.contains(&item.id) { return; } - if cx.tcx - .destructor_for_type - .borrow() - .contains_key(&ast_util::local_def(item.id)) { + if cx.tcx.destructor_for_type.borrow().contains_key(&local_def(item.id)) { return; } let ty = match item.node { @@ -1655,16 +1638,14 @@ impl LintPass for MissingCopyImplementations { if ast_generics.is_parameterized() { return; } - ty::mk_struct(cx.tcx, - ast_util::local_def(item.id), + ty::mk_struct(cx.tcx, local_def(item.id), cx.tcx.mk_substs(Substs::empty())) } ast::ItemEnum(_, ref ast_generics) => { if ast_generics.is_parameterized() { return; } - ty::mk_enum(cx.tcx, - ast_util::local_def(item.id), + ty::mk_enum(cx.tcx, local_def(item.id), cx.tcx.mk_substs(Substs::empty())) } _ => return, @@ -1828,13 +1809,13 @@ impl LintPass for UnconditionalRecursion { let (name, checker) = match fn_kind { visit::FkItemFn(name, _, _, _) => (name, id_refers_to_this_fn as F), - visit::FkMethod(name, _, _) => (name, id_refers_to_this_method as F), + visit::FkMethod(name, _) => (name, id_refers_to_this_method as F), // closures can't recur, so they don't matter. visit::FkFnBlock => return }; - let impl_def_id = ty::impl_of_method(cx.tcx, ast_util::local_def(id)) - .unwrap_or(ast_util::local_def(ast::DUMMY_NODE_ID)); + let impl_def_id = ty::impl_of_method(cx.tcx, local_def(id)) + .unwrap_or(local_def(ast::DUMMY_NODE_ID)); assert!(ast_util::is_local(impl_def_id)); let impl_node_id = impl_def_id.node; @@ -1938,7 +1919,7 @@ impl LintPass for UnconditionalRecursion { _: ast::Ident, id: ast::NodeId) -> bool { tcx.def_map.borrow().get(&id) - .map_or(false, |def| def.def_id() == ast_util::local_def(fn_id)) + .map_or(false, |def| def.def_id() == local_def(fn_id)) } // check if the method call `id` refers to method `method_id` diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index a979c4919952a..9cb9c1f2f85eb 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -92,17 +92,9 @@ impl<'v> Visitor<'v> for ParentVisitor { // method to the root. In this case, if the trait is private, then // parent all the methods to the trait to indicate that they're // private. - ast::ItemTrait(_, _, _, ref methods) if item.vis != ast::Public => { - for m in methods { - match **m { - ast::ProvidedMethod(ref m) => { - self.parents.insert(m.id, item.id); - } - ast::RequiredMethod(ref m) => { - self.parents.insert(m.id, item.id); - } - ast::TypeTraitItem(_) => {} - }; + ast::ItemTrait(_, _, _, ref trait_items) if item.vis != ast::Public => { + for trait_item in trait_items { + self.parents.insert(trait_item.id, item.id); } } @@ -280,15 +272,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> { if public_ty || public_trait { for impl_item in impl_items { - match **impl_item { + match impl_item.node { ast::MethodImplItem(ref method) => { let meth_public = match method.pe_explicit_self().node { ast::SelfStatic => public_ty, _ => true, - } && method.pe_vis() == ast::Public; + } && impl_item.vis == ast::Public; if meth_public || tr.is_some() { - self.exported_items.insert(method.id); + self.exported_items.insert(impl_item.id); } } ast::TypeImplItem(_) => {} @@ -299,22 +291,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> { // Default methods on traits are all public so long as the trait // is public - ast::ItemTrait(_, _, _, ref methods) if public_first => { - for method in methods { - match **method { - ast::ProvidedMethod(ref m) => { - debug!("provided {}", m.id); - self.exported_items.insert(m.id); - } - ast::RequiredMethod(ref m) => { - debug!("required {}", m.id); - self.exported_items.insert(m.id); - } - ast::TypeTraitItem(ref t) => { - debug!("typedef {}", t.ty_param.id); - self.exported_items.insert(t.ty_param.id); - } - } + ast::ItemTrait(_, _, _, ref trait_items) if public_first => { + for trait_item in trait_items { + debug!("trait item {}", trait_item.id); + self.exported_items.insert(trait_item.id); } } @@ -510,16 +490,16 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { // FIXME(#10573) is this the right behavior? Why not consider // where the method was defined? Some(ast_map::NodeImplItem(ii)) => { - match *ii { - ast::MethodImplItem(ref m) => { + match ii.node { + ast::MethodImplItem(_) => { let imp = self.tcx.map .get_parent_did(closest_private_id); match ty::impl_trait_ref(self.tcx, imp) { Some(..) => return Allowable, - _ if m.pe_vis() == ast::Public => { + _ if ii.vis == ast::Public => { return Allowable } - _ => m.pe_vis() + _ => ii.vis } } ast::TypeImplItem(_) => return Allowable, @@ -1088,12 +1068,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> { "visibility qualifiers have no effect on trait \ impls"); for impl_item in impl_items { - match **impl_item { - ast::MethodImplItem(ref m) => { - check_inherited(m.span, m.pe_vis(), ""); - } - ast::TypeImplItem(_) => {} - } + check_inherited(impl_item.span, impl_item.vis, ""); } } @@ -1121,23 +1096,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> { } } - ast::ItemTrait(_, _, _, ref methods) => { - for m in methods { - match **m { - ast::ProvidedMethod(ref m) => { - check_inherited(m.span, m.pe_vis(), - "unnecessary visibility"); - } - ast::RequiredMethod(ref m) => { - check_inherited(m.span, m.vis, - "unnecessary visibility"); - } - ast::TypeTraitItem(_) => {} - } - } - } - - ast::ItemDefaultImpl(..) | + ast::ItemTrait(..) | ast::ItemDefaultImpl(..) | ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemStruct(..) | ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) | ast::ItemExternCrate(_) | ast::ItemUse(_) | ast::ItemMac(..) => {} @@ -1165,9 +1124,9 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> { match item.node { ast::ItemImpl(_, _, _, _, _, ref impl_items) => { for impl_item in impl_items { - match **impl_item { - ast::MethodImplItem(ref m) => { - check_inherited(tcx, m.span, m.pe_vis()); + match impl_item.node { + ast::MethodImplItem(_) => { + check_inherited(tcx, impl_item.span, impl_item.vis); } ast::TypeImplItem(_) => {} } @@ -1186,18 +1145,8 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> { ast::ItemStruct(ref def, _) => check_struct(&**def), - ast::ItemTrait(_, _, _, ref methods) => { - for m in methods { - match **m { - ast::RequiredMethod(..) => {} - ast::ProvidedMethod(ref m) => check_inherited(tcx, m.span, - m.pe_vis()), - ast::TypeTraitItem(_) => {} - } - } - } - - ast::ItemDefaultImpl(..) | ast::ItemExternCrate(_) | ast::ItemUse(_) | + ast::ItemExternCrate(_) | ast::ItemUse(_) | + ast::ItemTrait(..) | ast::ItemDefaultImpl(..) | ast::ItemStatic(..) | ast::ItemConst(..) | ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) | ast::ItemMac(..) => {} @@ -1352,9 +1301,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { trait_ref.is_some() || impl_items.iter() .any(|impl_item| { - match **impl_item { - ast::MethodImplItem(ref m) => { - self.exported_items.contains(&m.id) + match impl_item.node { + ast::MethodImplItem(_) => { + self.exported_items.contains(&impl_item.id) } ast::TypeImplItem(_) => false, } @@ -1369,12 +1318,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { match *trait_ref { None => { for impl_item in impl_items { - match **impl_item { - ast::MethodImplItem(ref method) => { - visit::walk_method_helper(self, method) - } - ast::TypeImplItem(_) => {} - } + visit::walk_impl_item(self, impl_item); } } Some(ref tr) => { @@ -1395,10 +1339,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { // Those in 3. are warned with this call. for impl_item in impl_items { - match **impl_item { + match impl_item.node { ast::MethodImplItem(..) => {}, - ast::TypeImplItem(ref typedef) => { - self.visit_ty(&typedef.typ); + ast::TypeImplItem(ref ty) => { + self.visit_ty(ty); } } } @@ -1409,14 +1353,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { // methods will be visible as `Public::foo`. let mut found_pub_static = false; for impl_item in impl_items { - match **impl_item { + match impl_item.node { ast::MethodImplItem(ref method) => { if method.pe_explicit_self().node == ast::SelfStatic && self.exported_items - .contains(&method.id) { + .contains(&impl_item.id) { found_pub_static = true; - visit::walk_method_helper(self, method); + visit::walk_impl_item(self, impl_item); } } ast::TypeImplItem(_) => {} diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 48fb03e1efb85..dd762f07b7246 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -48,7 +48,7 @@ use syntax::ast::UnnamedField; use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple}; use syntax::ast::{Visibility}; use syntax::ast; -use syntax::ast_util::{self, local_def, PostExpansionMethod}; +use syntax::ast_util::local_def; use syntax::attr::AttrMetaMethods; use syntax::parse::token::{self, special_idents}; use syntax::codemap::{Span, DUMMY_SP}; @@ -525,53 +525,29 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { // Add the names of all the items to the trait info. for trait_item in items { - let (name, trait_item_id) = match **trait_item { + let name_bindings = self.add_child(trait_item.ident.name, + &module_parent, + ForbidDuplicateTypesAndValues, + trait_item.span); + + match trait_item.node { ast::RequiredMethod(_) | ast::ProvidedMethod(_) => { - let (id, name, span) = match **trait_item { - ast::RequiredMethod(ref m) => { - (m.id, m.ident.name, m.span) - } - ast::ProvidedMethod(ref m) => { - (m.id, m.pe_ident().name, m.span) - } - _ => unreachable!() - }; - - // Add it as a name in the trait module. - let def = DefMethod(local_def(id), + let def = DefMethod(local_def(trait_item.id), FromTrait(local_def(item.id))); - - let method_name_bindings = - self.add_child(name, - &module_parent, - ForbidDuplicateTypesAndValues, - span); // NB: not IMPORTABLE - method_name_bindings.define_value(def, span, PUBLIC); - - (name, local_def(id)) + name_bindings.define_value(def, trait_item.span, PUBLIC); } - ast::TypeTraitItem(ref associated_type) => { + ast::TypeTraitItem(..) => { let def = DefAssociatedTy(local_def(item.id), - local_def(associated_type.ty_param.id)); - - let name_bindings = - self.add_child(associated_type.ty_param.ident.name, - &module_parent, - ForbidDuplicateTypesAndValues, - associated_type.ty_param.span); + local_def(trait_item.id)); // NB: not IMPORTABLE - name_bindings.define_type(def, - associated_type.ty_param.span, - PUBLIC); - - (associated_type.ty_param.ident.name, - local_def(associated_type.ty_param.id)) + name_bindings.define_type(def, trait_item.span, PUBLIC); } - }; + } - self.trait_item_map.insert((name, def_id), trait_item_id); + self.trait_item_map.insert((trait_item.ident.name, def_id), + local_def(trait_item.id)); } name_bindings.define_type(DefTrait(def_id), sp, modifiers); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index cb1540e0f4f43..67675a5a1ae70 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -242,8 +242,8 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { self.visit_generics(generics); ItemRibKind } - visit::FkMethod(_, generics, method) => { - self.visit_generics(generics); + visit::FkMethod(_, method) => { + self.visit_generics(method.pe_generics()); self.visit_explicit_self(method.pe_explicit_self()); MethodRibKind } @@ -2807,13 +2807,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { this.visit_generics(generics); visit::walk_ty_param_bounds_helper(this, bounds); - for trait_item in &(*trait_items) { + for trait_item in trait_items { // Create a new rib for the trait_item-specific type // parameters. // // FIXME #4951: Do we need a node ID here? - let type_parameters = match **trait_item { + let type_parameters = match trait_item.node { ast::RequiredMethod(ref ty_m) => { HasTypeParameters(&ty_m.generics, FnSpace, @@ -2824,10 +2824,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { FnSpace, MethodRibKind) } - ast::TypeTraitItem(ref assoc_ty) => { - let ty_param = &assoc_ty.ty_param; - this.check_if_primitive_type_name(ty_param.ident.name, - ty_param.span); + ast::TypeTraitItem(..) => { + this.check_if_primitive_type_name(trait_item.ident.name, + trait_item.span); NoTypeParameters } }; @@ -3066,12 +3065,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { this.with_current_self_type(self_type, |this| { for impl_item in impl_items { - match **impl_item { + match impl_item.node { MethodImplItem(ref method) => { // If this is a trait impl, ensure the method // exists in trait - this.check_trait_item(method.pe_ident().name, - method.span); + this.check_trait_item(impl_item.ident.name, + impl_item.span); // We also need a new scope for the method- // specific type parameters. @@ -3080,16 +3079,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { FnSpace, MethodRibKind); this.with_type_parameter_rib(type_parameters, |this| { - visit::walk_method_helper(this, method); + visit::walk_impl_item(this, impl_item); }); } - TypeImplItem(ref typedef) => { + TypeImplItem(ref ty) => { // If this is a trait impl, ensure the method // exists in trait - this.check_trait_item(typedef.ident.name, - typedef.span); + this.check_trait_item(impl_item.ident.name, + impl_item.span); - this.visit_ty(&*typedef.typ); + this.visit_ty(ty); } } } @@ -3955,12 +3954,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn is_static_method(this: &Resolver, did: DefId) -> bool { if did.krate == ast::LOCAL_CRATE { let explicit_self = match this.ast_map.get(did.node) { - ast_map::NodeTraitItem(m) => match *m { + ast_map::NodeTraitItem(trait_item) => match trait_item.node { ast::RequiredMethod(ref m) => &m.explicit_self, ast::ProvidedMethod(ref m) => m.pe_explicit_self(), _ => return false }, - ast_map::NodeImplItem(m) => match *m { + ast_map::NodeImplItem(impl_item) => match impl_item.node { ast::MethodImplItem(ref m) => m.pe_explicit_self(), _ => return false }, diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 13e3db4ba75c2..953650209645b 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -284,8 +284,10 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { } } - fn process_method(&mut self, method: &ast::Method) { - if generated_code(method.span) { + fn process_method(&mut self, method: &ast::Method, + id: ast::NodeId, ident: ast::Ident, + span: Span) { + if generated_code(span) { return; } @@ -293,7 +295,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { // The qualname for a method is the trait name or name of the struct in an impl in // which the method is declared in, followed by the method's name. let qualname = match ty::impl_of_method(&self.analysis.ty_cx, - ast_util::local_def(method.id)) { + ast_util::local_def(id)) { Some(impl_id) => match self.analysis.ty_cx.map.get(impl_id.node) { NodeItem(item) => { scope_id = item.id; @@ -303,7 +305,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { result.push_str(&ty_to_string(&**ty)); match ty::trait_of_item(&self.analysis.ty_cx, - ast_util::local_def(method.id)) { + ast_util::local_def(id)) { Some(def_id) => { result.push_str(" as "); result.push_str( @@ -315,23 +317,20 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { result } _ => { - self.sess.span_bug(method.span, - &format!("Container {} for method {} not an impl?", - impl_id.node, method.id)); + self.sess.span_bug(span, + &format!("Container {} for method {} not an impl?", + impl_id.node, id)); }, } }, _ => { - self.sess.span_bug(method.span, - &format!( - "Container {} for method {} is not a node item {:?}", - impl_id.node, - method.id, - self.analysis.ty_cx.map.get(impl_id.node))); + self.sess.span_bug(span, + &format!("Container {} for method {} is not a node item {:?}", + impl_id.node, id, self.analysis.ty_cx.map.get(impl_id.node))); }, }, None => match ty::trait_of_item(&self.analysis.ty_cx, - ast_util::local_def(method.id)) { + ast_util::local_def(id)) { Some(def_id) => { scope_id = def_id.node; match self.analysis.ty_cx.map.get(def_id.node) { @@ -339,30 +338,29 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { format!("::{}", ty::item_path_str(&self.analysis.ty_cx, def_id)) } _ => { - self.sess.span_bug(method.span, - &format!("Could not find container {} for method {}", - def_id.node, method.id)); + self.sess.span_bug(span, + &format!("Could not find container {} for method {}", + def_id.node, id)); } } }, None => { - self.sess.span_bug(method.span, - &format!("Could not find container for method {}", - method.id)); + self.sess.span_bug(span, + &format!("Could not find container for method {}", id)); }, }, }; - let qualname = format!("{}::{}", qualname, &get_ident(method.pe_ident())); + let qualname = format!("{}::{}", qualname, &get_ident(ident)); let qualname = &qualname[..]; // record the decl for this def (if it has one) let decl_id = ty::trait_item_of_item(&self.analysis.ty_cx, - ast_util::local_def(method.id)) + ast_util::local_def(id)) .and_then(|def_id| { if match def_id { ty::MethodTraitItemId(def_id) => { - def_id.node != 0 && def_id != ast_util::local_def(method.id) + def_id.node != 0 && def_id != ast_util::local_def(id) } ty::TypeTraitItemId(_) => false, } { @@ -376,10 +374,10 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { Some(id) => Some(id.def_id()), }; - let sub_span = self.span.sub_span_after_keyword(method.span, keywords::Fn); - self.fmt.method_str(method.span, + let sub_span = self.span.sub_span_after_keyword(span, keywords::Fn); + self.fmt.method_str(span, sub_span, - method.id, + id, qualname, decl_id, scope_id); @@ -396,12 +394,12 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { } // walk the fn body - self.nest(method.id, |v| v.visit_block(&*method.pe_body())); + self.nest(id, |v| v.visit_block(&*method.pe_body())); self.process_generic_params(method.pe_generics(), - method.span, + span, qualname, - method.id); + id); } fn process_trait_ref(&mut self, @@ -698,14 +696,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { self.process_generic_params(type_parameters, item.span, "", item.id); for impl_item in impl_items { - match **impl_item { - ast::MethodImplItem(ref method) => { - visit::walk_method_helper(self, method) - } - ast::TypeImplItem(ref typedef) => { - visit::walk_ty(self, &*typedef.typ) - } - } + visit::walk_impl_item(self, impl_item); } } @@ -1233,52 +1224,34 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { } } - // We don't actually index functions here, that is done in visit_item/ItemFn. - // Here we just visit methods. - fn visit_fn(&mut self, - fk: visit::FnKind<'v>, - fd: &'v ast::FnDecl, - b: &'v ast::Block, - s: Span, - _: ast::NodeId) { - if generated_code(s) { - return; - } - - match fk { - visit::FkMethod(_, _, method) => self.process_method(method), - _ => visit::walk_fn(self, fk, fd, b, s), - } - } - - fn visit_trait_item(&mut self, tm: &ast::TraitItem) { - match *tm { + fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) { + match trait_item.node { ast::RequiredMethod(ref method_type) => { - if generated_code(method_type.span) { + if generated_code(trait_item.span) { return; } let mut scope_id; let mut qualname = match ty::trait_of_item(&self.analysis.ty_cx, - ast_util::local_def(method_type.id)) { + ast_util::local_def(trait_item.id)) { Some(def_id) => { scope_id = def_id.node; format!("::{}::", ty::item_path_str(&self.analysis.ty_cx, def_id)) }, None => { - self.sess.span_bug(method_type.span, + self.sess.span_bug(trait_item.span, &format!("Could not find trait for method {}", - method_type.id)); + trait_item.id)); }, }; - qualname.push_str(&get_ident(method_type.ident)); + qualname.push_str(&get_ident(trait_item.ident)); let qualname = &qualname[..]; - let sub_span = self.span.sub_span_after_keyword(method_type.span, keywords::Fn); - self.fmt.method_decl_str(method_type.span, + let sub_span = self.span.sub_span_after_keyword(trait_item.span, keywords::Fn); + self.fmt.method_decl_str(trait_item.span, sub_span, - method_type.id, + trait_item.id, qualname, scope_id); @@ -1292,12 +1265,23 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { } self.process_generic_params(&method_type.generics, - method_type.span, + trait_item.span, qualname, - method_type.id); + trait_item.id); + } + ast::ProvidedMethod(ref method) => { + self.process_method(method, trait_item.id, trait_item.ident, trait_item.span); + } + ast::TypeTraitItem(..) => {} + } + } + + fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) { + match impl_item.node { + ast::MethodImplItem(ref method) => { + self.process_method(method, impl_item.id, impl_item.ident, impl_item.span); } - ast::ProvidedMethod(ref method) => self.process_method(method), - ast::TypeTraitItem(_) => {} + ast::TypeImplItem(_) => {} } } diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 77df121580d81..9616bf8b64893 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -94,7 +94,7 @@ use std::rc::Rc; use std::str; use std::{i8, i16, i32, i64}; use syntax::abi::{Rust, RustCall, RustIntrinsic, Abi}; -use syntax::ast_util::local_def; +use syntax::ast_util::{local_def, PostExpansionMethod}; use syntax::attr::AttrMetaMethods; use syntax::attr; use syntax::codemap::Span; @@ -1263,41 +1263,27 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option) Some(ast_map::NodeItem(i)) => { match i.node { ast::ItemFn(_, _, _, _, ref blk) => { - blk + &**blk } _ => tcx.sess.bug("unexpected item variant in has_nested_returns") } } - Some(ast_map::NodeTraitItem(trait_method)) => { - match *trait_method { - ast::ProvidedMethod(ref m) => { - match m.node { - ast::MethDecl(_, _, _, _, _, _, ref blk, _) => { - blk - } - ast::MethMac(_) => tcx.sess.bug("unexpanded macro") - } - } + Some(ast_map::NodeTraitItem(trait_item)) => { + match trait_item.node { + ast::ProvidedMethod(ref m) => m.pe_body(), ast::RequiredMethod(_) => { tcx.sess.bug("unexpected variant: required trait method \ in has_nested_returns") } - ast::TypeTraitItem(_) => { + ast::TypeTraitItem(..) => { tcx.sess.bug("unexpected variant: associated type trait item in \ has_nested_returns") } } } - Some(ast_map::NodeImplItem(ii)) => { - match *ii { - ast::MethodImplItem(ref m) => { - match m.node { - ast::MethDecl(_, _, _, _, _, _, ref blk, _) => { - blk - } - ast::MethMac(_) => tcx.sess.bug("unexpanded macro") - } - } + Some(ast_map::NodeImplItem(impl_item)) => { + match impl_item.node { + ast::MethodImplItem(ref m) => m.pe_body(), ast::TypeImplItem(_) => { tcx.sess.bug("unexpected variant: associated type impl item in \ has_nested_returns") @@ -1306,9 +1292,7 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option) } Some(ast_map::NodeExpr(e)) => { match e.node { - ast::ExprClosure(_, _, ref blk) => { - blk - } + ast::ExprClosure(_, _, ref blk) => &**blk, _ => tcx.sess.bug("unexpected expr variant in has_nested_returns") } } @@ -1322,7 +1306,7 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option) tcx.map.path_to_string(id))) }; - (blk.id, Some(cfg::CFG::new(tcx, &**blk))) + (blk.id, Some(cfg::CFG::new(tcx, blk))) } // Checks for the presence of "nested returns" in a function. @@ -2818,26 +2802,27 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { v } - ast_map::NodeTraitItem(trait_method) => { + ast_map::NodeTraitItem(trait_item) => { debug!("get_item_val(): processing a NodeTraitItem"); - match *trait_method { - ast::RequiredMethod(_) | ast::TypeTraitItem(_) => { - ccx.sess().bug("unexpected variant: required trait \ - method in get_item_val()"); + match trait_item.node { + ast::RequiredMethod(_) | ast::TypeTraitItem(..) => { + ccx.sess().span_bug(trait_item.span, + "unexpected variant: required trait method in get_item_val()"); } - ast::ProvidedMethod(ref m) => { - register_method(ccx, id, m) + ast::ProvidedMethod(_) => { + register_method(ccx, id, &trait_item.attrs, trait_item.span) } } } - ast_map::NodeImplItem(ii) => { - match *ii { - ast::MethodImplItem(ref m) => register_method(ccx, id, m), - ast::TypeImplItem(ref typedef) => { - ccx.sess().span_bug(typedef.span, - "unexpected variant: associated type \ - in get_item_val()") + ast_map::NodeImplItem(impl_item) => { + match impl_item.node { + ast::MethodImplItem(_) => { + register_method(ccx, id, &impl_item.attrs, impl_item.span) + } + ast::TypeImplItem(_) => { + ccx.sess().span_bug(impl_item.span, + "unexpected variant: associated type in get_item_val()") } } } @@ -2925,21 +2910,21 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { } fn register_method(ccx: &CrateContext, id: ast::NodeId, - m: &ast::Method) -> ValueRef { + attrs: &[ast::Attribute], span: Span) -> ValueRef { let mty = ty::node_id_to_type(ccx.tcx(), id); - let sym = exported_name(ccx, id, mty, &m.attrs); + let sym = exported_name(ccx, id, mty, &attrs); if let ty::ty_bare_fn(_, ref f) = mty.sty { let llfn = if f.abi == Rust || f.abi == RustCall { - register_fn(ccx, m.span, sym, id, mty) + register_fn(ccx, span, sym, id, mty) } else { - foreign::register_rust_fn_with_foreign_abi(ccx, m.span, sym, id) + foreign::register_rust_fn_with_foreign_abi(ccx, span, sym, id) }; - set_llvm_fn_attrs(ccx, &m.attrs, llfn); + set_llvm_fn_attrs(ccx, &attrs, llfn); return llfn; } else { - ccx.sess().span_bug(m.span, "expected bare rust function"); + ccx.sess().span_bug(span, "expected bare rust function"); } } diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 95c39270cc6d9..0b98beb53c57a 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -1300,22 +1300,22 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } } } - ast_map::NodeImplItem(ref item) => { - match **item { + ast_map::NodeImplItem(impl_item) => { + match impl_item.node { ast::MethodImplItem(ref method) => { - if contains_nodebug_attribute(&method.attrs) { + if contains_nodebug_attribute(&impl_item.attrs) { return FunctionDebugContext::FunctionWithoutDebugInfo; } - (method.pe_ident(), + (impl_item.ident, method.pe_fn_decl(), method.pe_generics(), method.pe_body(), - method.span, + impl_item.span, true) } - ast::TypeImplItem(ref typedef) => { - cx.sess().span_bug(typedef.span, + ast::TypeImplItem(_) => { + cx.sess().span_bug(impl_item.span, "create_function_debug_context() \ called on associated type?!") } @@ -1339,18 +1339,18 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, "create_function_debug_context: expected an expr_fn_block here") } } - ast_map::NodeTraitItem(ref trait_method) => { - match **trait_method { + ast_map::NodeTraitItem(trait_item) => { + match trait_item.node { ast::ProvidedMethod(ref method) => { - if contains_nodebug_attribute(&method.attrs) { + if contains_nodebug_attribute(&trait_item.attrs) { return FunctionDebugContext::FunctionWithoutDebugInfo; } - (method.pe_ident(), + (trait_item.ident, method.pe_fn_decl(), method.pe_generics(), method.pe_body(), - method.span, + trait_item.span, true) } _ => { diff --git a/src/librustc_trans/trans/inline.rs b/src/librustc_trans/trans/inline.rs index 14889190a85af..6c1401a4c029b 100644 --- a/src/librustc_trans/trans/inline.rs +++ b/src/librustc_trans/trans/inline.rs @@ -42,7 +42,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) ccx.tcx(), fn_id, Box::new(|a,b,c,d| astencode::decode_inlined_item(a, b, c, d))); - let inline_def = match csearch_result { + let inline_id = match csearch_result { csearch::FoundAst::NotFound => { ccx.external().borrow_mut().insert(fn_id, None); return None; @@ -88,12 +88,12 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) None => {} } - local_def(item.id) + item.id } csearch::FoundAst::Found(&ast::IIForeign(ref item)) => { ccx.external().borrow_mut().insert(fn_id, Some(item.id)); ccx.external_srcs().borrow_mut().insert(item.id, fn_id); - local_def(item.id) + item.id } csearch::FoundAst::FoundParent(parent_id, &ast::IIItem(ref item)) => { ccx.external().borrow_mut().insert(parent_id, Some(item.id)); @@ -122,65 +122,53 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) non-enum, non-struct parent") } trans_item(ccx, &**item); - local_def(my_id) + my_id } csearch::FoundAst::FoundParent(_, _) => { ccx.sess().bug("maybe_get_item_ast returned a FoundParent \ with a non-item parent"); } csearch::FoundAst::Found(&ast::IITraitItem(_, ref trait_item)) => { - let id = match *trait_item { - ast::ProvidedMethod(ref mth) => mth.id, - ast::RequiredMethod(_) => ccx.sess().bug("found RequiredMethod IITraitItem"), - ast::TypeTraitItem(_) => ccx.sess().bug("found TypeTraitItem IITraitItem"), - }; - ccx.external().borrow_mut().insert(fn_id, Some(id)); - ccx.external_srcs().borrow_mut().insert(id, fn_id); + ccx.external().borrow_mut().insert(fn_id, Some(trait_item.id)); + ccx.external_srcs().borrow_mut().insert(trait_item.id, fn_id); ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1); // If this is a default method, we can't look up the // impl type. But we aren't going to translate anyways, so // don't. - local_def(id) + trait_item.id } csearch::FoundAst::Found(&ast::IIImplItem(impl_did, ref impl_item)) => { - let (id, monomorphic_method) = match *impl_item { - ast::MethodImplItem(ref mth) => { - let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did); - let unparameterized = impl_tpt.generics.types.is_empty() && - mth.pe_generics().ty_params.is_empty(); - - (mth.id, if unparameterized { Some(mth) } else { None }) - } - ast::TypeImplItem(_) => { - ccx.sess().bug("found TypeImplItem IIImplItem") - } - }; - - ccx.external().borrow_mut().insert(fn_id, Some(id)); - ccx.external_srcs().borrow_mut().insert(id, fn_id); + ccx.external().borrow_mut().insert(fn_id, Some(impl_item.id)); + ccx.external_srcs().borrow_mut().insert(impl_item.id, fn_id); ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1); - if let Some(mth) = monomorphic_method { - let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty()); - let llfn = get_item_val(ccx, mth.id); - trans_fn(ccx, - &*mth.pe_fn_decl(), - &*mth.pe_body(), - llfn, - empty_substs, - mth.id, - &[]); - // Use InternalLinkage so LLVM can optimize more aggressively. - SetLinkage(llfn, InternalLinkage); + // Translate monomorphic impl methods immediately. + if let ast::MethodImplItem(ref mth) = impl_item.node { + let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did); + if impl_tpt.generics.types.is_empty() && + mth.pe_generics().ty_params.is_empty() { + let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty()); + let llfn = get_item_val(ccx, impl_item.id); + trans_fn(ccx, + &*mth.pe_fn_decl(), + &*mth.pe_body(), + llfn, + empty_substs, + impl_item.id, + &[]); + // Use InternalLinkage so LLVM can optimize more aggressively. + SetLinkage(llfn, InternalLinkage); + } } - local_def(id) + + impl_item.id } }; - return Some(inline_def); + Some(local_def(inline_id)) } pub fn get_local_instance(ccx: &CrateContext, fn_id: ast::DefId) diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index 8bbd688d63cd7..aea922d9f9f57 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -62,14 +62,15 @@ pub fn trans_impl(ccx: &CrateContext, debug!("trans_impl(name={}, id={})", name.repr(tcx), id); + let mut v = TransItemVisitor { ccx: ccx }; + // Both here and below with generic methods, be sure to recurse and look for // items that we need to translate. if !generics.ty_params.is_empty() { - let mut v = TransItemVisitor{ ccx: ccx }; for impl_item in impl_items { - match **impl_item { - ast::MethodImplItem(ref method) => { - visit::walk_method_helper(&mut v, method); + match impl_item.node { + ast::MethodImplItem(_) => { + visit::walk_impl_item(&mut v, impl_item); } ast::TypeImplItem(_) => {} } @@ -77,30 +78,27 @@ pub fn trans_impl(ccx: &CrateContext, return; } for impl_item in impl_items { - match **impl_item { + match impl_item.node { ast::MethodImplItem(ref method) => { if method.pe_generics().ty_params.len() == 0 { - let trans_everywhere = attr::requests_inline(&method.attrs); + let trans_everywhere = attr::requests_inline(&impl_item.attrs); for (ref ccx, is_origin) in ccx.maybe_iter(trans_everywhere) { - let llfn = get_item_val(ccx, method.id); + let llfn = get_item_val(ccx, impl_item.id); let empty_substs = tcx.mk_substs(Substs::trans_empty()); trans_fn(ccx, method.pe_fn_decl(), method.pe_body(), llfn, empty_substs, - method.id, + impl_item.id, &[]); update_linkage(ccx, llfn, - Some(method.id), + Some(impl_item.id), if is_origin { OriginalTranslation } else { InlinedCopy }); } } - let mut v = TransItemVisitor { - ccx: ccx, - }; - visit::walk_method_helper(&mut v, method); + visit::walk_impl_item(&mut v, impl_item); } ast::TypeImplItem(_) => {} } @@ -190,17 +188,7 @@ pub fn trans_static_method_callee<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let mname = if method_id.krate == ast::LOCAL_CRATE { match tcx.map.get(method_id.node) { - ast_map::NodeTraitItem(method) => { - let ident = match *method { - ast::RequiredMethod(ref m) => m.ident, - ast::ProvidedMethod(ref m) => m.pe_ident(), - ast::TypeTraitItem(_) => { - tcx.sess.bug("trans_static_method_callee() on \ - an associated type?!") - } - }; - ident.name - } + ast_map::NodeTraitItem(trait_item) => trait_item.ident.name, _ => panic!("callee is not a trait method") } } else { diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index 5ab1ec2a69eda..1af783373f9ce 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -216,18 +216,18 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } d } - ast_map::NodeImplItem(ii) => { - match *ii { + ast_map::NodeImplItem(impl_item) => { + match impl_item.node { ast::MethodImplItem(ref mth) => { let d = mk_lldecl(abi::Rust); - let needs_body = setup_lldecl(d, &mth.attrs); + let needs_body = setup_lldecl(d, &impl_item.attrs); if needs_body { trans_fn(ccx, mth.pe_fn_decl(), mth.pe_body(), d, psubsts, - mth.id, + impl_item.id, &[]); } d @@ -237,14 +237,14 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } } } - ast_map::NodeTraitItem(method) => { - match *method { + ast_map::NodeTraitItem(trait_item) => { + match trait_item.node { ast::ProvidedMethod(ref mth) => { let d = mk_lldecl(abi::Rust); - let needs_body = setup_lldecl(d, &mth.attrs); + let needs_body = setup_lldecl(d, &trait_item.attrs); if needs_body { trans_fn(ccx, mth.pe_fn_decl(), mth.pe_body(), d, - psubsts, mth.id, &[]); + psubsts, trait_item.id, &[]); } d } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 9d364df5553c1..9c2bc4da64f33 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1095,14 +1095,9 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>, // by type collection, which may be in progress at this point. match this.tcx().map.expect_item(trait_did.node).node { ast::ItemTrait(_, _, _, ref trait_items) => { - trait_items.iter().filter_map(|i| { - if let ast::TypeTraitItem(ref assoc) = **i { - if assoc.ty_param.ident.name == assoc_name { - return Some(ast_util::local_def(assoc.ty_param.id)); - } - } - None - }).next().expect("missing associated type") + let item = trait_items.iter().find(|i| i.ident.name == assoc_name) + .expect("missing associated type"); + ast_util::local_def(item.id) } _ => unreachable!() } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c625d82671354..3ffc36d3acb75 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -739,9 +739,10 @@ pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) { } for impl_item in impl_items { - match **impl_item { + match impl_item.node { ast::MethodImplItem(ref m) => { - check_method_body(ccx, &impl_pty.generics, m); + check_method_body(ccx, &impl_pty.generics, m, + impl_item.id, impl_item.span); } ast::TypeImplItem(_) => { // Nothing to do here. @@ -750,19 +751,20 @@ pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) { } } - ast::ItemTrait(_, ref generics, _, ref trait_methods) => { + ast::ItemTrait(_, ref generics, _, ref trait_items) => { check_trait_on_unimplemented(ccx, generics, it); let trait_def = ty::lookup_trait_def(ccx.tcx, local_def(it.id)); - for trait_method in trait_methods { - match **trait_method { + for trait_item in trait_items { + match trait_item.node { RequiredMethod(..) => { // Nothing to do, since required methods don't have // bodies to check. } ProvidedMethod(ref m) => { - check_method_body(ccx, &trait_def.generics, m); + check_method_body(ccx, &trait_def.generics, m, + trait_item.id, trait_item.span); } - TypeTraitItem(_) => { + TypeTraitItem(..) => { // Nothing to do. } } @@ -855,20 +857,20 @@ fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, /// * `method`: the method definition fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, item_generics: &ty::Generics<'tcx>, - method: &'tcx ast::Method) { - debug!("check_method_body(item_generics={}, method.id={})", - item_generics.repr(ccx.tcx), - method.id); - let param_env = ParameterEnvironment::for_item(ccx.tcx, method.id); + method: &'tcx ast::Method, + id: ast::NodeId, span: Span) { + debug!("check_method_body(item_generics={}, id={})", + item_generics.repr(ccx.tcx), id); + let param_env = ParameterEnvironment::for_item(ccx.tcx, id); - let fty = ty::node_id_to_type(ccx.tcx, method.id); + let fty = ty::node_id_to_type(ccx.tcx, id); debug!("check_method_body: fty={}", fty.repr(ccx.tcx)); check_bare_fn(ccx, &*method.pe_fn_decl(), &*method.pe_body(), - method.id, - method.span, + id, + span, fty, param_env); } @@ -884,9 +886,9 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // Check existing impl methods to see if they are both present in trait // and compatible with trait signature for impl_item in impl_items { - match **impl_item { + match impl_item.node { ast::MethodImplItem(ref impl_method) => { - let impl_method_def_id = local_def(impl_method.id); + let impl_method_def_id = local_def(impl_item.id); let impl_item_ty = ty::impl_or_trait_item(ccx.tcx, impl_method_def_id); @@ -902,7 +904,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, &ty::MethodTraitItem(ref impl_method_ty)) => { compare_impl_method(ccx.tcx, &**impl_method_ty, - impl_method.span, + impl_item.span, impl_method.pe_body().id, &**trait_method_ty, &*impl_trait_ref); @@ -911,7 +913,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // This is span_bug as it should have already been // caught in resolve. tcx.sess.span_bug( - impl_method.span, + impl_item.span, &format!("item `{}` is of a different kind from its trait `{}`", token::get_name(impl_item_ty.name()), impl_trait_ref.repr(tcx))); @@ -922,15 +924,15 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // This is span_bug as it should have already been // caught in resolve. tcx.sess.span_bug( - impl_method.span, + impl_item.span, &format!("method `{}` is not a member of trait `{}`", token::get_name(impl_item_ty.name()), impl_trait_ref.repr(tcx))); } } } - ast::TypeImplItem(ref typedef) => { - let typedef_def_id = local_def(typedef.id); + ast::TypeImplItem(_) => { + let typedef_def_id = local_def(impl_item.id); let typedef_ty = ty::impl_or_trait_item(ccx.tcx, typedef_def_id); @@ -947,7 +949,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // This is `span_bug` as it should have // already been caught in resolve. tcx.sess.span_bug( - typedef.span, + impl_item.span, &format!("item `{}` is of a different kind from its trait `{}`", token::get_name(typedef_ty.name()), impl_trait_ref.repr(tcx))); @@ -958,7 +960,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // This is `span_bug` as it should have already been // caught in resolve. tcx.sess.span_bug( - typedef.span, + impl_item.span, &format!( "associated type `{}` is not a member of \ trait `{}`", @@ -978,9 +980,9 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ty::MethodTraitItem(ref trait_method) => { let is_implemented = impl_items.iter().any(|ii| { - match **ii { - ast::MethodImplItem(ref m) => { - m.pe_ident().name == trait_method.name + match ii.node { + ast::MethodImplItem(_) => { + ii.ident.name == trait_method.name } ast::TypeImplItem(_) => false, } @@ -993,9 +995,9 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } ty::TypeTraitItem(ref associated_type) => { let is_implemented = impl_items.iter().any(|ii| { - match **ii { - ast::TypeImplItem(ref typedef) => { - typedef.ident.name == associated_type.name + match ii.node { + ast::TypeImplItem(_) => { + ii.ident.name == associated_type.name } ast::MethodImplItem(_) => false, } diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index 6c7c3cf08bc30..0e50938abc447 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -498,28 +498,24 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> { visit::walk_fn(self, fk, fd, b, span) } - fn visit_trait_item(&mut self, t: &'v ast::TraitItem) { - match t { - &ast::TraitItem::ProvidedMethod(_) | - &ast::TraitItem::TypeTraitItem(_) => {} - &ast::TraitItem::RequiredMethod(ref method) => { - match ty::impl_or_trait_item(self.tcx(), local_def(method.id)) { - ty::ImplOrTraitItem::MethodTraitItem(ty_method) => { - reject_non_type_param_bounds( - self.tcx(), - method.span, - &ty_method.predicates); - reject_shadowing_type_parameters( - self.tcx(), - method.span, - &ty_method.generics); - } - _ => {} + fn visit_trait_item(&mut self, trait_item: &'v ast::TraitItem) { + if let ast::RequiredMethod(_) = trait_item.node { + match ty::impl_or_trait_item(self.tcx(), local_def(trait_item.id)) { + ty::ImplOrTraitItem::MethodTraitItem(ty_method) => { + reject_non_type_param_bounds( + self.tcx(), + trait_item.span, + &ty_method.predicates); + reject_shadowing_type_parameters( + self.tcx(), + trait_item.span, + &ty_method.generics); } + _ => {} } } - visit::walk_trait_item(self, t) + visit::walk_trait_item(self, trait_item) } } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index b990ba0ab24f9..a4eab5b7a2650 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -275,20 +275,18 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { // Converts an implementation in the AST to a vector of items. fn create_impl_from_item(&self, item: &Item) -> Vec { match item.node { - ItemImpl(_, _, _, ref opt_trait, _, ref ast_items) => { + ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => { let mut items: Vec = - ast_items.iter() - .map(|ast_item| { - match **ast_item { - ast::MethodImplItem(ref ast_method) => { - MethodTraitItemId( - local_def(ast_method.id)) - } - ast::TypeImplItem(ref typedef) => { - TypeTraitItemId(local_def(typedef.id)) - } - } - }).collect(); + impl_items.iter().map(|impl_item| { + match impl_item.node { + ast::MethodImplItem(_) => { + MethodTraitItemId(local_def(impl_item.id)) + } + ast::TypeImplItem(_) => { + TypeTraitItemId(local_def(impl_item.id)) + } + } + }).collect(); if opt_trait.is_some() { let trait_ref = ty::impl_id_to_trait_ref(self.crate_context.tcx, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 4d98aed8006b2..b90129f7ab7f8 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -631,18 +631,18 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // For each method, construct a suitable ty::Method and // store it into the `tcx.impl_or_trait_items` table: for trait_item in trait_items { - match **trait_item { + match trait_item.node { ast::RequiredMethod(_) | ast::ProvidedMethod(_) => { - let ty_method = Rc::new(match **trait_item { + let ty_method = Rc::new(match trait_item.node { ast::RequiredMethod(ref m) => { ty_method_of_trait_method( ccx, trait_id, &trait_def.generics, &trait_predicates, - &m.id, - &m.ident.name, + trait_item.id, + trait_item.ident, &m.explicit_self, m.abi, &m.generics, @@ -655,18 +655,15 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, trait_id, &trait_def.generics, &trait_predicates, - &m.id, - &m.pe_ident().name, + trait_item.id, + trait_item.ident, m.pe_explicit_self(), m.pe_abi(), m.pe_generics(), &m.pe_unsafety(), &*m.pe_fn_decl()) } - ast::TypeTraitItem(ref at) => { - tcx.sess.span_bug(at.ty_param.span, - "there shouldn't be a type trait item here") - } + ast::TypeTraitItem(..) => unreachable!() }); debug!("ty_method_of_trait_method yielded {} for method {} of trait {}", @@ -680,12 +677,12 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, .borrow_mut() .insert(ty_method.def_id, ty::MethodTraitItem(ty_method)); } - ast::TypeTraitItem(ref ast_associated_type) => { + ast::TypeTraitItem(..) => { let trait_did = local_def(trait_id); let associated_type = ty::AssociatedType { - name: ast_associated_type.ty_param.ident.name, + name: trait_item.ident.name, vis: ast::Public, - def_id: local_def(ast_associated_type.ty_param.id), + def_id: local_def(trait_item.id), container: TraitContainer(trait_did), }; @@ -698,20 +695,18 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } // Add an entry mapping - let trait_item_def_ids = - Rc::new(trait_items.iter().map(|ti| { - match **ti { - ast::RequiredMethod(ref ty_method) => { - ty::MethodTraitItemId(local_def(ty_method.id)) - } - ast::ProvidedMethod(ref method) => { - ty::MethodTraitItemId(local_def(method.id)) - } - ast::TypeTraitItem(ref typedef) => { - ty::TypeTraitItemId(local_def(typedef.ty_param.id)) - } + let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| { + let def_id = local_def(trait_item.id); + match trait_item.node { + ast::RequiredMethod(_) | + ast::ProvidedMethod(_) => { + ty::MethodTraitItemId(def_id) + } + ast::TypeTraitItem(..) => { + ty::TypeTraitItemId(def_id) } - }).collect()); + } + }).collect()); let trait_def_id = local_def(trait_id); tcx.trait_item_def_ids.borrow_mut().insert(trait_def_id, trait_item_def_ids); @@ -734,8 +729,8 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, trait_id: ast::NodeId, trait_generics: &ty::Generics<'tcx>, trait_bounds: &ty::GenericPredicates<'tcx>, - m_id: &ast::NodeId, - m_name: &ast::Name, + m_id: ast::NodeId, + m_ident: ast::Ident, m_explicit_self: &ast::ExplicitSelf, m_abi: abi::Abi, m_generics: &ast::Generics, @@ -760,14 +755,14 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, }; ty::Method::new( - *m_name, + m_ident.name, ty_generics, ty_generic_predicates, fty, explicit_self_category, // assume public, because this is only invoked on trait methods ast::Public, - local_def(*m_id), + local_def(m_id), TraitContainer(local_def(trait_id)), None ) @@ -815,12 +810,13 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, trait_def: &ty::TraitDef<'tcx>, - associated_type: &ast::AssociatedType) + ident: ast::Ident, + id: ast::NodeId) { let associated_type = Rc::new(ty::AssociatedType { - name: associated_type.ty_param.ident.name, + name: ident.name, vis: ast::Public, - def_id: local_def(associated_type.ty_param.id), + def_id: local_def(id), container: TraitContainer(trait_def.trait_ref.def_id), }); ccx.tcx @@ -831,12 +827,12 @@ fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>, container: ImplOrTraitItemContainer, - ms: I, + methods: I, untransformed_rcvr_ty: Ty<'tcx>, rcvr_ty_generics: &ty::Generics<'tcx>, rcvr_ty_predicates: &ty::GenericPredicates<'tcx>, rcvr_visibility: ast::Visibility) - where I: Iterator + where I: Iterator { debug!("convert_methods(untransformed_rcvr_ty={}, rcvr_ty_generics={}, rcvr_ty_predicates={})", untransformed_rcvr_ty.repr(ccx.tcx), @@ -845,24 +841,27 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>, let tcx = ccx.tcx; let mut seen_methods = FnvHashSet(); - for m in ms { - if !seen_methods.insert(m.pe_ident().repr(tcx)) { - span_err!(tcx.sess, m.span, E0201, "duplicate method in trait impl"); + for (m, id, ident, vis, span) in methods { + if !seen_methods.insert(ident.name) { + span_err!(tcx.sess, span, E0201, "duplicate method in trait impl"); } - let m_def_id = local_def(m.id); + let m_def_id = local_def(id); let mty = Rc::new(ty_of_method(ccx, container, m, + id, + ident, + vis, untransformed_rcvr_ty, rcvr_ty_generics, rcvr_ty_predicates, rcvr_visibility)); let fty = ty::mk_bare_fn(tcx, Some(m_def_id), tcx.mk_bare_fn(mty.fty.clone())); debug!("method {} (id {}) has type {}", - m.pe_ident().repr(tcx), - m.id, + ident.repr(tcx), + id, fty.repr(tcx)); tcx.tcache.borrow_mut().insert( m_def_id, @@ -872,7 +871,7 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>, }); tcx.predicates.borrow_mut().insert(m_def_id, mty.predicates.clone()); - write_ty_to_tcx(tcx, m.id, fty); + write_ty_to_tcx(tcx, id, fty); debug!("writing method type: def_id={:?} mty={}", mty.def_id, mty.repr(ccx.tcx)); @@ -885,6 +884,9 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>, fn ty_of_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, container: ImplOrTraitItemContainer, m: &ast::Method, + id: ast::NodeId, + ident: ast::Ident, + vis: ast::Visibility, untransformed_rcvr_ty: Ty<'tcx>, rcvr_ty_generics: &ty::Generics<'tcx>, rcvr_ty_predicates: &ty::GenericPredicates<'tcx>, @@ -909,15 +911,15 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>, // inherit the visibility from the impl (so `foo` in `pub impl // { fn foo(); }` is public, but private in `priv impl { fn // foo(); }`). - let method_vis = m.pe_vis().inherit_from(rcvr_visibility); + let method_vis = vis.inherit_from(rcvr_visibility); - ty::Method::new(m.pe_ident().name, + ty::Method::new(ident.name, m_ty_generics, m_ty_generic_predicates, fty, explicit_self_category, method_vis, - local_def(m.id), + local_def(id), container, None) } @@ -1011,62 +1013,67 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { it.vis }; - let mut methods = Vec::new(); for impl_item in impl_items { - match **impl_item { - ast::MethodImplItem(ref method) => { - methods.push(method); - } - ast::TypeImplItem(ref typedef) => { + match impl_item.node { + ast::MethodImplItem(_) => {} + ast::TypeImplItem(ref ty) => { if opt_trait_ref.is_none() { - span_err!(tcx.sess, typedef.span, E0202, + span_err!(tcx.sess, impl_item.span, E0202, "associated items are not allowed in inherent impls"); } - let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &*typedef.typ); - tcx.tcache.borrow_mut().insert(local_def(typedef.id), + let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty); + tcx.tcache.borrow_mut().insert(local_def(impl_item.id), TypeScheme { generics: ty::Generics::empty(), ty: typ, }); - tcx.predicates.borrow_mut().insert(local_def(typedef.id), + tcx.predicates.borrow_mut().insert(local_def(impl_item.id), ty::GenericPredicates::empty()); - write_ty_to_tcx(tcx, typedef.id, typ); + write_ty_to_tcx(tcx, impl_item.id, typ); let associated_type = Rc::new(ty::AssociatedType { - name: typedef.ident.name, - vis: typedef.vis, - def_id: local_def(typedef.id), + name: impl_item.ident.name, + vis: impl_item.vis, + def_id: local_def(impl_item.id), container: ty::ImplContainer(local_def(it.id)), }); tcx.impl_or_trait_items .borrow_mut() - .insert(local_def(typedef.id), + .insert(local_def(impl_item.id), ty::TypeTraitItem(associated_type)); } } } + let methods = impl_items.iter().filter_map(|ii| { + match ii.node { + ast::MethodImplItem(ref m) => { + Some((m, ii.id, ii.ident, ii.vis, ii.span)) + } + ast::TypeImplItem(_) => None + } + }); convert_methods(ccx, ImplContainer(local_def(it.id)), - methods.into_iter(), + methods, selfty, &ty_generics, &ty_predicates, parent_visibility); for impl_item in impl_items { - match **impl_item { + match impl_item.node { ast::MethodImplItem(ref method) => { let body_id = method.pe_body().id; check_method_self_type(ccx, &BindingRscope::new(), - ccx.method_ty(method.id), + ccx.method_ty(impl_item.id), selfty, method.pe_explicit_self(), body_id); } - ast::TypeImplItem(..) => { } + ast::TypeImplItem(_) => {} } } @@ -1092,15 +1099,20 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { debug!("convert: trait_bounds={:?}", trait_predicates); + let methods = trait_items.iter().filter_map(|ti| { + match ti.node { + ast::ProvidedMethod(ref m) => { + Some((m, ti.id, ti.ident, ast::Inherited, ti.span)) + } + ast::RequiredMethod(_) | + ast::TypeTraitItem(..) => None, + } + }); // Run convert_methods on the provided methods. let untransformed_rcvr_ty = ty::mk_self_type(tcx); convert_methods(ccx, TraitContainer(local_def(it.id)), - trait_items.iter().filter_map(|m| match **m { - ast::RequiredMethod(_) => None, - ast::ProvidedMethod(ref m) => Some(m), - ast::TypeTraitItem(_) => None, - }), + methods, untransformed_rcvr_ty, &trait_def.generics, &trait_predicates, @@ -1115,12 +1127,12 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { // we have a method type stored for every method. for trait_item in trait_items { let self_type = ty::mk_self_type(tcx); - match **trait_item { + match trait_item.node { ast::RequiredMethod(ref type_method) => { let rscope = BindingRscope::new(); check_method_self_type(ccx, &rscope, - ccx.method_ty(type_method.id), + ccx.method_ty(trait_item.id), self_type, &type_method.explicit_self, it.id) @@ -1128,15 +1140,16 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { ast::ProvidedMethod(ref method) => { check_method_self_type(ccx, &BindingRscope::new(), - ccx.method_ty(method.id), + ccx.method_ty(trait_item.id), self_type, method.pe_explicit_self(), it.id) } - ast::TypeTraitItem(ref associated_type) => { + ast::TypeTraitItem(..) => { convert_associated_type(ccx, &*trait_def, - associated_type); + trait_item.ident, + trait_item.id); } } } @@ -1348,15 +1361,12 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics); - let associated_type_names: Vec<_> = - items.iter() - .filter_map(|item| { - match **item { - ast::RequiredMethod(_) | ast::ProvidedMethod(_) => None, - ast::TypeTraitItem(ref data) => Some(data.ty_param.ident.name), - } - }) - .collect(); + let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| { + match trait_item.node { + ast::RequiredMethod(_) | ast::ProvidedMethod(_) => None, + ast::TypeTraitItem(..) => Some(trait_item.ident.name), + } + }).collect(); let trait_ref = Rc::new(ty::TraitRef { def_id: def_id, @@ -1423,13 +1433,12 @@ fn trait_defines_associated_type_named(ccx: &CrateCtxt, _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id)) }; - trait_items.iter() - .any(|trait_item| { - match *trait_item { - ast::TypeTraitItem(ref t) => t.ty_param.ident.name == assoc_name, - ast::RequiredMethod(..) | ast::ProvidedMethod(..) => false, - } - }) + trait_items.iter().any(|trait_item| { + match trait_item.node { + ast::TypeTraitItem(..) => trait_item.ident.name == assoc_name, + ast::RequiredMethod(_) | ast::ProvidedMethod(_) => false, + } + }) } fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item) { @@ -1484,29 +1493,26 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item) trait_items: &[P]) -> Vec> { - trait_items - .iter() - .flat_map(|trait_item| { - let assoc_type_def = match **trait_item { - ast::TypeTraitItem(ref assoc_type) => &assoc_type.ty_param, - ast::RequiredMethod(..) | ast::ProvidedMethod(..) => { - return vec!().into_iter(); - } - }; + trait_items.iter().flat_map(|trait_item| { + let bounds = match trait_item.node { + ast::TypeTraitItem(ref bounds, _) => bounds, + ast::RequiredMethod(..) | ast::ProvidedMethod(..) => { + return vec!().into_iter(); + } + }; - let assoc_ty = ty::mk_projection(ccx.tcx, - self_trait_ref.clone(), - assoc_type_def.ident.name); + let assoc_ty = ty::mk_projection(ccx.tcx, + self_trait_ref.clone(), + trait_item.ident.name); - let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)), - assoc_ty, - &*assoc_type_def.bounds, - SizedByDefault::Yes, - assoc_type_def.span); + let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)), + assoc_ty, + bounds, + SizedByDefault::Yes, + trait_item.span); - ty::predicates(ccx.tcx, assoc_ty, &bounds).into_iter() - }) - .collect() + ty::predicates(ccx.tcx, assoc_ty, &bounds).into_iter() + }).collect() } } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index db41bf9fee329..9f7b68f38fa6e 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -147,29 +147,13 @@ pub fn record_extern_fqn(cx: &DocContext, did: ast::DefId, kind: clean::TypeKind pub fn build_external_trait(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::Trait { - use clean::TraitMethod; - let def = ty::lookup_trait_def(tcx, did); let trait_items = ty::trait_items(tcx, did).clean(cx); - let provided = ty::provided_trait_methods(tcx, did); - let items = trait_items.into_iter().map(|trait_item| { - match trait_item.inner { - clean::TyMethodItem(_) => { - if provided.iter().any(|a| a.def_id == trait_item.def_id) { - TraitMethod::ProvidedMethod(trait_item) - } else { - TraitMethod::RequiredMethod(trait_item) - } - }, - clean::AssociatedTypeItem(_) => TraitMethod::TypeTraitItem(trait_item), - _ => unreachable!() - } - }); let predicates = ty::lookup_predicates(tcx, did); clean::Trait { unsafety: def.unsafety, generics: (&def.generics, &predicates, subst::TypeSpace).clean(cx), - items: items.collect(), + items: trait_items, bounds: vec![], // supertraits can be found in the list of predicates } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c39451b15ada5..202b5f59fb7bb 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -11,7 +11,6 @@ //! This module contains the "cleaned" pieces of the AST, and the functions //! that clean them. -pub use self::ImplMethod::*; pub use self::Type::*; pub use self::PrimitiveType::*; pub use self::TypeKind::*; @@ -24,7 +23,6 @@ pub use self::Attribute::*; pub use self::TyParamBound::*; pub use self::SelfTy::*; pub use self::FunctionRetTy::*; -pub use self::TraitMethod::*; use syntax; use syntax::abi; @@ -70,7 +68,7 @@ pub trait Clean { fn clean(&self, cx: &DocContext) -> T; } -impl, U> Clean> for Vec { +impl, U> Clean> for [T] { fn clean(&self, cx: &DocContext) -> Vec { self.iter().map(|x| x.clean(cx)).collect() } @@ -339,7 +337,7 @@ pub enum ItemEnum { ForeignStaticItem(Static), MacroItem(Macro), PrimitiveItem(PrimitiveType), - AssociatedTypeItem(TyParam), + AssociatedTypeItem(Vec, Option), } #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] @@ -951,8 +949,8 @@ pub struct Method { pub abi: abi::Abi } -impl Clean for ast::Method { - fn clean(&self, cx: &DocContext) -> Item { +impl Clean for ast::Method { + fn clean(&self, cx: &DocContext) -> Method { let all_inputs = &self.pe_fn_decl().inputs; let inputs = match self.pe_explicit_self().node { ast::SelfStatic => &**all_inputs, @@ -960,25 +958,17 @@ impl Clean for ast::Method { }; let decl = FnDecl { inputs: Arguments { - values: inputs.iter().map(|x| x.clean(cx)).collect(), + values: inputs.clean(cx), }, output: self.pe_fn_decl().output.clean(cx), attrs: Vec::new() }; - Item { - name: Some(self.pe_ident().clean(cx)), - attrs: self.attrs.clean(cx), - source: self.span.clean(cx), - def_id: ast_util::local_def(self.id), - visibility: self.pe_vis().clean(cx), - stability: get_stability(cx, ast_util::local_def(self.id)), - inner: MethodItem(Method { - generics: self.pe_generics().clean(cx), - self_: self.pe_explicit_self().node.clean(cx), - unsafety: self.pe_unsafety().clone(), - decl: decl, - abi: self.pe_abi() - }), + Method { + generics: self.pe_generics().clean(cx), + self_: self.pe_explicit_self().node.clean(cx), + unsafety: self.pe_unsafety().clone(), + decl: decl, + abi: self.pe_abi() } } } @@ -992,33 +982,25 @@ pub struct TyMethod { pub abi: abi::Abi } -impl Clean for ast::TypeMethod { - fn clean(&self, cx: &DocContext) -> Item { +impl Clean for ast::TypeMethod { + fn clean(&self, cx: &DocContext) -> TyMethod { let inputs = match self.explicit_self.node { ast::SelfStatic => &*self.decl.inputs, _ => &self.decl.inputs[1..] }; let decl = FnDecl { inputs: Arguments { - values: inputs.iter().map(|x| x.clean(cx)).collect(), + values: inputs.clean(cx), }, output: self.decl.output.clean(cx), attrs: Vec::new() }; - Item { - name: Some(self.ident.clean(cx)), - attrs: self.attrs.clean(cx), - source: self.span.clean(cx), - def_id: ast_util::local_def(self.id), - visibility: None, - stability: get_stability(cx, ast_util::local_def(self.id)), - inner: TyMethodItem(TyMethod { - unsafety: self.unsafety.clone(), - decl: decl, - self_: self.explicit_self.node.clean(cx), - generics: self.generics.clean(cx), - abi: self.abi - }), + TyMethod { + unsafety: self.unsafety.clone(), + decl: decl, + self_: self.explicit_self.node.clean(cx), + generics: self.generics.clean(cx), + abi: self.abi } } } @@ -1166,7 +1148,7 @@ impl Clean for ast::FunctionRetTy { #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Trait { pub unsafety: ast::Unsafety, - pub items: Vec, + pub items: Vec, pub generics: Generics, pub bounds: Vec, } @@ -1205,64 +1187,48 @@ impl Clean for ast::PolyTraitRef { } } -/// An item belonging to a trait, whether a method or associated. Could be named -/// TraitItem except that's already taken by an exported enum variant. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] -pub enum TraitMethod { - RequiredMethod(Item), - ProvidedMethod(Item), - TypeTraitItem(Item), // an associated type -} - -impl TraitMethod { - pub fn is_req(&self) -> bool { - match self { - &RequiredMethod(..) => true, - _ => false, - } - } - pub fn is_def(&self) -> bool { - match self { - &ProvidedMethod(..) => true, - _ => false, - } - } - pub fn is_type(&self) -> bool { - match self { - &TypeTraitItem(..) => true, - _ => false, - } - } - pub fn item<'a>(&'a self) -> &'a Item { - match *self { - RequiredMethod(ref item) => item, - ProvidedMethod(ref item) => item, - TypeTraitItem(ref item) => item, - } - } -} - -impl Clean for ast::TraitItem { - fn clean(&self, cx: &DocContext) -> TraitMethod { - match self { - &ast::RequiredMethod(ref t) => RequiredMethod(t.clean(cx)), - &ast::ProvidedMethod(ref t) => ProvidedMethod(t.clean(cx)), - &ast::TypeTraitItem(ref t) => TypeTraitItem(t.clean(cx)), +impl Clean for ast::TraitItem { + fn clean(&self, cx: &DocContext) -> Item { + let inner = match self.node { + ast::ProvidedMethod(ref m) => MethodItem(m.clean(cx)), + ast::RequiredMethod(ref m) => TyMethodItem(m.clean(cx)), + ast::TypeTraitItem(ref bounds, ref default) => { + AssociatedTypeItem(bounds.clean(cx), default.clean(cx)) + } + }; + Item { + name: Some(self.ident.clean(cx)), + attrs: self.attrs.clean(cx), + source: self.span.clean(cx), + def_id: ast_util::local_def(self.id), + visibility: None, + stability: get_stability(cx, ast_util::local_def(self.id)), + inner: inner } } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] -pub enum ImplMethod { - MethodImplItem(Item), - TypeImplItem(Item), -} - -impl Clean for ast::ImplItem { - fn clean(&self, cx: &DocContext) -> ImplMethod { - match self { - &ast::MethodImplItem(ref t) => MethodImplItem(t.clean(cx)), - &ast::TypeImplItem(ref t) => TypeImplItem(t.clean(cx)), +impl Clean for ast::ImplItem { + fn clean(&self, cx: &DocContext) -> Item { + let inner = match self.node { + ast::MethodImplItem(ref m) => MethodItem(m.clean(cx)), + ast::TypeImplItem(ref ty) => TypedefItem(Typedef { + type_: ty.clean(cx), + generics: Generics { + lifetimes: Vec::new(), + type_params: Vec::new(), + where_predicates: Vec::new() + }, + }), + }; + Item { + name: Some(self.ident.clean(cx)), + source: self.span.clean(cx), + attrs: self.attrs.clean(cx), + def_id: ast_util::local_def(self.id), + visibility: self.vis.clean(cx), + stability: get_stability(cx, ast_util::local_def(self.id)), + inner: inner } } } @@ -2128,12 +2094,7 @@ impl Clean for doctree::Impl { generics: self.generics.clean(cx), trait_: self.trait_.clean(cx), for_: self.for_.clean(cx), - items: self.items.clean(cx).into_iter().map(|ti| { - match ti { - MethodImplItem(i) => i, - TypeImplItem(i) => i, - } - }).collect(), + items: self.items.clean(cx), derived: detect_derived(&self.attrs), polarity: Some(self.polarity.clean(cx)), }), @@ -2500,37 +2461,15 @@ impl Clean for attr::Stability { } } -impl Clean for ast::AssociatedType { - fn clean(&self, cx: &DocContext) -> Item { - Item { - source: self.ty_param.span.clean(cx), - name: Some(self.ty_param.ident.clean(cx)), - attrs: self.attrs.clean(cx), - inner: AssociatedTypeItem(self.ty_param.clean(cx)), - visibility: None, - def_id: ast_util::local_def(self.ty_param.id), - stability: None, - } - } -} - impl Clean for ty::AssociatedType { fn clean(&self, cx: &DocContext) -> Item { Item { source: DUMMY_SP.clean(cx), name: Some(self.name.clean(cx)), attrs: Vec::new(), - inner: AssociatedTypeItem(TyParam { - name: self.name.clean(cx), - did: ast::DefId { - krate: 0, - node: ast::DUMMY_NODE_ID - }, - // FIXME(#20727): bounds are missing and need to be filled in from the - // predicates on the trait itself - bounds: vec![], - default: None, - }), + // FIXME(#20727): bounds are missing and need to be filled in from the + // predicates on the trait itself + inner: AssociatedTypeItem(vec![], None), visibility: None, def_id: self.def_id, stability: None, @@ -2538,27 +2477,6 @@ impl Clean for ty::AssociatedType { } } -impl Clean for ast::Typedef { - fn clean(&self, cx: &DocContext) -> Item { - Item { - source: self.span.clean(cx), - name: Some(self.ident.clean(cx)), - attrs: self.attrs.clean(cx), - inner: TypedefItem(Typedef { - type_: self.typ.clean(cx), - generics: Generics { - lifetimes: Vec::new(), - type_params: Vec::new(), - where_predicates: Vec::new() - }, - }), - visibility: None, - def_id: ast_util::local_def(self.id), - stability: None, - } - } -} - impl<'a> Clean for (ty::TypeScheme<'a>, ty::GenericPredicates<'a>, ParamSpace) { fn clean(&self, cx: &DocContext) -> Typedef { let (ref ty_scheme, ref predicates, ps) = *self; diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index 4f277cc868a1a..cdeeacfb78397 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -40,37 +40,13 @@ pub trait DocFolder : Sized { EnumItem(i) }, TraitItem(mut i) => { - fn vtrm(this: &mut T, trm: TraitMethod) - -> Option { - match trm { - RequiredMethod(it) => { - match this.fold_item(it) { - Some(x) => return Some(RequiredMethod(x)), - None => return None, - } - }, - ProvidedMethod(it) => { - match this.fold_item(it) { - Some(x) => return Some(ProvidedMethod(x)), - None => return None, - } - }, - TypeTraitItem(it) => { - match this.fold_item(it) { - Some(x) => return Some(TypeTraitItem(x)), - None => return None, - } - } - } - } let mut foo = Vec::new(); swap(&mut foo, &mut i.items); - i.items.extend(foo.into_iter().filter_map(|x| vtrm(self, x))); + i.items.extend(foo.into_iter().filter_map(|x| self.fold_item(x))); TraitItem(i) }, ImplItem(mut i) => { let mut foo = Vec::new(); swap(&mut foo, &mut i.items); - i.items.extend(foo.into_iter() - .filter_map(|x| self.fold_item(x))); + i.items.extend(foo.into_iter().filter_map(|x| self.fold_item(x))); ImplItem(i) }, VariantItem(i) => { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 46c7a70195485..dba7b16eceecb 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1685,9 +1685,15 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, bounds, WhereClause(&t.generics))); - let types = t.items.iter().filter(|m| m.is_type()).collect::>(); - let required = t.items.iter().filter(|m| m.is_req()).collect::>(); - let provided = t.items.iter().filter(|m| m.is_def()).collect::>(); + let types = t.items.iter().filter(|m| { + match m.inner { clean::AssociatedTypeItem(..) => true, _ => false } + }).collect::>(); + let required = t.items.iter().filter(|m| { + match m.inner { clean::TyMethodItem(_) => true, _ => false } + }).collect::>(); + let provided = t.items.iter().filter(|m| { + match m.inner { clean::MethodItem(_) => true, _ => false } + }).collect::>(); if t.items.len() == 0 { try!(write!(w, "{{ }}")); @@ -1695,7 +1701,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, try!(write!(w, "{{\n")); for t in &types { try!(write!(w, " ")); - try!(render_method(w, t.item())); + try!(render_method(w, t)); try!(write!(w, ";\n")); } if types.len() > 0 && required.len() > 0 { @@ -1703,7 +1709,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, } for m in &required { try!(write!(w, " ")); - try!(render_method(w, m.item())); + try!(render_method(w, m)); try!(write!(w, ";\n")); } if required.len() > 0 && provided.len() > 0 { @@ -1711,7 +1717,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, } for m in &provided { try!(write!(w, " ")); - try!(render_method(w, m.item())); + try!(render_method(w, m)); try!(write!(w, " {{ ... }}\n")); } try!(write!(w, "}}")); @@ -1721,15 +1727,15 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, // Trait documentation try!(document(w, it)); - fn trait_item(w: &mut fmt::Formatter, m: &clean::TraitMethod) + fn trait_item(w: &mut fmt::Formatter, m: &clean::Item) -> fmt::Result { try!(write!(w, "

{}", - shortty(m.item()), - *m.item().name.as_ref().unwrap(), - ConciseStability(&m.item().stability))); - try!(render_method(w, m.item())); + shortty(m), + *m.name.as_ref().unwrap(), + ConciseStability(&m.stability))); + try!(render_method(w, m)); try!(write!(w, "

")); - try!(document(w, m.item())); + try!(document(w, m)); Ok(()) } @@ -1798,12 +1804,14 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, } fn assoc_type(w: &mut fmt::Formatter, it: &clean::Item, - typ: &clean::TyParam) -> fmt::Result { + bounds: &Vec, + default: &Option) + -> fmt::Result { try!(write!(w, "type {}", it.name.as_ref().unwrap())); - if typ.bounds.len() > 0 { - try!(write!(w, ": {}", TyParamBounds(&*typ.bounds))) + if bounds.len() > 0 { + try!(write!(w, ": {}", TyParamBounds(bounds))) } - if let Some(ref default) = typ.default { + if let Some(ref default) = *default { try!(write!(w, " = {}", default)); } Ok(()) @@ -1839,8 +1847,8 @@ fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result { clean::MethodItem(ref m) => { method(w, meth, m.unsafety, m.abi, &m.generics, &m.self_, &m.decl) } - clean::AssociatedTypeItem(ref typ) => { - assoc_type(w, meth, typ) + clean::AssociatedTypeItem(ref bounds, ref default) => { + assoc_type(w, meth, bounds, default) } _ => panic!("render_method called on non-method") } @@ -2138,13 +2146,13 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result { try!(write!(w, "type {} = {}", name, tydef.type_)); try!(write!(w, "\n")); } - clean::AssociatedTypeItem(ref typaram) => { + clean::AssociatedTypeItem(ref bounds, ref default) => { let name = item.name.as_ref().unwrap(); try!(write!(w, "

{}", *name, shortty(item), ConciseStability(&item.stability))); - try!(assoc_type(w, item, typaram)); + try!(assoc_type(w, item, bounds, default)); try!(write!(w, "

\n")); } _ => panic!("can't make docs for trait item with name {:?}", item.name) @@ -2167,13 +2175,13 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result { t: &clean::Trait, i: &clean::Impl) -> fmt::Result { for trait_item in &t.items { - let n = trait_item.item().name.clone(); + let n = trait_item.name.clone(); match i.items.iter().find(|m| { m.name == n }) { Some(..) => continue, None => {} } - try!(doctraititem(w, trait_item.item(), false)); + try!(doctraititem(w, trait_item, false)); } Ok(()) } diff --git a/src/librustdoc/stability_summary.rs b/src/librustdoc/stability_summary.rs index 47918ba78a270..0726a822b59b7 100644 --- a/src/librustdoc/stability_summary.rs +++ b/src/librustdoc/stability_summary.rs @@ -20,8 +20,8 @@ use syntax::attr::{Unstable, Stable}; use syntax::ast::Public; use clean::{Crate, Item, ModuleItem, Module, EnumItem, Enum}; -use clean::{ImplItem, Impl, Trait, TraitItem, TraitMethod, ProvidedMethod, RequiredMethod}; -use clean::{TypeTraitItem, ExternCrateItem, ImportItem, PrimitiveItem, Stability}; +use clean::{ImplItem, Impl, Trait, TraitItem}; +use clean::{ExternCrateItem, ImportItem, PrimitiveItem, Stability}; use html::render::cache; @@ -140,11 +140,11 @@ fn summarize_item(item: &Item) -> (Counts, Option) { // considered to have no children. match item.inner { // Require explicit `pub` to be visible - ImplItem(Impl { items: ref subitems, trait_: None, .. }) => { - let subcounts = subitems.iter().filter(|i| visible(*i)) - .map(summarize_item) - .map(|s| s.0) - .fold(Counts::zero(), |acc, x| acc + x); + ImplItem(Impl { ref items, trait_: None, .. }) => { + let subcounts = items.iter().filter(|i| visible(*i)) + .map(summarize_item) + .map(|s| s.0) + .fold(Counts::zero(), |acc, x| acc + x); (subcounts, None) } // `pub` automatically @@ -154,22 +154,10 @@ fn summarize_item(item: &Item) -> (Counts, Option) { .fold(Counts::zero(), |acc, x| acc + x); (item_counts + subcounts, None) } - TraitItem(Trait { - items: ref trait_items, - .. - }) => { - fn extract_item<'a>(trait_item: &'a TraitMethod) -> &'a Item { - match *trait_item { - ProvidedMethod(ref item) | - RequiredMethod(ref item) | - TypeTraitItem(ref item) => item - } - } - let subcounts = trait_items.iter() - .map(extract_item) - .map(summarize_item) - .map(|s| s.0) - .fold(Counts::zero(), |acc, x| acc + x); + TraitItem(Trait { ref items, .. }) => { + let subcounts = items.iter().map(summarize_item) + .map(|s| s.0) + .fold(Counts::zero(), |acc, x| acc + x); (item_counts + subcounts, None) } ModuleItem(Module { ref items, .. }) => { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index fafcc056dedfb..bc1767fa3a44d 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,7 @@ pub use self::LocalSource::*; pub use self::Mac_::*; pub use self::MacStmtStyle::*; pub use self::MetaItem_::*; -pub use self::Method_::*; +pub use self::Method::*; pub use self::Mutability::*; pub use self::Pat_::*; pub use self::PathListItem_::*; @@ -44,7 +44,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::*; @@ -1062,16 +1062,11 @@ pub struct TypeField { /// one without a default implementation #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct TypeMethod { - pub ident: Ident, - pub attrs: Vec, pub unsafety: Unsafety, pub abi: Abi, pub decl: P, 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 +1074,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(Method), - TypeTraitItem(AssociatedType), -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum ImplItem { - MethodImplItem(Method), - TypeImplItem(Typedef), +pub struct TraitItem { + pub id: NodeId, + pub ident: Ident, + pub attrs: Vec, + pub node: TraitItem_, + pub span: Span, } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct AssociatedType { - pub attrs: Vec, - pub ty_param: TyParam, +pub enum TraitItem_ { + RequiredMethod(TypeMethod), + ProvidedMethod(Method), + TypeTraitItem(TyParamBounds, Option>), } #[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, - pub typ: P, + pub node: ImplItem_, + pub span: Span, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum ImplItem_ { + MethodImplItem(Method), + TypeImplItem(P), } #[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Copy)] @@ -1419,24 +1417,14 @@ pub enum ExplicitSelf_ { pub type ExplicitSelf = Spanned; #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct Method { - pub attrs: Vec, - pub id: NodeId, - pub span: Span, - pub node: Method_, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum Method_ { +pub enum Method { /// Represents a method declaration - MethDecl(Ident, - Generics, + MethDecl(Generics, Abi, ExplicitSelf, Unsafety, P, - P, - Visibility), + P), /// Represents a macro in method position MethMac(Mac), } @@ -1726,8 +1714,8 @@ impl ForeignItem_ { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum InlinedItem { IIItem(P), - IITraitItem(DefId /* impl id */, TraitItem), - IIImplItem(DefId /* impl id */, ImplItem), + IITraitItem(DefId /* impl id */, P), + IIImplItem(DefId /* impl id */, P), IIForeign(P), } diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs index 8d605ea50cda6..053c315334088 100644 --- a/src/libsyntax/ast_map/blocks.rs +++ b/src/libsyntax/ast_map/blocks.rs @@ -65,7 +65,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::ProvidedMethod(_) => true, _ => false, } } } @@ -156,25 +156,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(), + |_, _, m: &'a ast::Method, _| m.pe_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(), + |_, _, m: &'a ast::Method, _| m.pe_fn_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::Method, 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::Method, _| id, |c: ClosureParts| c.id) } @@ -185,15 +185,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, m: &'a ast::Method, _| { + visit::FkMethod(ident, m) }; self.handle(item, method, closure) } fn handle(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::Method, Span) -> A, C: FnOnce(ClosureParts<'a>) -> A, { match self.node { @@ -205,13 +205,13 @@ 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::ProvidedMethod(ref m) => method(ti.id, ti.ident, m, ti.span), _ => panic!("trait method FnLikeNode that is not fn-like"), }, ast_map::NodeImplItem(ii) => { - match *ii { - ast::MethodImplItem(ref m) => method(m), + match ii.node { + ast::MethodImplItem(ref m) => method(ii.id, ii.ident, m, ii.span), ast::TypeImplItem(_) => { 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 4db6f9bc3c52b..606c6b640df2e 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -14,7 +14,7 @@ use self::MapEntry::*; use abi; use ast::*; -use ast_util::{self, PostExpansionMethod}; +use ast_util; use codemap::{DUMMY_SP, Span, Spanned}; use fold::Folder; use parse::token; @@ -374,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) } @@ -458,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. @@ -505,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, @@ -650,31 +603,8 @@ impl Named for Spanned { 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 { @@ -739,12 +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 { - let id = match **impl_item { - MethodImplItem(ref m) => m.id, - TypeImplItem(ref t) => t.id, - }; - self.insert(id, NodeImplItem(impl_item)); + for ii in impl_items { + self.insert(ii.id, NodeImplItem(ii)); } } ItemEnum(ref enum_definition, _) => { @@ -773,13 +699,8 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { } } - for tm in trait_items { - let id = match **tm { - RequiredMethod(ref m) => m.id, - ProvidedMethod(ref m) => m.id, - TypeTraitItem(ref typ) => typ.ty_param.id, - }; - self.insert(id, NodeTraitItem(tm)); + for ti in trait_items { + self.insert(ti.id, NodeTraitItem(ti)); } } _ => {} @@ -788,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... @@ -807,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) { @@ -911,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(fld.fold_associated_type(at))) - } - }, - 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(fld.fold_typedef(t))) - } - }, + 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)) }; @@ -959,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; @@ -993,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), @@ -1041,48 +927,39 @@ 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 { + Some(NodeImplItem(ii)) => { + match ii.node { MethodImplItem(ref m) => { - match m.node { - MethDecl(ident, _, _, _, _, _, _, _) => + match *m { + MethDecl(..) => format!("method {} in {}{}", - token::get_ident(ident), + 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) } } - TypeImplItem(ref t) => { + TypeImplItem(_) => { format!("assoc type {} in {}{}", - token::get_ident(t.ident), + token::get_ident(ii.ident), map.path_to_string(id), id_str) } } } - Some(NodeTraitItem(ref tm)) => { - match **tm { - RequiredMethod(ref m) => { - format!("required method {} in {}{}", - token::get_ident(m.ident), - map.path_to_string(id), - id_str) - } - ProvidedMethod(ref m) => { - format!("provided method {} in {}{}", - token::get_ident(m.pe_ident()), - map.path_to_string(id), - id_str) - } - TypeTraitItem(ref t) => { - format!("assoc type {} in {}{}", - token::get_ident(t.ty_param.ident), - map.path_to_string(id), - id_str) - } - } + Some(NodeTraitItem(ti)) => { + let kind = match ti.node { + RequiredMethod(_) => "required method", + ProvidedMethod(_) => "provided method", + TypeTraitItem(..) => "assoc type", + }; + + format!("{} {} in {}{}", + kind, + token::get_ident(ti.ident), + map.path_to_string(id), + id_str) } Some(NodeVariant(ref variant)) => { format!("variant {} in {}{}", diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index a8804b595d403..673ea4ac43151 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -457,10 +457,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(_, m) => { + self.visit_generics_helper(m.pe_generics()) + } visit::FkFnBlock => {} } @@ -496,13 +498,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) { @@ -650,20 +653,18 @@ pub fn lit_is_str(lit: &Lit) -> bool { /// 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 { + match *self { $field_pat => $result, MethMac(_) => { panic!("expected an AST without macro invocations"); @@ -675,20 +676,18 @@ macro_rules! mf_method{ impl PostExpansionMethod for Method { - mf_method! { pe_ident,ast::Ident,MethDecl(ident,_,_,_,_,_,_,_),ident } mf_method! { pe_generics,&'a ast::Generics, - MethDecl(_,ref generics,_,_,_,_,_,_),generics + MethDecl(ref generics,_,_,_,_,_),generics } - mf_method! { pe_abi,Abi,MethDecl(_,_,abi,_,_,_,_,_),abi } + mf_method! { pe_abi,Abi,MethDecl(_,abi,_,_,_,_),abi } mf_method! { pe_explicit_self,&'a ast::ExplicitSelf, - MethDecl(_,_,_,ref explicit_self,_,_,_,_),explicit_self + 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 } + 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 } } #[cfg(test)] diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index dfe3477bddc3b..489a7721d7ba7 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -118,13 +118,13 @@ fn fold_item_underscore(cx: &mut Context, 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(cx: &mut Context, item: &ast::ForeignItem) -> bool return (cx.in_cfg)(&item.attrs); } -fn trait_method_in_cfg(cx: &mut Context, 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(cx: &mut Context, 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], attrs: &[ast::Attribute]) -> bool { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index b999680ff1a9a..cad5f97a4a5bb 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -77,23 +77,16 @@ impl ItemModifier for F #[derive(Debug,Clone)] pub enum Annotatable { Item(P), - TraitItem(ast::TraitItem), - ImplItem(ast::ImplItem), + TraitItem(P), + ImplItem(P), } impl Annotatable { pub fn attrs(&self) -> &[ast::Attribute] { match *self { Annotatable::Item(ref i) => &i.attrs, - Annotatable::TraitItem(ref i) => match *i { - ast::RequiredMethod(ref tm) => &tm.attrs, - ast::ProvidedMethod(ref m) => &m.attrs, - ast::TypeTraitItem(ref at) => &at.attrs, - }, - Annotatable::ImplItem(ref i) => match *i { - ast::MethodImplItem(ref m) => &m.attrs, - ast::TypeImplItem(ref t) => &t.attrs, - } + Annotatable::TraitItem(ref ti) => &ti.attrs, + Annotatable::ImplItem(ref ii) => &ii.attrs, } } @@ -103,20 +96,12 @@ impl Annotatable { attrs: attrs, ..i })), - Annotatable::TraitItem(i) => Annotatable::TraitItem(match i { - ast::RequiredMethod(tm) => - ast::RequiredMethod(ast::TypeMethod { attrs: attrs, ..tm }), - ast::ProvidedMethod(m) => - ast::ProvidedMethod(ast::Method { attrs: attrs, ..m }), - ast::TypeTraitItem(at) => - ast::TypeTraitItem(ast::AssociatedType { attrs: attrs, ..at }), - }), - Annotatable::ImplItem(i) => Annotatable::ImplItem(match i { - ast::MethodImplItem(m) => - ast::MethodImplItem(ast::Method { attrs: attrs, ..m }), - ast::TypeImplItem(t) => - ast::TypeImplItem(ast::Typedef { attrs: attrs, ..t }), - }) + 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 } + })), } } @@ -127,14 +112,14 @@ impl Annotatable { } } - pub fn expect_trait_item(self) -> ast::TraitItem { + pub fn expect_trait_item(self) -> P { match self { Annotatable::TraitItem(i) => i, _ => panic!("expected Item") } } - pub fn expect_impl_item(self) -> ast::ImplItem { + pub fn expect_impl_item(self) -> P { match self { Annotatable::ImplItem(i) => i, _ => panic!("expected Item") @@ -244,7 +229,7 @@ pub trait MacResult { } /// Create zero or more methods. - fn make_methods(self: Box) -> Option> { + fn make_methods(self: Box) -> Option>> { None } @@ -290,7 +275,7 @@ make_MacEager! { expr: P, pat: P, items: SmallVector>, - methods: SmallVector, + methods: SmallVector>, stmt: P, } @@ -303,7 +288,7 @@ impl MacResult for MacEager { self.items } - fn make_methods(self: Box) -> Option> { + fn make_methods(self: Box) -> Option>> { self.methods } @@ -392,7 +377,7 @@ impl MacResult for DummyResult { Some(SmallVector::zero()) } } - fn make_methods(self: Box) -> Option> { + fn make_methods(self: Box) -> Option>> { if self.expr_only { None } else { @@ -500,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 0573289150c84..a4962afff3c01 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -386,23 +386,23 @@ impl<'a> TraitDef<'a> { cx: &mut ExtCtxt, type_ident: Ident, generics: &Generics, - methods: Vec) -> P { + methods: Vec>) -> P { 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)| { - 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 - ), - } + )), + }) }); let Generics { mut lifetimes, ty_params, mut where_clause } = @@ -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_) - }) - ).map(P).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)> , - body: P) -> ast::Method { + body: P) -> P { // create the generics that aren't for Self let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics); @@ -725,19 +718,20 @@ impl<'a> MethodDef<'a> { let body_block = cx.block_expr(body); // Create the method. - 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::MethDecl(fn_generics, + abi, + explicit_self, + ast::Unsafety::Normal, + fn_decl, + body_block)) + }) } /// ``` diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 96859b94f1dde..5fb0126cdd09c 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -25,6 +25,7 @@ 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; @@ -1174,29 +1175,42 @@ 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)))) + 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 + }), + _ => 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() } - ast::TraitItem::TypeTraitItem(t) => { - SmallVector::one(Annotatable::TraitItem( - ast::TraitItem::TypeTraitItem(fld.fold_associated_type(t)))) + _ => { + fold::noop_fold_trait_item(it, fld).into_iter() + .map(|ti| Annotatable::TraitItem(ti)).collect() } }, - 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(fld.fold_typedef(t)))) - } + Annotatable::ImplItem(ii) => { + expand_method(ii, fld).into_iter().map(Annotatable::ImplItem).collect() } }; @@ -1204,21 +1218,6 @@ fn expand_annotatable(a: Annotatable, new_items } -fn expand_trait_item(i: ast::TraitItem, - fld: &mut MacroExpander) - -> SmallVector { - 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 { - 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, fld: &MacroExpander) @@ -1292,37 +1291,18 @@ fn expand_item_multi_modifier(mut it: Annotatable, expand_item_multi_modifier(it, fld) } -// expand a method -fn expand_method(m: ast::Method, fld: &mut MacroExpander) -> SmallVector { - 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(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) => { +// expand an impl item if it's a method macro +fn expand_method(ii: P, fld: &mut MacroExpander) + -> SmallVector> { + let ii = fold::noop_fold_impl_item(ii, fld).expect_one("expected one impl item"); + match ii.node { + ast::MethodImplItem(ast::MethMac(_)) => { + let (span, mac) = ii.and_then(|ii| match ii.node { + ast::MethodImplItem(ast::MethMac(mac)) => (ii.span, mac), + _ => unreachable!() + }); let maybe_new_methods = - expand_mac_invoc(mac, m.span, + expand_mac_invoc(mac, span, |r| r.make_methods(), |meths, mark| meths.move_map(|m| mark_method(m, mark)), fld); @@ -1331,7 +1311,7 @@ fn expand_method(m: ast::Method, fld: &mut MacroExpander) -> SmallVector { // expand again if necessary let new_methods = methods.into_iter() - .flat_map(|m| fld.fold_method(m).into_iter()) + .flat_map(|m| expand_method(m, fld).into_iter()) .collect(); fld.cx.bt_pop(); new_methods @@ -1339,6 +1319,7 @@ fn expand_method(m: ast::Method, fld: &mut MacroExpander) -> SmallVector SmallVector::zero() } } + _ => SmallVector::one(ii) } } @@ -1410,16 +1391,30 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { expand_arm(arm, self) } - fn fold_trait_item(&mut self, i: ast::TraitItem) -> SmallVector { - expand_trait_item(i, self) + fn fold_method(&mut self, m: ast::Method) -> ast::Method { + match m { + ast::MethDecl(generics, abi, explicit_self, fn_style, decl, body) => { + let (rewritten_fn_decl, rewritten_body) + = expand_and_rename_fn_decl_and_block(decl, body, self); + ast::MethDecl(self.fold_generics(generics), + abi, + self.fold_explicit_self(explicit_self), + fn_style, + rewritten_fn_decl, + rewritten_body) + } + ast::MethMac(mac) => ast::MethMac(mac) + } } - fn fold_impl_item(&mut self, i: ast::ImplItem) -> SmallVector { - expand_impl_item(i, self) + fn fold_trait_item(&mut self, i: P) -> SmallVector> { + expand_annotatable(Annotatable::TraitItem(i), self) + .into_iter().map(|i| i.expect_trait_item()).collect() } - fn fold_method(&mut self, method: ast::Method) -> SmallVector { - expand_method(method, self) + fn fold_impl_item(&mut self, i: P) -> SmallVector> { + expand_annotatable(Annotatable::ImplItem(i), self) + .into_iter().map(|i| i.expect_impl_item()).collect() } fn fold_ty(&mut self, t: P) -> P { @@ -1565,9 +1560,9 @@ fn mark_item(expr: P, m: Mrk) -> P { } // apply a given mark to the given item. Used following the expansion of a macro. -fn mark_method(expr: ast::Method, m: Mrk) -> ast::Method { - Marker{mark:m}.fold_method(expr) - .expect_one("marking an item didn't return exactly one method") +fn mark_method(ii: P, m: Mrk) -> P { + Marker{mark:m}.fold_impl_item(ii) + .expect_one("marking an impl item didn't return exactly one method") } /// 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 737648cd90c37..48c045ee4f98f 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, item_to_string } - impl_to_source! { P, method_to_string } impl_to_source! { P, stmt_to_string } impl_to_source! { P, expr_to_string } impl_to_source! { P, pat_to_string } @@ -311,7 +310,6 @@ pub mod rt { impl_to_tokens! { P } impl_to_tokens! { P } impl_to_tokens! { ast::Arm } - impl_to_tokens! { P } impl_to_tokens_lifetime! { &'a [P] } 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 { - 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 dcdfad4632de3..dad50af9a9192 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -82,7 +82,8 @@ impl<'a> MacResult for ParserAnyMacro<'a> { Some(ret) } - fn make_methods(self: Box>) -> Option> { + fn make_methods(self: Box>) + -> Option>> { let mut ret = SmallVector::zero(); loop { let mut parser = self.parser.borrow_mut(); diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 5109a19fdb6f6..d99f1600cb388 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -110,11 +110,7 @@ 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: Method) -> SmallVector { + fn fold_method(&mut self, m: Method) -> Method { noop_fold_method(m, self) } @@ -315,15 +311,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 +816,6 @@ pub fn noop_fold_where_predicate( } } -pub fn noop_fold_typedef(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(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(struct_def: P, fld: &mut T) -> P { struct_def.map(|StructDef { fields, ctor_id }| StructDef { fields: fields.move_map(|f| fld.fold_struct_field(f)), @@ -1020,55 +972,43 @@ pub fn noop_fold_item_underscore(i: Item_, folder: &mut T) -> Item_ { pub fn noop_fold_trait_item(i: P, folder: &mut T) -> SmallVector> { - i.map(|i| SmallVector::one(P(match i { - RequiredMethod(m) => RequiredMethod(folder.fold_type_method(m)), - ProvidedMethod(method) => { - return folder.fold_method(method).into_iter() - .map(|m| P(ProvidedMethod(m))).collect(); - } - TypeTraitItem(at) => { - TypeTraitItem(folder.fold_associated_type(at)) - } - }))) + 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 { + RequiredMethod(TypeMethod { unsafety, abi, decl, generics, explicit_self }) => { + RequiredMethod(TypeMethod { + unsafety: unsafety, + abi: abi, + decl: folder.fold_fn_decl(decl), + generics: folder.fold_generics(generics), + explicit_self: folder.fold_explicit_self(explicit_self) + }) + } + ProvidedMethod(m) => ProvidedMethod(folder.fold_method(m)), + TypeTraitItem(bounds, default) => { + TypeTraitItem(folder.fold_bounds(bounds), + default.map(|x| folder.fold_ty(x))) + } + }, + span: folder.new_span(span) + })) } pub fn noop_fold_impl_item(i: P, folder: &mut T) -> SmallVector> { - i.and_then(|i| match i { - MethodImplItem(x) => { - folder.fold_method(x).into_iter().map(|m| P(MethodImplItem(m))).collect() - } - TypeImplItem(t) => { - SmallVector::one(TypeImplItem(folder.fold_typedef(t))) - } - }) -} - -pub fn noop_fold_type_method(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), + 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(m) => MethodImplItem(folder.fold_method(m)), + TypeImplItem(ty) => TypeImplItem(folder.fold_ty(ty)) + }, + span: folder.new_span(span) + })) } pub fn noop_fold_mod(Mod {inner, items}: Mod, folder: &mut T) -> Mod { @@ -1168,34 +1108,23 @@ pub fn noop_fold_foreign_item(ni: P, folder: &mut T) -> } // Default fold over a method. -// Invariant: produces exactly one method. -pub fn noop_fold_method(Method {id, attrs, node, span}: Method, folder: &mut T) - -> SmallVector { - SmallVector::one(Method { - id: folder.new_id(id), - attrs: fold_attrs(attrs, folder), - node: match node { - MethDecl(ident, - generics, +pub fn noop_fold_method(method: Method, folder: &mut T) -> Method { + match method { + MethDecl(generics, + abi, + explicit_self, + unsafety, + decl, + body) => { + MethDecl(folder.fold_generics(generics), abi, - explicit_self, + folder.fold_explicit_self(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)), + folder.fold_fn_decl(decl), + folder.fold_block(body)) }, - span: folder.new_span(span) - }) + MethMac(mac) => MethMac(folder.fold_mac(mac)) + } } pub fn noop_fold_pat(p: P, folder: &mut T) -> P { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 63c0f4e1cfa35..a38508d2cf50b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -11,7 +11,7 @@ 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::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue}; @@ -38,7 +38,7 @@ 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}; @@ -55,7 +55,7 @@ use ast::{TyFixedLengthVec, TyBareFn}; use ast::{TyTypeof, TyInfer, TypeMethod}; 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}; @@ -1275,35 +1275,37 @@ 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) - -> AssociatedType - { - let ty_param = self.parse_ty_param(); + fn parse_assoc_ty_in_trait(&mut self, attrs: Vec) + -> P { + 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, vis: Visibility) - -> Typedef { + fn parse_assoc_ty_in_impl(&mut self, attrs: Vec, vis: Visibility) + -> P { 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 @@ -1313,14 +1315,13 @@ impl<'a> Parser<'a> { &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) { - P(TypeTraitItem(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) @@ -1342,42 +1343,29 @@ impl<'a> Parser<'a> { p.parse_where_clause(&mut generics); let hi = p.last_span.hi; - match p.token { + let node = match p.token { token::Semi => { p.bump(); debug!("parse_trait_methods(): parsing required method"); - P(RequiredMethod(TypeMethod { - ident: ident, - attrs: attrs, + RequiredMethod(TypeMethod { unsafety: style, decl: d, generics: generics, abi: abi, explicit_self: explicit_self, - id: ast::DUMMY_NODE_ID, - span: mk_sp(lo, hi), - vis: vis, - })) + }) } 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[..]); - P(ProvidedMethod(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) - })) + ProvidedMethod(ast::MethDecl(generics, + abi, + explicit_self, + style, + d, + body)) } _ => { @@ -1385,7 +1373,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: node, + span: mk_sp(lo, hi), + }) } }) } @@ -4692,7 +4688,7 @@ impl<'a> Parser<'a> { } /// Parse a method in a trait impl - pub fn parse_method_with_outer_attributes(&mut self) -> Method { + pub fn parse_method_with_outer_attributes(&mut self) -> P { let attrs = self.parse_outer_attributes(); let visa = self.parse_visibility(); self.parse_method(attrs, visa) @@ -4712,12 +4708,12 @@ impl<'a> Parser<'a> { /// Parse a method in a trait impl, starting with `attrs` attributes. pub fn parse_method(&mut self, attrs: Vec, - visa: Visibility) - -> Method { + vis: Visibility) + -> P { 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)) @@ -4725,7 +4721,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); @@ -4742,7 +4738,8 @@ impl<'a> Parser<'a> { if delim != token::Brace { self.expect(&token::Semi) } - (ast::MethMac(m), self.span.hi, attrs) + (ast::MethMac(m), self.span.hi, attrs, + token::special_idents::invalid) } else { let unsafety = self.parse_unsafety(); let abi = if self.eat_keyword(keywords::Extern) { @@ -4761,23 +4758,23 @@ impl<'a> Parser<'a> { let body_span = body.span; let mut new_attrs = attrs; new_attrs.push_all(&inner_attrs[..]); - (ast::MethDecl(ident, - generics, + (ast::MethDecl(generics, abi, explicit_self, unsafety, decl, - body, - visa), - body_span.hi, new_attrs) + body), + body_span.hi, new_attrs, ident) } }; - ast::Method { - attrs: new_attrs, + P(ImplItem { id: ast::DUMMY_NODE_ID, + attrs: new_attrs, + vis: vis, + ident: ident, + node: MethodImplItem(method_), span: mk_sp(lo, hi), - node: method_, - } + }) } /// Parse trait Foo { ... } @@ -4820,15 +4817,11 @@ impl<'a> Parser<'a> { } let vis = self.parse_visibility(); - if self.eat_keyword(keywords::Type) { - impl_items.push(P(TypeImplItem(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(P(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 863c000dd40e5..a457355698d1f 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -359,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)) } @@ -789,23 +781,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<()> { @@ -976,18 +969,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)); @@ -1008,8 +994,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)); } @@ -1241,48 +1227,65 @@ 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)); + pub fn print_ty_method(&mut self, + ident: ast::Ident, + m: &ast::TypeMethod) + -> io::Result<()> { try!(self.print_ty_fn(m.abi, m.unsafety, &*m.decl, - Some(m.ident), + Some(ident), &m.generics, Some(&m.explicit_self.node))); word(&mut self.s, ";") } - pub fn print_trait_method(&mut self, - m: &ast::TraitItem) -> io::Result<()> { - match *m { - ast::RequiredMethod(ref ty_m) => self.print_ty_method(ty_m), - ast::ProvidedMethod(ref m) => self.print_method(m), - ast::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::RequiredMethod(ref ty_m) => { + self.print_ty_method(ti.ident, ty_m) + } + ast::ProvidedMethod(ref m) => { + self.print_method(ti.ident, &ti.attrs, ast::Inherited, m) + } + 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 { - ast::MethodImplItem(ref m) => self.print_method(m), - ast::TypeImplItem(ref td) => self.print_typedef(td), + try!(self.hardbreak_if_not_bol()); + 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::TypeImplItem(ref ty) => { + self.print_associated_type(ii.ident, None, Some(ty)) + } } } - 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, + 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 generics, abi, ref explicit_self, unsafety, ref decl, - ref body, - vis) => { + ref body) => { try!(self.print_fn(&**decl, Some(unsafety), abi, @@ -1291,7 +1294,7 @@ impl<'a> State<'a> { Some(&explicit_self.node), vis)); try!(word(&mut self.s, " ")); - self.print_block_with_attrs(&**body, &meth.attrs) + self.print_block_with_attrs(&**body, attrs) }, ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _), ..}) => { diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 4222bd58a07ea..867f98f6077de 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 Method), /// |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 { @@ -618,19 +596,19 @@ pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: & // 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), +fn walk_method_helper<'v, V: Visitor<'v>>(visitor: &mut V, + id: NodeId, + ident: Ident, + span: Span, + method: &'v Method) { + match *method { + MethDecl(_, _, _, _, ref decl, ref body) => { + visitor.visit_ident(span, ident); + visitor.visit_fn(FkMethod(ident, method), &**decl, &**body, - method.span, - method.id); - for attr in &method.attrs { - visitor.visit_attribute(attr); - } - + span, + id); }, MethMac(ref mac) => visitor.visit_mac(mac) } @@ -647,13 +625,13 @@ 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(_, method) => { + match *method { + MethDecl(ref generics, _, ref explicit_self, _, _, _) => { + visitor.visit_generics(generics); + visitor.visit_explicit_self(explicit_self); + } + MethMac(ref mac) => visitor.visit_mac(mac) } } FkFnBlock(..) => {} @@ -662,25 +640,46 @@ 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 { + RequiredMethod(ref method_type) => { + visitor.visit_explicit_self(&method_type.explicit_self); + visitor.visit_generics(&method_type.generics); + walk_fn_decl(visitor, &method_type.decl); + } + ProvidedMethod(ref method) => { + walk_method_helper(visitor, + trait_item.id, + trait_item.ident, + trait_item.span, + method); + } + 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 method) => { + walk_method_helper(visitor, + impl_item.id, + impl_item.ident, + impl_item.span, + method); + } + TypeImplItem(ref ty) => { + visitor.visit_ty(ty); } } } diff --git a/src/test/auxiliary/macro_crate_test.rs b/src/test/auxiliary/macro_crate_test.rs index d9afc1df28ebf..8218fa0c4892a 100644 --- a/src/test/auxiliary/macro_crate_test.rs +++ b/src/test/auxiliary/macro_crate_test.rs @@ -81,16 +81,7 @@ fn expand_into_foo_multi(cx: &mut ExtCtxt, ..(*quote_item!(cx, enum Foo2 { Bar2, Baz2 }).unwrap()).clone() })) } - Annotatable::ImplItem(it) => { - Annotatable::ImplItem(ImplItem::MethodImplItem( - quote_method!(cx, fn foo(&self) -> i32 { 42 }) - )) - } - Annotatable::TraitItem(it) => { - Annotatable::TraitItem(TraitItem::ProvidedMethod( - quote_method!(cx, fn foo(&self) -> i32 { 0 }) - )) - } + it => it } } diff --git a/src/test/compile-fail/lint-missing-doc.rs b/src/test/compile-fail/lint-missing-doc.rs index cb2d4e10e6e71..788236a27a55b 100644 --- a/src/test/compile-fail/lint-missing-doc.rs +++ b/src/test/compile-fail/lint-missing-doc.rs @@ -59,8 +59,8 @@ trait B { } pub trait C { //~ ERROR: missing documentation for a trait - fn foo(&self); //~ ERROR: missing documentation for a type method - fn foo_with_impl(&self) {} //~ ERROR: missing documentation for a method + fn foo(&self); //~ ERROR: missing documentation for a trait method + fn foo_with_impl(&self) {} //~ ERROR: missing documentation for a default method } #[allow(missing_docs)] diff --git a/src/test/compile-fail/unnecessary-private.rs b/src/test/compile-fail/unnecessary-private.rs index 5f3744712ccb4..113393490cb6d 100644 --- a/src/test/compile-fail/unnecessary-private.rs +++ b/src/test/compile-fail/unnecessary-private.rs @@ -13,7 +13,7 @@ fn main() { pub struct A; //~ ERROR: visibility has no effect pub enum B {} //~ ERROR: visibility has no effect pub trait C { //~ ERROR: visibility has no effect - pub fn foo(&self) {} //~ ERROR: visibility has no effect + fn foo(&self) {} } impl A { pub fn foo(&self) {} //~ ERROR: visibility has no effect diff --git a/src/test/compile-fail/useless-priv.rs b/src/test/compile-fail/useless-priv.rs index b1120e54434eb..59964d0df956c 100644 --- a/src/test/compile-fail/useless-priv.rs +++ b/src/test/compile-fail/useless-priv.rs @@ -12,10 +12,7 @@ struct A { pub i: isize } pub enum C { pub Variant } //~ ERROR: unnecessary `pub` pub trait E { - pub fn foo(&self) {} //~ ERROR: unnecessary visibility -} -trait F { - pub fn foo(&self) {} //~ ERROR: unnecessary visibility + fn foo(&self); } impl E for A { diff --git a/src/test/parse-fail/issue-21153.rs b/src/test/parse-fail/issue-21153.rs index e2b6deb0ad93a..6496ffebbc849 100644 --- a/src/test/parse-fail/issue-21153.rs +++ b/src/test/parse-fail/issue-21153.rs @@ -9,5 +9,5 @@ // except according to those terms. trait MyTrait: Iterator { - Item = T; //~ ERROR expected one of `extern`, `fn`, `pub`, `type`, or `unsafe`, found `Item` + Item = T; //~ ERROR expected one of `extern`, `fn`, `type`, or `unsafe`, found `Item` } diff --git a/src/test/compile-fail/useless-priv2.rs b/src/test/parse-fail/trait-pub-assoc-ty.rs similarity index 64% rename from src/test/compile-fail/useless-priv2.rs rename to src/test/parse-fail/trait-pub-assoc-ty.rs index a404d09248f01..02d76234d4e57 100644 --- a/src/test/compile-fail/useless-priv2.rs +++ b/src/test/parse-fail/trait-pub-assoc-ty.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,11 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub trait E { - pub fn foo(&self); //~ ERROR: unnecessary visibility -} -trait F { - pub fn foo(&self); //~ ERROR: unnecessary visibility +trait Foo { + pub type Foo; //~ ERROR expected one of `extern`, `fn`, `type`, or `unsafe`, found `pub` } fn main() {} diff --git a/src/test/parse-fail/trait-pub-method.rs b/src/test/parse-fail/trait-pub-method.rs new file mode 100644 index 0000000000000..e76802d2ea0f7 --- /dev/null +++ b/src/test/parse-fail/trait-pub-method.rs @@ -0,0 +1,15 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Foo { + pub fn foo(); //~ ERROR expected one of `extern`, `fn`, `type`, or `unsafe`, found `pub` +} + +fn main() {} diff --git a/src/test/run-pass-fulldeps/quote-tokens.rs b/src/test/run-pass-fulldeps/quote-tokens.rs index a9b77419b9a37..7f7ed586878e5 100644 --- a/src/test/run-pass-fulldeps/quote-tokens.rs +++ b/src/test/run-pass-fulldeps/quote-tokens.rs @@ -36,9 +36,6 @@ fn syntax_extension(cx: &ExtCtxt) { let i: Option> = quote_item!(cx, #[derive(Eq)] struct Foo; ); assert!(i.is_some()); - let _j: P = quote_method!(cx, fn foo(&self) {}); - let _k: P = quote_method!(cx, #[doc = "hello"] fn foo(&self) {}); - let _l: P = quote_ty!(cx, &int); let _m: Vec = quote_matcher!(cx, $($foo:tt,)* bar);