From 98491827b920884e4ea1182dcacce2a650dde861 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Thu, 5 Mar 2015 04:48:54 +0200 Subject: [PATCH 1/4] syntax: move indirection around {Trait,Impl}Item, from within. --- src/librustc/metadata/encoder.rs | 26 ++++---- src/librustc/middle/astencode.rs | 8 +-- src/librustc/middle/dead.rs | 4 +- src/librustc/middle/reachable.rs | 2 +- src/librustc/middle/stability.rs | 18 +++--- src/librustc/middle/ty.rs | 46 +++++--------- src/librustc_privacy/lib.rs | 26 ++++---- src/librustc_resolve/build_reduced_graph.rs | 26 ++++---- src/librustc_resolve/lib.rs | 9 +-- src/librustc_trans/save/mod.rs | 10 +-- src/librustc_trans/trans/base.rs | 12 ++-- src/librustc_trans/trans/inline.rs | 68 ++++++++++----------- src/librustc_trans/trans/meth.rs | 11 ++-- src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/check/mod.rs | 16 ++--- src/librustc_typeck/check/wf.rs | 2 +- src/librustc_typeck/coherence/mod.rs | 2 +- src/librustc_typeck/collect.rs | 29 ++++----- src/librustdoc/doctree.rs | 4 +- src/libsyntax/ast.rs | 12 ++-- src/libsyntax/ast_map/blocks.rs | 4 +- src/libsyntax/ast_map/mod.rs | 52 ++++++++-------- src/libsyntax/ast_util.rs | 56 ----------------- src/libsyntax/ext/base.rs | 55 ++++++++--------- src/libsyntax/ext/deriving/generic/mod.rs | 14 ++--- src/libsyntax/ext/expand.rs | 18 +++--- src/libsyntax/ext/tt/macro_rules.rs | 2 +- src/libsyntax/fold.rs | 49 +++++++-------- src/libsyntax/parse/parser.rs | 26 ++++---- src/libsyntax/print/pprust.rs | 19 +++--- src/libsyntax/visit.rs | 8 +-- 31 files changed, 274 insertions(+), 362 deletions(-) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 08263eb8e6a03..44c01eba2ce5e 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -851,7 +851,7 @@ fn encode_info_for_associated_type(ecx: &EncodeContext, associated_type: &ty::AssociatedType, impl_path: PathElems, parent_id: NodeId, - typedef_opt: Option>) { + typedef_opt: Option<&ast::Typedef>) { debug!("encode_info_for_associated_type({:?},{:?})", associated_type.def_id, token::get_name(associated_type.name)); @@ -873,13 +873,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())); - match typedef_opt { - None => {} - Some(typedef) => { - encode_attributes(rbml_w, &typedef.attrs); - encode_type(ecx, rbml_w, ty::node_id_to_type(ecx.tcx, - typedef.id)); - } + 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)); } rbml_w.end_tag(); @@ -1226,7 +1222,7 @@ fn encode_info_for_item(ecx: &EncodeContext, let num_implemented_methods = ast_items.len(); for (i, &trait_item_def_id) in items.iter().enumerate() { let ast_item = if i < num_implemented_methods { - Some(&ast_items[i]) + Some(&*ast_items[i]) } else { None }; @@ -1265,7 +1261,7 @@ fn encode_info_for_item(ecx: &EncodeContext, &**associated_type, path.clone(), item.id, - Some((*typedef).clone())) + Some(typedef)) } (ty::TypeTraitItem(ref associated_type), _) => { encode_info_for_associated_type(ecx, @@ -1387,7 +1383,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_parent_sort(rbml_w, 't'); - let trait_item = &ms[i]; + let trait_item = &*ms[i]; let encode_trait_item = |rbml_w: &mut Encoder| { // If this is a static method, we've already // encoded this. @@ -1397,15 +1393,15 @@ 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 { - &ast::RequiredMethod(ref m) => { + match *trait_item { + 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) => { + ast::ProvidedMethod(ref m) => { encode_attributes(rbml_w, &m.attrs); encode_trait_item(rbml_w); encode_item_sort(rbml_w, 'p'); @@ -1413,7 +1409,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_method_argument_names(rbml_w, &*m.pe_fn_decl()); } - &ast::TypeTraitItem(ref associated_type) => { + ast::TypeTraitItem(ref associated_type) => { encode_attributes(rbml_w, &associated_type.attrs); encode_item_sort(rbml_w, 't'); diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 9d712c7c0fcc8..20b0307f47a32 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -425,9 +425,9 @@ fn simplify_ast(ii: e::InlinedItemRef) -> ast::InlinedItem { } ast::TypeTraitItem(ref associated_type) => { ast::TypeTraitItem( - P(fold::noop_fold_associated_type( - (**associated_type).clone(), - &mut fld))) + fold::noop_fold_associated_type( + (*associated_type).clone(), + &mut fld)) } }) } @@ -441,7 +441,7 @@ fn simplify_ast(ii: e::InlinedItemRef) -> ast::InlinedItem { } ast::TypeImplItem(ref td) => { ast::TypeImplItem( - P(fold::noop_fold_typedef((**td).clone(), &mut fld))) + fold::noop_fold_typedef((*td).clone(), &mut fld)) } }) } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 2d837ce52b56a..37cb23ff4f030 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -357,7 +357,7 @@ impl<'v> Visitor<'v> for LifeSeeder { } ast::ItemImpl(_, _, _, Some(ref _trait_ref), _, ref impl_items) => { for impl_item in impl_items { - match *impl_item { + match **impl_item { ast::MethodImplItem(ref method) => { self.worklist.push(method.id); } @@ -586,7 +586,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> { ast::ProvidedMethod(ref method) => { visit::walk_block(self, &*method.pe_body()) } - ast::RequiredMethod(_) => {} + ast::RequiredMethod(_) | ast::TypeTraitItem(_) => {} } } diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 45d565ec69380..35f904c2ee841 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -315,7 +315,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { match *impl_item { 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, did) { visit::walk_block(self, method.pe_body()) } } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 3599ba5a0f779..d1a02ff82e544 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -22,8 +22,7 @@ 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, RequiredMethod, ProvidedMethod, TraitItem}; -use syntax::ast::{TypeMethod, Method, Generics, StructField, TypeTraitItem}; +use syntax::ast::{Item, TypeMethod, Method, Generics, StructField}; use syntax::ast_util::is_local; use syntax::attr::{Stability, AttrMetaMethods}; use syntax::visit::{FnKind, FkMethod, Visitor}; @@ -134,19 +133,20 @@ impl<'a, 'v> Visitor<'v> for Annotator<'a> { // a stability attribute, so we don't recurse. } - fn visit_trait_item(&mut self, t: &TraitItem) { + fn visit_trait_item(&mut self, t: &ast::TraitItem) { let (id, attrs, sp) = match *t { - RequiredMethod(TypeMethod {id, ref attrs, span, ..}) => (id, attrs, span), + ast::RequiredMethod(TypeMethod {id, ref attrs, span, ..}) => (id, attrs, span), // work around lack of pattern matching for @ types - ProvidedMethod(ref method) => { - match **method { + ast::ProvidedMethod(ref method) => { + match *method { Method {ref attrs, id, span, ..} => (id, attrs, span), } } - TypeTraitItem(ref typedef) => (typedef.ty_param.id, &typedef.attrs, - typedef.ty_param.span), + 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); } @@ -335,7 +335,7 @@ 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 { + let (ident, span) = match **impl_item { ast::MethodImplItem(ref method) => { (match method.node { ast::MethDecl(ident, _, _, _, _, _, _, _) => ident, diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 4cb4d343de758..f6920dc52cdcc 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -5080,39 +5080,23 @@ pub fn provided_source(cx: &ctxt, id: ast::DefId) -> Option { pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) -> Vec>> { if is_local(id) { - match cx.map.find(id.node) { - Some(ast_map::NodeItem(item)) => { - match item.node { - ItemTrait(_, _, _, ref ms) => { - let (_, p) = - ast_util::split_trait_methods(&ms[..]); - p.iter() - .map(|m| { - match impl_or_trait_item( - cx, - ast_util::local_def(m.id)) { - MethodTraitItem(m) => m, - TypeTraitItem(_) => { - cx.sess.bug("provided_trait_methods(): \ - split_trait_methods() put \ - associated types in the \ - provided method bucket?!") - } - } - }).collect() - } - _ => { - cx.sess.bug(&format!("provided_trait_methods: `{:?}` is \ - not a trait", - 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)) { + MethodTraitItem(m) => Some(m), + TypeTraitItem(_) => { + cx.sess.bug("provided_trait_methods(): \ + associated type found from \ + looking up ProvidedMethod?!") + } } + } else { + None } - } - _ => { - cx.sess.bug(&format!("provided_trait_methods: `{:?}` is not a \ - trait", - id)) - } + }).collect() + } else { + cx.sess.bug(&format!("provided_trait_methods: `{:?}` is not a trait", id)) } } else { csearch::get_provided_trait_methods(cx, id) diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index c766b20389e73..a979c4919952a 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -94,7 +94,7 @@ impl<'v> Visitor<'v> for ParentVisitor { // private. ast::ItemTrait(_, _, _, ref methods) if item.vis != ast::Public => { for m in methods { - match *m { + match **m { ast::ProvidedMethod(ref m) => { self.parents.insert(m.id, item.id); } @@ -280,7 +280,7 @@ 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 { ast::MethodImplItem(ref method) => { let meth_public = match method.pe_explicit_self().node { @@ -301,7 +301,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> { // is public ast::ItemTrait(_, _, _, ref methods) if public_first => { for method in methods { - match *method { + match **method { ast::ProvidedMethod(ref m) => { debug!("provided {}", m.id); self.exported_items.insert(m.id); @@ -1088,7 +1088,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> { "visibility qualifiers have no effect on trait \ impls"); for impl_item in impl_items { - match *impl_item { + match **impl_item { ast::MethodImplItem(ref m) => { check_inherited(m.span, m.pe_vis(), ""); } @@ -1123,7 +1123,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> { ast::ItemTrait(_, _, _, ref methods) => { for m in methods { - match *m { + match **m { ast::ProvidedMethod(ref m) => { check_inherited(m.span, m.pe_vis(), "unnecessary visibility"); @@ -1165,7 +1165,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> { match item.node { ast::ItemImpl(_, _, _, _, _, ref impl_items) => { for impl_item in impl_items { - match *impl_item { + match **impl_item { ast::MethodImplItem(ref m) => { check_inherited(tcx, m.span, m.pe_vis()); } @@ -1188,7 +1188,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> { ast::ItemTrait(_, _, _, ref methods) => { for m in methods { - match *m { + match **m { ast::RequiredMethod(..) => {} ast::ProvidedMethod(ref m) => check_inherited(tcx, m.span, m.pe_vis()), @@ -1352,7 +1352,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { trait_ref.is_some() || impl_items.iter() .any(|impl_item| { - match *impl_item { + match **impl_item { ast::MethodImplItem(ref m) => { self.exported_items.contains(&m.id) } @@ -1369,9 +1369,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { match *trait_ref { None => { for impl_item in impl_items { - match *impl_item { + match **impl_item { ast::MethodImplItem(ref method) => { - visit::walk_method_helper(self, &**method) + visit::walk_method_helper(self, method) } ast::TypeImplItem(_) => {} } @@ -1395,7 +1395,7 @@ 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 { ast::MethodImplItem(..) => {}, ast::TypeImplItem(ref typedef) => { self.visit_ty(&typedef.typ); @@ -1409,14 +1409,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 { ast::MethodImplItem(ref method) => { if method.pe_explicit_self().node == ast::SelfStatic && self.exported_items .contains(&method.id) { found_pub_static = true; - visit::walk_method_helper(self, &**method); + visit::walk_method_helper(self, method); } } ast::TypeImplItem(_) => {} diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 67e2b409c8e22..48fb03e1efb85 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}; +use syntax::ast_util::{self, local_def, PostExpansionMethod}; use syntax::attr::AttrMetaMethods; use syntax::parse::token::{self, special_idents}; use syntax::codemap::{Span, DUMMY_SP}; @@ -525,28 +525,32 @@ 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, trait_item_id) = match **trait_item { ast::RequiredMethod(_) | ast::ProvidedMethod(_) => { - let ty_m = ast_util::trait_item_to_ty_method(trait_item); - - let name = ty_m.ident.name; + 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(ty_m.id), + let def = DefMethod(local_def(id), FromTrait(local_def(item.id))); let method_name_bindings = self.add_child(name, &module_parent, ForbidDuplicateTypesAndValues, - ty_m.span); + span); // NB: not IMPORTABLE - method_name_bindings.define_value(def, - ty_m.span, - PUBLIC); + method_name_bindings.define_value(def, span, PUBLIC); - (name, local_def(ty_m.id)) + (name, local_def(id)) } ast::TypeTraitItem(ref associated_type) => { let def = DefAssociatedTy(local_def(item.id), diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index ccca99f8b4e4a..cb1540e0f4f43 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -86,6 +86,7 @@ use syntax::ast_util::{PostExpansionMethod, local_def, walk_pat}; use syntax::attr::AttrMetaMethods; use syntax::ext::mtwt; use syntax::parse::token::{self, special_names, special_idents}; +use syntax::ptr::P; use syntax::codemap::{self, Span, Pos}; use syntax::visit::{self, Visitor}; @@ -2812,7 +2813,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // // FIXME #4951: Do we need a node ID here? - let type_parameters = match *trait_item { + let type_parameters = match **trait_item { ast::RequiredMethod(ref ty_m) => { HasTypeParameters(&ty_m.generics, FnSpace, @@ -3049,7 +3050,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { generics: &Generics, opt_trait_reference: &Option, self_type: &Ty, - impl_items: &[ImplItem]) { + impl_items: &[P]) { // If applicable, create a rib for the type parameters. self.with_type_parameter_rib(HasTypeParameters(generics, TypeSpace, @@ -3065,7 +3066,7 @@ 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 { MethodImplItem(ref method) => { // If this is a trait impl, ensure the method // exists in trait @@ -3079,7 +3080,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { FnSpace, MethodRibKind); this.with_type_parameter_rib(type_parameters, |this| { - visit::walk_method_helper(this, &**method); + visit::walk_method_helper(this, method); }); } TypeImplItem(ref typedef) => { diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 3c6cb5f9de989..13e3db4ba75c2 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -656,7 +656,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { type_parameters: &ast::Generics, trait_ref: &Option, typ: &ast::Ty, - impl_items: &Vec) { + impl_items: &[P]) { let trait_id = trait_ref.as_ref().and_then(|tr| self.lookup_type_ref(tr.ref_id)); match typ.node { // Common case impl for a struct or something basic. @@ -698,9 +698,9 @@ 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 { + match **impl_item { ast::MethodImplItem(ref method) => { - visit::walk_method_helper(self, &**method) + visit::walk_method_helper(self, method) } ast::TypeImplItem(ref typedef) => { visit::walk_ty(self, &*typedef.typ) @@ -713,7 +713,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { item: &ast::Item, generics: &ast::Generics, trait_refs: &OwnedSlice, - methods: &Vec) { + methods: &[P]) { let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id)); let val = self.span.snippet(item.span); let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Trait); @@ -1296,7 +1296,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { qualname, method_type.id); } - ast::ProvidedMethod(ref method) => self.process_method(&**method), + ast::ProvidedMethod(ref method) => self.process_method(method), ast::TypeTraitItem(_) => {} } } diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index f49905613d24c..77df121580d81 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -1283,7 +1283,7 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option) in has_nested_returns") } ast::TypeTraitItem(_) => { - tcx.sess.bug("unexpected variant: type trait item in \ + tcx.sess.bug("unexpected variant: associated type trait item in \ has_nested_returns") } } @@ -1299,7 +1299,7 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option) } } ast::TypeImplItem(_) => { - tcx.sess.bug("unexpected variant: type impl item in \ + tcx.sess.bug("unexpected variant: associated type impl item in \ has_nested_returns") } } @@ -2826,18 +2826,18 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { method in get_item_val()"); } ast::ProvidedMethod(ref m) => { - register_method(ccx, id, &**m) + register_method(ccx, id, m) } } } ast_map::NodeImplItem(ii) => { match *ii { - ast::MethodImplItem(ref m) => register_method(ccx, id, &**m), + ast::MethodImplItem(ref m) => register_method(ccx, id, m), ast::TypeImplItem(ref typedef) => { ccx.sess().span_bug(typedef.span, - "unexpected variant: required impl \ - method in get_item_val()") + "unexpected variant: associated type \ + in get_item_val()") } } } diff --git a/src/librustc_trans/trans/inline.rs b/src/librustc_trans/trans/inline.rs index 14f9233407372..14889190a85af 100644 --- a/src/librustc_trans/trans/inline.rs +++ b/src/librustc_trans/trans/inline.rs @@ -129,56 +129,54 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) with a non-item parent"); } csearch::FoundAst::Found(&ast::IITraitItem(_, ref trait_item)) => { - match *trait_item { + let id = match *trait_item { + ast::ProvidedMethod(ref mth) => mth.id, ast::RequiredMethod(_) => ccx.sess().bug("found RequiredMethod IITraitItem"), - ast::ProvidedMethod(ref mth) => { - ccx.external().borrow_mut().insert(fn_id, Some(mth.id)); - ccx.external_srcs().borrow_mut().insert(mth.id, fn_id); + 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.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1); + 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(mth.id) - } - ast::TypeTraitItem(_) => { - ccx.sess().bug("found TypeTraitItem IITraitItem") - } - } + // 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) } csearch::FoundAst::Found(&ast::IIImplItem(impl_did, ref impl_item)) => { - match *impl_item { + let (id, monomorphic_method) = match *impl_item { ast::MethodImplItem(ref mth) => { - ccx.external().borrow_mut().insert(fn_id, Some(mth.id)); - ccx.external_srcs().borrow_mut().insert(mth.id, fn_id); - - ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1); - 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(); - let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty()); - if unparameterized { - 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); - } - local_def(mth.id) + (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.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); } + local_def(id) } }; diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index 0c82d681eed15..8bbd688d63cd7 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -43,6 +43,7 @@ use syntax::parse::token; use syntax::{ast, ast_map, attr, visit}; use syntax::ast_util::PostExpansionMethod; use syntax::codemap::DUMMY_SP; +use syntax::ptr::P; // drop_glue pointer, size, align. const VTABLE_OFFSET: uint = 3; @@ -53,7 +54,7 @@ const VTABLE_OFFSET: uint = 3; /// see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`. pub fn trans_impl(ccx: &CrateContext, name: ast::Ident, - impl_items: &[ast::ImplItem], + impl_items: &[P], generics: &ast::Generics, id: ast::NodeId) { let _icx = push_ctxt("meth::trans_impl"); @@ -66,9 +67,9 @@ pub fn trans_impl(ccx: &CrateContext, if !generics.ty_params.is_empty() { let mut v = TransItemVisitor{ ccx: ccx }; for impl_item in impl_items { - match *impl_item { + match **impl_item { ast::MethodImplItem(ref method) => { - visit::walk_method_helper(&mut v, &**method); + visit::walk_method_helper(&mut v, method); } ast::TypeImplItem(_) => {} } @@ -76,7 +77,7 @@ pub fn trans_impl(ccx: &CrateContext, return; } for impl_item in impl_items { - match *impl_item { + match **impl_item { ast::MethodImplItem(ref method) => { if method.pe_generics().ty_params.len() == 0 { let trans_everywhere = attr::requests_inline(&method.attrs); @@ -99,7 +100,7 @@ pub fn trans_impl(ccx: &CrateContext, let mut v = TransItemVisitor { ccx: ccx, }; - visit::walk_method_helper(&mut v, &**method); + visit::walk_method_helper(&mut v, method); } ast::TypeImplItem(_) => {} } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 2c7a9bf8020c3..9d364df5553c1 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1096,7 +1096,7 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>, 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 let ast::TypeTraitItem(ref assoc) = **i { if assoc.ty_param.ident.name == assoc_name { return Some(ast_util::local_def(assoc.ty_param.id)); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 44500ce0bbb7f..c625d82671354 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -739,9 +739,9 @@ 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 { ast::MethodImplItem(ref m) => { - check_method_body(ccx, &impl_pty.generics, &**m); + check_method_body(ccx, &impl_pty.generics, m); } ast::TypeImplItem(_) => { // Nothing to do here. @@ -754,13 +754,13 @@ pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) { 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 { + match **trait_method { 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); } TypeTraitItem(_) => { // Nothing to do. @@ -876,7 +876,7 @@ fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, impl_span: Span, impl_trait_ref: &ty::TraitRef<'tcx>, - impl_items: &[ast::ImplItem]) { + impl_items: &[P]) { // Locate trait methods let tcx = ccx.tcx; let trait_items = ty::trait_items(tcx, impl_trait_ref.def_id); @@ -884,7 +884,7 @@ 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 { ast::MethodImplItem(ref impl_method) => { let impl_method_def_id = local_def(impl_method.id); let impl_item_ty = ty::impl_or_trait_item(ccx.tcx, @@ -978,7 +978,7 @@ 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 { + match **ii { ast::MethodImplItem(ref m) => { m.pe_ident().name == trait_method.name } @@ -993,7 +993,7 @@ 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 { + match **ii { ast::TypeImplItem(ref typedef) => { typedef.ident.name == associated_type.name } diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index 32bd40ebda2de..6c7c3cf08bc30 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -501,7 +501,7 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> { fn visit_trait_item(&mut self, t: &'v ast::TraitItem) { match t { &ast::TraitItem::ProvidedMethod(_) | - &ast::TraitItem::TypeTraitItem(_) => {}, + &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) => { diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index a06dcbaf556bd..b990ba0ab24f9 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -279,7 +279,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { let mut items: Vec = ast_items.iter() .map(|ast_item| { - match *ast_item { + match **ast_item { ast::MethodImplItem(ref ast_method) => { MethodTraitItemId( local_def(ast_method.id)) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index bd68802f262c1..4d98aed8006b2 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -631,17 +631,16 @@ 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 { ast::RequiredMethod(_) | ast::ProvidedMethod(_) => { - let ty_method = Rc::new(match *trait_item { + let ty_method = Rc::new(match **trait_item { ast::RequiredMethod(ref m) => { ty_method_of_trait_method( ccx, trait_id, &trait_def.generics, &trait_predicates, - &trait_items[..], &m.id, &m.ident.name, &m.explicit_self, @@ -656,7 +655,6 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, trait_id, &trait_def.generics, &trait_predicates, - &trait_items[..], &m.id, &m.pe_ident().name, m.pe_explicit_self(), @@ -702,7 +700,7 @@ 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 { + match **ti { ast::RequiredMethod(ref ty_method) => { ty::MethodTraitItemId(local_def(ty_method.id)) } @@ -736,7 +734,6 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, trait_id: ast::NodeId, trait_generics: &ty::Generics<'tcx>, trait_bounds: &ty::GenericPredicates<'tcx>, - _trait_items: &[ast::TraitItem], m_id: &ast::NodeId, m_name: &ast::Name, m_explicit_self: &ast::ExplicitSelf, @@ -1016,9 +1013,9 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { let mut methods = Vec::new(); for impl_item in impl_items { - match *impl_item { + match **impl_item { ast::MethodImplItem(ref method) => { - methods.push(&**method); + methods.push(method); } ast::TypeImplItem(ref typedef) => { if opt_trait_ref.is_none() { @@ -1059,7 +1056,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { parent_visibility); for impl_item in impl_items { - match *impl_item { + match **impl_item { ast::MethodImplItem(ref method) => { let body_id = method.pe_body().id; check_method_self_type(ccx, @@ -1099,9 +1096,9 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { 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 { + trait_items.iter().filter_map(|m| match **m { ast::RequiredMethod(_) => None, - ast::ProvidedMethod(ref m) => Some(&**m), + ast::ProvidedMethod(ref m) => Some(m), ast::TypeTraitItem(_) => None, }), untransformed_rcvr_ty, @@ -1118,7 +1115,7 @@ 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 { ast::RequiredMethod(ref type_method) => { let rscope = BindingRscope::new(); check_method_self_type(ccx, @@ -1139,7 +1136,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { ast::TypeTraitItem(ref associated_type) => { convert_associated_type(ccx, &*trait_def, - &**associated_type); + associated_type); } } } @@ -1354,7 +1351,7 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let associated_type_names: Vec<_> = items.iter() .filter_map(|item| { - match *item { + match **item { ast::RequiredMethod(_) | ast::ProvidedMethod(_) => None, ast::TypeTraitItem(ref data) => Some(data.ty_param.ident.name), } @@ -1484,13 +1481,13 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item) ast_generics: &ast::Generics, trait_predicates: &ty::GenericPredicates<'tcx>, self_trait_ref: &Rc>, - trait_items: &[ast::TraitItem]) + trait_items: &[P]) -> Vec> { trait_items .iter() .flat_map(|trait_item| { - let assoc_type_def = match *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(); diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 8143926982f01..5a4deaa2e7266 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -174,7 +174,7 @@ pub struct Constant { pub struct Trait { pub unsafety: ast::Unsafety, pub name: Ident, - pub items: Vec, //should be TraitItem + pub items: Vec>, //should be TraitItem pub generics: ast::Generics, pub bounds: Vec, pub attrs: Vec, @@ -190,7 +190,7 @@ pub struct Impl { pub generics: ast::Generics, pub trait_: Option, pub for_: P, - pub items: Vec, + pub items: Vec>, pub attrs: Vec, pub whence: Span, pub vis: ast::Visibility, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 550ce3bb8c873..fafcc056dedfb 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1081,14 +1081,14 @@ pub struct TypeMethod { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum TraitItem { RequiredMethod(TypeMethod), - ProvidedMethod(P), - TypeTraitItem(P), + ProvidedMethod(Method), + TypeTraitItem(AssociatedType), } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum ImplItem { - MethodImplItem(P), - TypeImplItem(P), + MethodImplItem(Method), + TypeImplItem(Typedef), } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] @@ -1659,7 +1659,7 @@ pub enum Item_ { ItemTrait(Unsafety, Generics, TyParamBounds, - Vec), + Vec>), // Default trait implementations // `impl Trait for ..` @@ -1669,7 +1669,7 @@ pub enum Item_ { Generics, Option, // (optional) trait this impl implements P, // self - Vec), + Vec>), /// A macro invocation (which includes macro definition) ItemMac(Mac), } diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs index 1a537c7a5b8f8..8d605ea50cda6 100644 --- a/src/libsyntax/ast_map/blocks.rs +++ b/src/libsyntax/ast_map/blocks.rs @@ -206,12 +206,12 @@ 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::ProvidedMethod(ref m) => method(m), _ => panic!("trait method FnLikeNode that is not fn-like"), }, ast_map::NodeImplItem(ii) => { match *ii { - ast::MethodImplItem(ref m) => method(&**m), + ast::MethodImplItem(ref m) => method(m), 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 b96d735d92dbd..4db6f9bc3c52b 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -14,12 +14,11 @@ use self::MapEntry::*; use abi; use ast::*; -use ast_util; +use ast_util::{self, PostExpansionMethod}; use codemap::{DUMMY_SP, Span, Spanned}; use fold::Folder; use parse::token; use print::pprust; -use ptr::P; use visit::{self, Visitor}; use arena::TypedArena; @@ -741,14 +740,11 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { match i.node { ItemImpl(_, _, _, _, _, ref impl_items) => { for impl_item in impl_items { - match *impl_item { - MethodImplItem(ref m) => { - self.insert(m.id, NodeImplItem(impl_item)); - } - TypeImplItem(ref t) => { - self.insert(t.id, NodeImplItem(impl_item)); - } - } + let id = match **impl_item { + MethodImplItem(ref m) => m.id, + TypeImplItem(ref t) => t.id, + }; + self.insert(id, NodeImplItem(impl_item)); } } ItemEnum(ref enum_definition, _) => { @@ -778,17 +774,12 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { } for tm in trait_items { - match *tm { - RequiredMethod(ref m) => { - self.insert(m.id, NodeTraitItem(tm)); - } - ProvidedMethod(ref m) => { - self.insert(m.id, NodeTraitItem(tm)); - } - TypeTraitItem(ref typ) => { - self.insert(typ.ty_param.id, NodeTraitItem(tm)); - } - } + 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)); } } _ => {} @@ -933,7 +924,7 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, TypeTraitItem(at) => { IITraitItem( fld.fold_ops.new_def_id(d), - TypeTraitItem(P(fld.fold_associated_type((*at).clone())))) + TypeTraitItem(fld.fold_associated_type(at))) } }, IIImplItem(d, m) => match m { @@ -944,7 +935,7 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, } TypeImplItem(t) => { IIImplItem(fld.fold_ops.new_def_id(d), - TypeImplItem(P(fld.fold_typedef((*t).clone())))) + TypeImplItem(fld.fold_typedef(t))) } }, IIForeign(i) => IIForeign(fld.fold_foreign_item(i)) @@ -1064,7 +1055,7 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { } } TypeImplItem(ref t) => { - format!("typedef {} in {}{}", + format!("assoc type {} in {}{}", token::get_ident(t.ident), map.path_to_string(id), id_str) @@ -1073,15 +1064,20 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { } Some(NodeTraitItem(ref tm)) => { match **tm { - RequiredMethod(_) | ProvidedMethod(_) => { - let m = ast_util::trait_item_to_ty_method(&**tm); - format!("method {} in {}{}", + 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!("type item {} in {}{}", + format!("assoc type {} in {}{}", token::get_ident(t.ty_param.ident), map.path_to_string(id), id_str) diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 26d7562cdb2d4..a8804b595d403 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -268,62 +268,6 @@ pub fn impl_pretty_name(trait_ref: &Option, ty: Option<&Ty>) -> Ident token::gensym_ident(&pretty[..]) } -pub fn trait_method_to_ty_method(method: &Method) -> TypeMethod { - match method.node { - MethDecl(ident, - ref generics, - abi, - ref explicit_self, - unsafety, - ref decl, - _, - vis) => { - TypeMethod { - ident: ident, - attrs: method.attrs.clone(), - unsafety: unsafety, - decl: (*decl).clone(), - generics: generics.clone(), - explicit_self: (*explicit_self).clone(), - id: method.id, - span: method.span, - vis: vis, - abi: abi, - } - }, - MethMac(_) => panic!("expected non-macro method declaration") - } -} - -/// extract a TypeMethod from a TraitItem. if the TraitItem is -/// a default, pull out the useful fields to make a TypeMethod -// -// NB: to be used only after expansion is complete, and macros are gone. -pub fn trait_item_to_ty_method(method: &TraitItem) -> TypeMethod { - match *method { - RequiredMethod(ref m) => (*m).clone(), - ProvidedMethod(ref m) => trait_method_to_ty_method(&**m), - TypeTraitItem(_) => { - panic!("trait_method_to_ty_method(): expected method but found \ - typedef") - } - } -} - -pub fn split_trait_methods(trait_methods: &[TraitItem]) - -> (Vec, Vec> ) { - let mut reqd = Vec::new(); - let mut provd = Vec::new(); - for trt_method in trait_methods { - match *trt_method { - RequiredMethod(ref tm) => reqd.push((*tm).clone()), - ProvidedMethod(ref m) => provd.push((*m).clone()), - TypeTraitItem(_) => {} - } - }; - (reqd, provd) -} - pub fn struct_field_visibility(field: ast::StructField) -> Visibility { match field.node.kind { ast::NamedField(_, v) | ast::UnnamedField(v) => v diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 8aeafe419daa9..b999680ff1a9a 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -86,42 +86,37 @@ impl Annotatable { match *self { Annotatable::Item(ref i) => &i.attrs, Annotatable::TraitItem(ref i) => match *i { - ast::TraitItem::RequiredMethod(ref tm) => &tm.attrs, - ast::TraitItem::ProvidedMethod(ref m) => &m.attrs, - ast::TraitItem::TypeTraitItem(ref at) => &at.attrs, + 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::ImplItem::MethodImplItem(ref m) => &m.attrs, - ast::ImplItem::TypeImplItem(ref t) => &t.attrs, + ast::MethodImplItem(ref m) => &m.attrs, + ast::TypeImplItem(ref t) => &t.attrs, } } } pub fn fold_attrs(self, attrs: Vec) -> Annotatable { match self { - Annotatable::Item(i) => Annotatable::Item(P(ast::Item { + Annotatable::Item(i) => Annotatable::Item(i.map(|i| ast::Item { attrs: attrs, - ..(*i).clone() + ..i })), - Annotatable::TraitItem(i) => match i { - ast::TraitItem::RequiredMethod(tm) => Annotatable::TraitItem( - ast::TraitItem::RequiredMethod( - ast::TypeMethod { attrs: attrs, ..tm })), - ast::TraitItem::ProvidedMethod(m) => Annotatable::TraitItem( - ast::TraitItem::ProvidedMethod(P( - ast::Method { attrs: attrs, ..(*m).clone() }))), - ast::TraitItem::TypeTraitItem(at) => Annotatable::TraitItem( - ast::TraitItem::TypeTraitItem(P( - ast::AssociatedType { attrs: attrs, ..(*at).clone() }))), - }, - Annotatable::ImplItem(i) => match i { - ast::ImplItem::MethodImplItem(m) => Annotatable::ImplItem( - ast::ImplItem::MethodImplItem(P( - ast::Method { attrs: attrs, ..(*m).clone() }))), - ast::ImplItem::TypeImplItem(t) => Annotatable::ImplItem( - ast::ImplItem::TypeImplItem(P( - ast::Typedef { attrs: attrs, ..(*t).clone() }))), - } + 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 }), + }) } } @@ -249,7 +244,7 @@ pub trait MacResult { } /// Create zero or more methods. - fn make_methods(self: Box) -> Option>> { + fn make_methods(self: Box) -> Option> { None } @@ -295,7 +290,7 @@ make_MacEager! { expr: P, pat: P, items: SmallVector>, - methods: SmallVector>, + methods: SmallVector, stmt: P, } @@ -308,7 +303,7 @@ impl MacResult for MacEager { self.items } - fn make_methods(self: Box) -> Option>> { + fn make_methods(self: Box) -> Option> { self.methods } @@ -397,7 +392,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 { diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index 9cd965a8138e0..0573289150c84 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -386,12 +386,12 @@ 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` let associated_types = self.associated_types.iter().map(|&(ident, ref type_def)| { - P(ast::Typedef { + ast::Typedef { id: ast::DUMMY_NODE_ID, span: self.span, ident: ident, @@ -402,7 +402,7 @@ impl<'a> TraitDef<'a> { type_ident, generics ), - }) + } }); let Generics { mut lifetimes, ty_params, mut where_clause } = @@ -517,7 +517,7 @@ impl<'a> TraitDef<'a> { associated_types.map(|type_| { ast::TypeImplItem(type_) }) - ).collect())) + ).map(P).collect())) } fn expand_struct_def(&self, @@ -702,7 +702,7 @@ impl<'a> MethodDef<'a> { abi: Abi, explicit_self: ast::ExplicitSelf, arg_types: Vec<(Ident, P)> , - body: P) -> P { + body: P) -> ast::Method { // create the generics that aren't for Self let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics); @@ -725,7 +725,7 @@ impl<'a> MethodDef<'a> { let body_block = cx.block_expr(body); // Create the method. - P(ast::Method { + ast::Method { attrs: self.attributes.clone(), id: ast::DUMMY_NODE_ID, span: trait_.span, @@ -737,7 +737,7 @@ impl<'a> MethodDef<'a> { fn_decl, body_block, ast::Inherited) - }) + } } /// ``` diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 98c7aefcd8ad3..96859b94f1dde 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1185,7 +1185,7 @@ fn expand_annotatable(a: Annotatable, } ast::TraitItem::TypeTraitItem(t) => { SmallVector::one(Annotatable::TraitItem( - ast::TraitItem::TypeTraitItem(P(fld.fold_associated_type((*t).clone()))))) + ast::TraitItem::TypeTraitItem(fld.fold_associated_type(t)))) } }, Annotatable::ImplItem(it) => match it { @@ -1195,7 +1195,7 @@ fn expand_annotatable(a: Annotatable, } ast::ImplItem::TypeImplItem(t) => { SmallVector::one(Annotatable::ImplItem( - ast::ImplItem::TypeImplItem(P(fld.fold_typedef((*t).clone()))))) + ast::ImplItem::TypeImplItem(fld.fold_typedef(t)))) } } }; @@ -1293,8 +1293,8 @@ fn expand_item_multi_modifier(mut it: Annotatable, } // expand a method -fn expand_method(m: P, fld: &mut MacroExpander) -> SmallVector> { - m.and_then(|m| match m.node { +fn expand_method(m: ast::Method, fld: &mut MacroExpander) -> SmallVector { + match m.node { ast::MethDecl(ident, generics, abi, @@ -1306,7 +1306,7 @@ fn expand_method(m: P, fld: &mut MacroExpander) -> SmallVector, fld: &mut MacroExpander) -> SmallVector { let maybe_new_methods = @@ -1339,7 +1339,7 @@ fn expand_method(m: P, fld: &mut MacroExpander) -> SmallVector SmallVector::zero() } } - }) + } } /// Given a fn_decl and a block and a MacroExpander, expand the fn_decl, then use the @@ -1418,7 +1418,7 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { expand_impl_item(i, self) } - fn fold_method(&mut self, method: P) -> SmallVector> { + fn fold_method(&mut self, method: ast::Method) -> SmallVector { expand_method(method, self) } @@ -1565,7 +1565,7 @@ 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: P, m: Mrk) -> P { +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") } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 644c6cd7e2833..dcdfad4632de3 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -82,7 +82,7 @@ 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 959e3bdb31476..5109a19fdb6f6 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -98,11 +98,11 @@ pub trait Folder : Sized { noop_fold_item_underscore(i, self) } - fn fold_trait_item(&mut self, i: TraitItem) -> SmallVector { + fn fold_trait_item(&mut self, i: P) -> SmallVector> { noop_fold_trait_item(i, self) } - fn fold_impl_item(&mut self, i: ImplItem) -> SmallVector { + fn fold_impl_item(&mut self, i: P) -> SmallVector> { noop_fold_impl_item(i, self) } @@ -114,7 +114,7 @@ pub trait Folder : Sized { noop_fold_type_method(m, self) } - fn fold_method(&mut self, m: P) -> SmallVector> { + fn fold_method(&mut self, m: Method) -> SmallVector { noop_fold_method(m, self) } @@ -1018,34 +1018,30 @@ pub fn noop_fold_item_underscore(i: Item_, folder: &mut T) -> Item_ { } } -pub fn noop_fold_trait_item(i: TraitItem, folder: &mut T) -> SmallVector { - match i { - RequiredMethod(m) => { - SmallVector::one(RequiredMethod( - folder.fold_type_method(m))) - } +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) => { - folder.fold_method(method).into_iter() - .map(|m| ProvidedMethod(m)).collect() + return folder.fold_method(method).into_iter() + .map(|m| P(ProvidedMethod(m))).collect(); } TypeTraitItem(at) => { - SmallVector::one(TypeTraitItem(P( - folder.fold_associated_type( - (*at).clone())))) + TypeTraitItem(folder.fold_associated_type(at)) } - } + }))) } -pub fn noop_fold_impl_item(i: ImplItem, folder: &mut T) -> SmallVector { - match i { - MethodImplItem(ref x) => { - folder.fold_method((*x).clone()).into_iter().map(|m| MethodImplItem(m)).collect() +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(ref t) => { - SmallVector::one(TypeImplItem( - P(folder.fold_typedef((**t).clone())))) + TypeImplItem(t) => { + SmallVector::one(TypeImplItem(folder.fold_typedef(t))) } - } + }) } pub fn noop_fold_type_method(m: TypeMethod, fld: &mut T) -> TypeMethod { @@ -1173,8 +1169,9 @@ 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(m: P, folder: &mut T) -> SmallVector> { - SmallVector::one(m.map(|Method {id, attrs, node, span}| 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 { @@ -1198,7 +1195,7 @@ pub fn noop_fold_method(m: P, folder: &mut T) -> SmallVector< MethMac(mac) => MethMac(folder.fold_mac(mac)), }, span: folder.new_span(span) - })) + }) } 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 28d757e9be963..63c0f4e1cfa35 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1307,7 +1307,7 @@ impl<'a> Parser<'a> { } /// Parse the items in a trait declaration - pub fn parse_trait_items(&mut self) -> Vec { + pub fn parse_trait_items(&mut self) -> Vec> { self.parse_unspanned_seq( &token::OpenDelim(token::Brace), &token::CloseDelim(token::Brace), @@ -1316,7 +1316,7 @@ impl<'a> Parser<'a> { let attrs = p.parse_outer_attributes(); if p.eat_keyword(keywords::Type) { - TypeTraitItem(P(p.parse_associated_type(attrs))) + P(TypeTraitItem(p.parse_associated_type(attrs))) } else { let lo = p.span.lo; @@ -1346,7 +1346,7 @@ impl<'a> Parser<'a> { token::Semi => { p.bump(); debug!("parse_trait_methods(): parsing required method"); - RequiredMethod(TypeMethod { + P(RequiredMethod(TypeMethod { ident: ident, attrs: attrs, unsafety: style, @@ -1357,7 +1357,7 @@ impl<'a> Parser<'a> { id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi), vis: vis, - }) + })) } token::OpenDelim(token::Brace) => { debug!("parse_trait_methods(): parsing provided method"); @@ -1365,7 +1365,7 @@ impl<'a> Parser<'a> { p.parse_inner_attrs_and_block(); let mut attrs = attrs; attrs.push_all(&inner_attrs[..]); - ProvidedMethod(P(ast::Method { + P(ProvidedMethod(ast::Method { attrs: attrs, id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi), @@ -4692,7 +4692,7 @@ impl<'a> Parser<'a> { } /// Parse a method in a trait impl - pub fn parse_method_with_outer_attributes(&mut self) -> P { + pub fn parse_method_with_outer_attributes(&mut self) -> Method { let attrs = self.parse_outer_attributes(); let visa = self.parse_visibility(); self.parse_method(attrs, visa) @@ -4713,7 +4713,7 @@ impl<'a> Parser<'a> { pub fn parse_method(&mut self, attrs: Vec, visa: Visibility) - -> P { + -> Method { let lo = self.span.lo; // code copied from parse_macro_use_or_failure... abstraction! @@ -4772,12 +4772,12 @@ impl<'a> Parser<'a> { body_span.hi, new_attrs) } }; - P(ast::Method { + ast::Method { attrs: new_attrs, id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi), node: method_, - }) + } } /// Parse trait Foo { ... } @@ -4808,7 +4808,7 @@ impl<'a> Parser<'a> { (ident, ItemTrait(unsafety, tps, bounds, meths), None) } - fn parse_impl_items(&mut self) -> (Vec, Vec) { + fn parse_impl_items(&mut self) -> (Vec>, Vec) { let mut impl_items = Vec::new(); self.expect(&token::OpenDelim(token::Brace)); let (inner_attrs, mut method_attrs) = @@ -4821,13 +4821,13 @@ impl<'a> Parser<'a> { let vis = self.parse_visibility(); if self.eat_keyword(keywords::Type) { - impl_items.push(TypeImplItem(P(self.parse_typedef( + impl_items.push(P(TypeImplItem(self.parse_typedef( method_attrs, vis)))) } else { - impl_items.push(MethodImplItem(self.parse_method( + impl_items.push(P(MethodImplItem(self.parse_method( method_attrs, - vis))); + vis)))); } method_attrs = vec![]; } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 883c2295a3655..863c000dd40e5 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -12,8 +12,7 @@ pub use self::AnnNode::*; use abi; use ast; -use ast::{MethodImplItem, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; -use ast::{RequiredMethod, ProvidedMethod, TypeImplItem, TypeTraitItem}; +use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; use ast_util; use attr; use owned_slice::OwnedSlice; @@ -977,12 +976,12 @@ impl<'a> State<'a> { try!(self.bopen()); try!(self.print_inner_attributes(&item.attrs)); for impl_item in impl_items { - match *impl_item { + match **impl_item { ast::MethodImplItem(ref meth) => { - try!(self.print_method(&**meth)); + try!(self.print_method(meth)); } ast::TypeImplItem(ref typ) => { - try!(self.print_typedef(&**typ)); + try!(self.print_typedef(typ)); } } } @@ -1258,16 +1257,16 @@ impl<'a> State<'a> { pub fn print_trait_method(&mut self, m: &ast::TraitItem) -> io::Result<()> { match *m { - RequiredMethod(ref ty_m) => self.print_ty_method(ty_m), - ProvidedMethod(ref m) => self.print_method(&**m), - TypeTraitItem(ref t) => self.print_associated_type(&**t), + 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_impl_item(&mut self, ii: &ast::ImplItem) -> io::Result<()> { match *ii { - MethodImplItem(ref m) => self.print_method(&**m), - TypeImplItem(ref td) => self.print_typedef(&**td), + ast::MethodImplItem(ref m) => self.print_method(m), + ast::TypeImplItem(ref td) => self.print_typedef(td), } } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 33d8d56b4b114..4222bd58a07ea 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -144,7 +144,7 @@ pub fn walk_inlined_item<'v,V>(visitor: &mut V, item: &'v InlinedItem) 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) + walk_method_helper(visitor, m) } IIImplItem(_, TypeImplItem(ref typedef)) => { visitor.visit_ident(typedef.span, typedef.ident); @@ -294,9 +294,9 @@ 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 { + match **impl_item { MethodImplItem(ref method) => { - walk_method_helper(visitor, &**method) + walk_method_helper(visitor, method) } TypeImplItem(ref typedef) => { visitor.visit_ident(typedef.span, typedef.ident); @@ -678,7 +678,7 @@ pub fn walk_ty_method<'v, V: Visitor<'v>>(visitor: &mut V, method_type: &'v Type 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), + ProvidedMethod(ref method) => walk_method_helper(visitor, method), TypeTraitItem(ref associated_type) => { walk_ty_param(visitor, &associated_type.ty_param); } From f98b1763140e4c9b0f122bde2f5cbd24227554a2 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Tue, 10 Mar 2015 12:28:44 +0200 Subject: [PATCH 2/4] 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); From ce10fa8d12cb20d9eee59fffeeaadfcca8badf4a Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Wed, 11 Mar 2015 08:38:27 +0200 Subject: [PATCH 3/4] syntax: rename TypeMethod to MethodSig and use it in MethDecl. --- src/librustc/metadata/encoder.rs | 4 +- src/librustc/middle/effect.rs | 2 +- src/librustc/middle/infer/error_reporting.rs | 20 +- src/librustc/middle/reachable.rs | 4 +- src/librustc/middle/resolve_lifetime.rs | 2 +- src/librustc_lint/builtin.rs | 4 +- src/librustc_privacy/lib.rs | 4 +- src/librustc_resolve/lib.rs | 16 +- src/librustc_trans/save/mod.rs | 8 +- src/librustc_trans/trans/debuginfo.rs | 12 +- src/librustc_trans/trans/inline.rs | 4 +- src/librustc_trans/trans/meth.rs | 4 +- src/librustc_trans/trans/monomorphize.rs | 4 +- src/librustc_typeck/astconv.rs | 15 +- src/librustc_typeck/check/mod.rs | 2 +- src/librustc_typeck/collect.rs | 409 ++++++------------ src/librustdoc/clean/mod.rs | 16 +- src/libsyntax/ast.rs | 15 +- src/libsyntax/ast_map/blocks.rs | 2 +- src/libsyntax/ast_util.rs | 23 +- src/libsyntax/ext/deriving/generic/mod.rs | 14 +- src/libsyntax/ext/expand.rs | 17 +- src/libsyntax/fold.rs | 33 +- src/libsyntax/parse/parser.rs | 39 +- src/libsyntax/print/pprust.rs | 107 ++--- src/libsyntax/visit.rs | 20 +- .../compile-fail/impl-duplicate-methods.rs | 2 +- src/test/compile-fail/issue-4265.rs | 2 +- 28 files changed, 291 insertions(+), 513 deletions(-) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 0c220ab8766d2..eb41a26fa7701 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -838,7 +838,7 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, if !any_types { encode_symbol(ecx, rbml_w, m.def_id.node); } - encode_method_argument_names(rbml_w, ast_method.pe_fn_decl()); + encode_method_argument_names(rbml_w, &ast_method.pe_sig().decl); } } @@ -1383,7 +1383,7 @@ fn encode_info_for_item(ecx: &EncodeContext, 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()); + encode_method_argument_names(rbml_w, &*m.pe_sig().decl); } ast::TypeTraitItem(..) => { diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 5b5e5b6555b91..02f2908a9e6d5 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -91,7 +91,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { visit::FkItemFn(_, _, fn_style, _) => (true, fn_style == ast::Unsafety::Unsafe), visit::FkMethod(_, method) => - (true, method.pe_unsafety() == ast::Unsafety::Unsafe), + (true, method.pe_sig().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 cf3715bc3fbe8..823acdc169120 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -841,7 +841,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { ast_map::NodeItem(ref item) => { match item.node { ast::ItemFn(ref fn_decl, pur, _, ref gen, _) => { - Some((&**fn_decl, gen, pur, item.ident, None, item.span)) + Some((fn_decl, gen, pur, item.ident, None, item.span)) }, _ => None } @@ -849,11 +849,11 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { ast_map::NodeImplItem(item) => { match item.node { ast::MethodImplItem(ref m) => { - Some((m.pe_fn_decl(), - m.pe_generics(), - m.pe_unsafety(), + Some((&m.pe_sig().decl, + &m.pe_sig().generics, + m.pe_sig().unsafety, item.ident, - Some(&m.pe_explicit_self().node), + Some(&m.pe_sig().explicit_self.node), item.span)) } ast::TypeImplItem(_) => None, @@ -862,11 +862,11 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { ast_map::NodeTraitItem(item) => { match item.node { ast::ProvidedMethod(ref m) => { - Some((m.pe_fn_decl(), - m.pe_generics(), - m.pe_unsafety(), + Some((&m.pe_sig().decl, + &m.pe_sig().generics, + m.pe_sig().unsafety, item.ident, - Some(&m.pe_explicit_self().node), + Some(&m.pe_sig().explicit_self.node), item.span)) } _ => None @@ -1732,7 +1732,7 @@ fn lifetimes_in_scope(tcx: &ty::ctxt, ast_map::NodeImplItem(ii) => { match ii.node { ast::MethodImplItem(ref m) => { - taken.push_all(&m.pe_generics().lifetimes); + taken.push_all(&m.pe_sig().generics.lifetimes); Some(ii.id) } ast::TypeImplItem(_) => None, diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index fd6b28fd2922f..75e9c60698ba3 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -57,7 +57,7 @@ fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method, impl_item: &ast::ImplItem, impl_src: ast::DefId) -> bool { if attr::requests_inline(&impl_item.attrs) || - generics_require_inlining(method.pe_generics()) { + generics_require_inlining(&method.pe_sig().generics) { return true } if is_local(impl_src) { @@ -191,7 +191,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { Some(ast_map::NodeImplItem(impl_item)) => { match impl_item.node { ast::MethodImplItem(ref method) => { - if generics_require_inlining(method.pe_generics()) || + if generics_require_inlining(&method.pe_sig().generics) || attr::requests_inline(&impl_item.attrs) { true } else { diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index e02f786128565..32d52bcbf74ee 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -149,7 +149,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { }) } visit::FkMethod(_, m) => { - self.visit_early_late(subst::FnSpace, m.pe_generics(), |this| { + self.visit_early_late(subst::FnSpace, &m.pe_sig().generics, |this| { visit::walk_fn(this, fk, fd, b, s) }) } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 259a9acadc6db..687b4cb8723df 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -46,7 +46,7 @@ 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::{self, is_shift_binop, local_def}; +use syntax::ast_util::{self, is_shift_binop, local_def, PostExpansionMethod}; use syntax::attr::{self, AttrMetaMethods}; use syntax::codemap::{self, Span}; use syntax::feature_gate::{KNOWN_ATTRIBUTES, AttributeType}; @@ -1319,7 +1319,7 @@ impl LintPass for UnsafeCode { cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` function"), visit::FkMethod(_, m) => { - if let ast::MethDecl(_, _, _, ast::Unsafety::Unsafe, _, _) = *m { + if m.pe_sig().unsafety == ast::Unsafety::Unsafe { cx.span_lint(UNSAFE_CODE, span, "implementation of an `unsafe` method") } }, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 9cb9c1f2f85eb..9b069962de409 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -275,7 +275,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> { match impl_item.node { ast::MethodImplItem(ref method) => { let meth_public = - match method.pe_explicit_self().node { + match method.pe_sig().explicit_self.node { ast::SelfStatic => public_ty, _ => true, } && impl_item.vis == ast::Public; @@ -1355,7 +1355,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { for impl_item in impl_items { match impl_item.node { ast::MethodImplItem(ref method) => { - if method.pe_explicit_self().node == + if method.pe_sig().explicit_self.node == ast::SelfStatic && self.exported_items .contains(&impl_item.id) { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 67675a5a1ae70..296a9794f1cea 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -243,8 +243,8 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { ItemRibKind } visit::FkMethod(_, method) => { - self.visit_generics(method.pe_generics()); - self.visit_explicit_self(method.pe_explicit_self()); + self.visit_generics(&method.pe_sig().generics); + self.visit_explicit_self(&method.pe_sig().explicit_self); MethodRibKind } visit::FkFnBlock(..) => ClosureRibKind(node_id) @@ -2814,13 +2814,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // FIXME #4951: Do we need a node ID here? let type_parameters = match trait_item.node { - ast::RequiredMethod(ref ty_m) => { - HasTypeParameters(&ty_m.generics, + ast::RequiredMethod(ref sig) => { + HasTypeParameters(&sig.generics, FnSpace, MethodRibKind) } ast::ProvidedMethod(ref m) => { - HasTypeParameters(m.pe_generics(), + HasTypeParameters(&m.pe_sig().generics, FnSpace, MethodRibKind) } @@ -3075,7 +3075,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // We also need a new scope for the method- // specific type parameters. let type_parameters = - HasTypeParameters(method.pe_generics(), + HasTypeParameters(&method.pe_sig().generics, FnSpace, MethodRibKind); this.with_type_parameter_rib(type_parameters, |this| { @@ -3956,11 +3956,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let explicit_self = match this.ast_map.get(did.node) { ast_map::NodeTraitItem(trait_item) => match trait_item.node { ast::RequiredMethod(ref m) => &m.explicit_self, - ast::ProvidedMethod(ref m) => m.pe_explicit_self(), + ast::ProvidedMethod(ref m) => &m.pe_sig().explicit_self, _ => return false }, ast_map::NodeImplItem(impl_item) => match impl_item.node { - ast::MethodImplItem(ref m) => m.pe_explicit_self(), + ast::MethodImplItem(ref m) => &m.pe_sig().explicit_self, _ => return false }, _ => return false diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 953650209645b..2b1def22ed9ab 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -382,21 +382,21 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { decl_id, scope_id); - self.process_formals(&method.pe_fn_decl().inputs, qualname); + self.process_formals(&method.pe_sig().decl.inputs, qualname); // walk arg and return types - for arg in &method.pe_fn_decl().inputs { + for arg in &method.pe_sig().decl.inputs { self.visit_ty(&*arg.ty); } - if let ast::Return(ref ret_ty) = method.pe_fn_decl().output { + if let ast::Return(ref ret_ty) = method.pe_sig().decl.output { self.visit_ty(&**ret_ty); } // walk the fn body self.nest(id, |v| v.visit_block(&*method.pe_body())); - self.process_generic_params(method.pe_generics(), + self.process_generic_params(&method.pe_sig().generics, span, qualname, id); diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 0b98beb53c57a..11495c7e6a37a 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -1292,7 +1292,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, match item.node { ast::ItemFn(ref fn_decl, _, _, ref generics, ref top_level_block) => { - (item.ident, &**fn_decl, generics, &**top_level_block, item.span, true) + (item.ident, fn_decl, generics, &**top_level_block, item.span, true) } _ => { cx.sess().span_bug(item.span, @@ -1308,8 +1308,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } (impl_item.ident, - method.pe_fn_decl(), - method.pe_generics(), + &method.pe_sig().decl, + &method.pe_sig().generics, method.pe_body(), impl_item.span, true) @@ -1326,7 +1326,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ast::ExprClosure(_, ref fn_decl, ref top_level_block) => { let name = format!("fn{}", token::gensym("fn")); let name = token::str_to_ident(&name[..]); - (name, &**fn_decl, + (name, fn_decl, // This is not quite right. It should actually inherit // the generics of the enclosing function. &empty_generics, @@ -1347,8 +1347,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } (trait_item.ident, - method.pe_fn_decl(), - method.pe_generics(), + &method.pe_sig().decl, + &method.pe_sig().generics, method.pe_body(), trait_item.span, true) diff --git a/src/librustc_trans/trans/inline.rs b/src/librustc_trans/trans/inline.rs index 6c1401a4c029b..eacc40edcc662 100644 --- a/src/librustc_trans/trans/inline.rs +++ b/src/librustc_trans/trans/inline.rs @@ -149,11 +149,11 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) 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() { + mth.pe_sig().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_sig().decl, &*mth.pe_body(), llfn, empty_substs, diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index aea922d9f9f57..8df086fd232a5 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -80,13 +80,13 @@ pub fn trans_impl(ccx: &CrateContext, for impl_item in impl_items { match impl_item.node { ast::MethodImplItem(ref method) => { - if method.pe_generics().ty_params.len() == 0 { + if method.pe_sig().generics.ty_params.len() == 0 { 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, impl_item.id); let empty_substs = tcx.mk_substs(Substs::trans_empty()); trans_fn(ccx, - method.pe_fn_decl(), + &method.pe_sig().decl, method.pe_body(), llfn, empty_substs, diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index 1af783373f9ce..80271a72c6859 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -223,7 +223,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let needs_body = setup_lldecl(d, &impl_item.attrs); if needs_body { trans_fn(ccx, - mth.pe_fn_decl(), + &mth.pe_sig().decl, mth.pe_body(), d, psubsts, @@ -243,7 +243,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let d = mk_lldecl(abi::Rust); let needs_body = setup_lldecl(d, &trait_item.attrs); if needs_body { - trans_fn(ccx, mth.pe_fn_decl(), mth.pe_body(), d, + trans_fn(ccx, &mth.pe_sig().decl, mth.pe_body(), d, psubsts, trait_item.id, &[]); } d diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 9c2bc4da64f33..28e7027b2124a 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1442,22 +1442,19 @@ struct SelfInfo<'a, 'tcx> { } pub fn ty_of_method<'tcx>(this: &AstConv<'tcx>, - unsafety: ast::Unsafety, - untransformed_self_ty: Ty<'tcx>, - explicit_self: &ast::ExplicitSelf, - decl: &ast::FnDecl, - abi: abi::Abi) + sig: &ast::MethodSig, + untransformed_self_ty: Ty<'tcx>) -> (ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory) { let self_info = Some(SelfInfo { untransformed_self_ty: untransformed_self_ty, - explicit_self: explicit_self, + explicit_self: &sig.explicit_self, }); let (bare_fn_ty, optional_explicit_self_category) = ty_of_method_or_bare_fn(this, - unsafety, - abi, + sig.unsafety, + sig.abi, self_info, - decl); + &sig.decl); (bare_fn_ty, optional_explicit_self_category.unwrap()) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 3ffc36d3acb75..470e1d54c7f77 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -867,7 +867,7 @@ fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, debug!("check_method_body: fty={}", fty.repr(ccx.tcx)); check_bare_fn(ccx, - &*method.pe_fn_decl(), + &*method.pe_sig().decl, &*method.pe_body(), id, span, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index b90129f7ab7f8..a2ca228b11a94 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -621,152 +621,52 @@ fn get_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } } -fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, - trait_id: ast::NodeId, - trait_def: &ty::TraitDef<'tcx>, - trait_predicates: &ty::GenericPredicates<'tcx>) { - let tcx = ccx.tcx; - if let ast_map::NodeItem(item) = tcx.map.get(trait_id) { - if let ast::ItemTrait(_, _, _, ref trait_items) = item.node { - // 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.node { - ast::RequiredMethod(_) | - ast::ProvidedMethod(_) => { - 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, - trait_item.id, - trait_item.ident, - &m.explicit_self, - m.abi, - &m.generics, - &m.unsafety, - &*m.decl) - } - ast::ProvidedMethod(ref m) => { - ty_method_of_trait_method( - ccx, - trait_id, - &trait_def.generics, - &trait_predicates, - 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(..) => unreachable!() - }); - - debug!("ty_method_of_trait_method yielded {} for method {} of trait {}", - ty_method.repr(ccx.tcx), - trait_item.repr(ccx.tcx), - local_def(trait_id).repr(ccx.tcx)); - - make_method_ty(ccx, &*ty_method); - - tcx.impl_or_trait_items - .borrow_mut() - .insert(ty_method.def_id, ty::MethodTraitItem(ty_method)); - } - ast::TypeTraitItem(..) => { - let trait_did = local_def(trait_id); - let associated_type = ty::AssociatedType { - name: trait_item.ident.name, - vis: ast::Public, - def_id: local_def(trait_item.id), - container: TraitContainer(trait_did), - }; - - let trait_item = ty::TypeTraitItem(Rc::new(associated_type)); - tcx.impl_or_trait_items - .borrow_mut() - .insert(associated_type.def_id, trait_item); - } - } - } - - // Add an entry mapping - 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()); +fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, + container: ImplOrTraitItemContainer, + sig: &ast::MethodSig, + 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>) { + let ty_generics = ty_generics_for_fn(ccx, &sig.generics, rcvr_ty_generics); + + let ty_generic_predicates = + ty_generic_predicates_for_fn(ccx, &sig.generics, rcvr_ty_predicates); + + let (fty, explicit_self_category) = + astconv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)), + sig, untransformed_rcvr_ty); + + let def_id = local_def(id); + let ty_method = ty::Method::new(ident.name, + ty_generics, + ty_generic_predicates, + fty, + explicit_self_category, + vis, + def_id, + container, + None); + + let fty = ty::mk_bare_fn(ccx.tcx, Some(def_id), + ccx.tcx.mk_bare_fn(ty_method.fty.clone())); + debug!("method {} (id {}) has type {}", + ident.repr(ccx.tcx), id, fty.repr(ccx.tcx)); + ccx.tcx.tcache.borrow_mut().insert(def_id,TypeScheme { + generics: ty_method.generics.clone(), + ty: fty + }); + ccx.tcx.predicates.borrow_mut().insert(def_id, ty_method.predicates.clone()); - let trait_def_id = local_def(trait_id); - tcx.trait_item_def_ids.borrow_mut().insert(trait_def_id, trait_item_def_ids); - } - } + write_ty_to_tcx(ccx.tcx, id, fty); - fn make_method_ty<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, m: &ty::Method<'tcx>) { - ccx.tcx.tcache.borrow_mut().insert( - m.def_id, - TypeScheme { - generics: m.generics.clone(), - ty: ty::mk_bare_fn(ccx.tcx, Some(m.def_id), ccx.tcx.mk_bare_fn(m.fty.clone())) - }); - ccx.tcx.predicates.borrow_mut().insert( - m.def_id, - m.predicates.clone()); - } + debug!("writing method type: def_id={:?} mty={}", + def_id, ty_method.repr(ccx.tcx)); - fn ty_method_of_trait_method<'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_ident: ast::Ident, - m_explicit_self: &ast::ExplicitSelf, - m_abi: abi::Abi, - m_generics: &ast::Generics, - m_unsafety: &ast::Unsafety, - m_decl: &ast::FnDecl) - -> ty::Method<'tcx> - { - let ty_generics = - ty_generics_for_fn(ccx, m_generics, trait_generics); - - let ty_generic_predicates = - ty_generic_predicates_for_fn(ccx, m_generics, trait_bounds); - - let (fty, explicit_self_category) = { - let trait_self_ty = ty::mk_self_type(ccx.tcx); - astconv::ty_of_method(&ccx.icx(&(trait_bounds, m_generics)), - *m_unsafety, - trait_self_ty, - m_explicit_self, - m_decl, - m_abi) - }; - - ty::Method::new( - 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), - TraitContainer(local_def(trait_id)), - None - ) - } + ccx.tcx.impl_or_trait_items.borrow_mut().insert(def_id, + ty::MethodTraitItem(Rc::new(ty_method))); } fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, @@ -809,20 +709,19 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, - trait_def: &ty::TraitDef<'tcx>, + container: ImplOrTraitItemContainer, ident: ast::Ident, - id: ast::NodeId) + id: ast::NodeId, + vis: ast::Visibility) { let associated_type = Rc::new(ty::AssociatedType { name: ident.name, - vis: ast::Public, + vis: vis, def_id: local_def(id), - container: TraitContainer(trait_def.trait_ref.def_id), + container: container }); - ccx.tcx - .impl_or_trait_items - .borrow_mut() - .insert(associated_type.def_id, ty::TypeTraitItem(associated_type)); + ccx.tcx.impl_or_trait_items.borrow_mut() + .insert(local_def(id), ty::TypeTraitItem(associated_type)); } fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>, @@ -830,9 +729,8 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>, 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 + rcvr_ty_predicates: &ty::GenericPredicates<'tcx>) + where I: Iterator { debug!("convert_methods(untransformed_rcvr_ty={}, rcvr_ty_generics={}, rcvr_ty_predicates={})", untransformed_rcvr_ty.repr(ccx.tcx), @@ -841,87 +739,20 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>, let tcx = ccx.tcx; let mut seen_methods = FnvHashSet(); - for (m, id, ident, vis, span) in methods { + for (sig, id, ident, vis, span) in methods { if !seen_methods.insert(ident.name) { - span_err!(tcx.sess, span, E0201, "duplicate method in trait impl"); + span_err!(tcx.sess, span, E0201, "duplicate method"); } - 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 {}", - ident.repr(tcx), - id, - fty.repr(tcx)); - tcx.tcache.borrow_mut().insert( - m_def_id, - TypeScheme { - generics: mty.generics.clone(), - ty: fty - }); - tcx.predicates.borrow_mut().insert(m_def_id, mty.predicates.clone()); - - write_ty_to_tcx(tcx, id, fty); - - debug!("writing method type: def_id={:?} mty={}", - mty.def_id, mty.repr(ccx.tcx)); - - tcx.impl_or_trait_items - .borrow_mut() - .insert(mty.def_id, ty::MethodTraitItem(mty)); - } - - 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>, - rcvr_visibility: ast::Visibility) - -> ty::Method<'tcx> - { - let m_ty_generics = - ty_generics_for_fn(ccx, m.pe_generics(), rcvr_ty_generics); - - let m_ty_generic_predicates = - ty_generic_predicates_for_fn(ccx, m.pe_generics(), rcvr_ty_predicates); - - let (fty, explicit_self_category) = - astconv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, m.pe_generics())), - m.pe_unsafety(), - untransformed_rcvr_ty, - m.pe_explicit_self(), - &*m.pe_fn_decl(), - m.pe_abi()); - - // if the method specifies a visibility, use that, otherwise - // 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 = vis.inherit_from(rcvr_visibility); - - ty::Method::new(ident.name, - m_ty_generics, - m_ty_generic_predicates, - fty, - explicit_self_category, - method_vis, - local_def(id), - container, - None) + convert_method(ccx, + container, + sig, + id, + ident, + vis, + untransformed_rcvr_ty, + rcvr_ty_generics, + rcvr_ty_predicates); } } @@ -1013,6 +844,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { it.vis }; + // Convert all the associated types. for impl_item in impl_items { match impl_item.node { ast::MethodImplItem(_) => {} @@ -1022,6 +854,9 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { "associated items are not allowed in inherent impls"); } + convert_associated_type(ccx, ImplContainer(local_def(it.id)), + impl_item.ident, impl_item.id, impl_item.vis); + let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty); tcx.tcache.borrow_mut().insert(local_def(impl_item.id), TypeScheme { @@ -1031,17 +866,6 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { tcx.predicates.borrow_mut().insert(local_def(impl_item.id), ty::GenericPredicates::empty()); write_ty_to_tcx(tcx, impl_item.id, typ); - - let associated_type = Rc::new(ty::AssociatedType { - 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(impl_item.id), - ty::TypeTraitItem(associated_type)); } } } @@ -1049,7 +873,12 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { 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)) + // if the method specifies a visibility, use that, otherwise + // 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 = ii.vis.inherit_from(parent_visibility); + Some((m.pe_sig(), ii.id, ii.ident, method_vis, ii.span)) } ast::TypeImplItem(_) => None } @@ -1059,8 +888,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { methods, selfty, &ty_generics, - &ty_predicates, - parent_visibility); + &ty_predicates); for impl_item in impl_items { match impl_item.node { @@ -1070,7 +898,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { &BindingRscope::new(), ccx.method_ty(impl_item.id), selfty, - method.pe_explicit_self(), + &method.pe_sig().explicit_self, body_id); } ast::TypeImplItem(_) => {} @@ -1095,63 +923,68 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { let _: Result<(), ErrorReported> = // any error is already reported, can ignore ccx.ensure_super_predicates(it.span, local_def(it.id)); convert_trait_predicates(ccx, it); - let trait_predicates = ty::lookup_predicates(ccx.tcx, local_def(it.id)); + let trait_predicates = ty::lookup_predicates(tcx, local_def(it.id)); 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)) - } + // Convert all the associated types. + for trait_item in trait_items { + match trait_item.node { ast::RequiredMethod(_) | - ast::TypeTraitItem(..) => None, + ast::ProvidedMethod(_) => {} + ast::TypeTraitItem(..) => { + convert_associated_type(ccx, TraitContainer(local_def(it.id)), + trait_item.ident, trait_item.id, ast::Public); + } } + }; + + let methods = trait_items.iter().filter_map(|ti| { + let sig = match ti.node { + ast::RequiredMethod(ref sig) => sig, + ast::ProvidedMethod(ref m) => m.pe_sig(), + ast::TypeTraitItem(..) => return None, + }; + Some((sig, ti.id, ti.ident, ast::Inherited, ti.span)) }); - // Run convert_methods on the provided methods. - let untransformed_rcvr_ty = ty::mk_self_type(tcx); + + // Run convert_methods on the trait methods. convert_methods(ccx, TraitContainer(local_def(it.id)), methods, - untransformed_rcvr_ty, + ty::mk_self_type(tcx), &trait_def.generics, - &trait_predicates, - it.vis); - - // We need to do this *after* converting methods, since - // convert_methods produces a tcache entry that is wrong for - // static trait methods. This is somewhat unfortunate. - collect_trait_methods(ccx, it.id, &*trait_def, &trait_predicates); + &trait_predicates); - // This must be done after `collect_trait_methods` so that - // we have a method type stored for every method. - for trait_item in trait_items { - let self_type = ty::mk_self_type(tcx); + // Add an entry mapping + 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(ref type_method) => { - let rscope = BindingRscope::new(); - check_method_self_type(ccx, - &rscope, - ccx.method_ty(trait_item.id), - self_type, - &type_method.explicit_self, - it.id) - } - ast::ProvidedMethod(ref method) => { - check_method_self_type(ccx, - &BindingRscope::new(), - ccx.method_ty(trait_item.id), - self_type, - method.pe_explicit_self(), - it.id) + ast::RequiredMethod(_) | + ast::ProvidedMethod(_) => { + ty::MethodTraitItemId(def_id) } ast::TypeTraitItem(..) => { - convert_associated_type(ccx, - &*trait_def, - trait_item.ident, - trait_item.id); + ty::TypeTraitItemId(def_id) } } + }).collect()); + tcx.trait_item_def_ids.borrow_mut().insert(local_def(it.id), trait_item_def_ids); + + // This must be done after `collect_trait_methods` so that + // we have a method type stored for every method. + for trait_item in trait_items { + let sig = match trait_item.node { + ast::RequiredMethod(ref sig) => sig, + ast::ProvidedMethod(ref method) => method.pe_sig(), + ast::TypeTraitItem(..) => continue + }; + check_method_self_type(ccx, + &BindingRscope::new(), + ccx.method_ty(trait_item.id), + ty::mk_self_type(tcx), + &sig.explicit_self, + it.id) } }, ast::ItemStruct(ref struct_def, _) => { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 202b5f59fb7bb..05139bf1eab91 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -951,8 +951,8 @@ pub struct Method { 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 { + let all_inputs = &self.pe_sig().decl.inputs; + let inputs = match self.pe_sig().explicit_self.node { ast::SelfStatic => &**all_inputs, _ => &all_inputs[1..] }; @@ -960,15 +960,15 @@ impl Clean for ast::Method { inputs: Arguments { values: inputs.clean(cx), }, - output: self.pe_fn_decl().output.clean(cx), + output: self.pe_sig().decl.output.clean(cx), attrs: Vec::new() }; Method { - generics: self.pe_generics().clean(cx), - self_: self.pe_explicit_self().node.clean(cx), - unsafety: self.pe_unsafety().clone(), + generics: self.pe_sig().generics.clean(cx), + self_: self.pe_sig().explicit_self.node.clean(cx), + unsafety: self.pe_sig().unsafety.clone(), decl: decl, - abi: self.pe_abi() + abi: self.pe_sig().abi } } } @@ -982,7 +982,7 @@ pub struct TyMethod { pub abi: abi::Abi } -impl Clean for ast::TypeMethod { +impl Clean for ast::MethodSig { fn clean(&self, cx: &DocContext) -> TyMethod { let inputs = match self.explicit_self.node { ast::SelfStatic => &*self.decl.inputs, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index bc1767fa3a44d..0a08b0b12072f 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1058,10 +1058,10 @@ pub struct TypeField { pub span: Span, } -/// Represents a required method in a trait declaration, -/// one without a default implementation +/// Represents a method's signature in a trait declaration, +/// or in an implementation. #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct TypeMethod { +pub struct MethodSig { pub unsafety: Unsafety, pub abi: Abi, pub decl: P, @@ -1084,7 +1084,7 @@ pub struct TraitItem { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum TraitItem_ { - RequiredMethod(TypeMethod), + RequiredMethod(MethodSig), ProvidedMethod(Method), TypeTraitItem(TyParamBounds, Option>), } @@ -1419,12 +1419,7 @@ pub type ExplicitSelf = Spanned; #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum Method { /// Represents a method declaration - MethDecl(Generics, - Abi, - ExplicitSelf, - Unsafety, - P, - P), + MethDecl(MethodSig, P), /// Represents a macro in method position MethMac(Mac), } diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs index 053c315334088..345ccf902cd8a 100644 --- a/src/libsyntax/ast_map/blocks.rs +++ b/src/libsyntax/ast_map/blocks.rs @@ -162,7 +162,7 @@ impl<'a> FnLikeNode<'a> { 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_sig().decl, |c: ClosureParts<'a>| c.decl) } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 673ea4ac43151..91ddc8beec81c 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::Abi; use ast::*; use ast; use ast_util; @@ -461,7 +460,7 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { self.visit_generics_helper(generics) } visit::FkMethod(_, m) => { - self.visit_generics_helper(m.pe_generics()) + self.visit_generics_helper(&m.pe_sig().generics) } visit::FkFnBlock => {} } @@ -653,11 +652,7 @@ 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_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_sig<'a>(&'a self) -> &'a ast::MethodSig; fn pe_body<'a>(&'a self) -> &'a ast::Block; } @@ -676,18 +671,8 @@ macro_rules! mf_method{ impl PostExpansionMethod for Method { - mf_method! { - pe_generics,&'a ast::Generics, - MethDecl(ref generics,_,_,_,_,_),generics - } - mf_method! { pe_abi,Abi,MethDecl(_,abi,_,_,_,_),abi } - mf_method! { - pe_explicit_self,&'a ast::ExplicitSelf, - MethDecl(_,_,ref explicit_self,_,_,_),explicit_self - } - mf_method! { pe_unsafety,ast::Unsafety,MethDecl(_,_,_,unsafety,_,_),unsafety } - mf_method! { pe_fn_decl,&'a ast::FnDecl,MethDecl(_,_,_,_,ref decl,_),&**decl } - mf_method! { pe_body,&'a ast::Block,MethDecl(_,_,_,_,_,ref body),&**body } + mf_method! { pe_sig, &'a ast::MethodSig,MethDecl(ref sig, _), sig } + mf_method! { pe_body, &'a ast::Block,MethDecl(_, ref body), body } } #[cfg(test)] diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index a4962afff3c01..d4b0f7d1dcb85 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -724,13 +724,13 @@ impl<'a> MethodDef<'a> { span: trait_.span, vis: ast::Inherited, ident: method_ident, - node: ast::MethodImplItem( - ast::MethDecl(fn_generics, - abi, - explicit_self, - ast::Unsafety::Normal, - fn_decl, - body_block)) + node: ast::MethodImplItem(ast::MethDecl(ast::MethodSig { + generics: fn_generics, + abi: abi, + explicit_self: explicit_self, + unsafety: ast::Unsafety::Normal, + decl: fn_decl + }, body_block)) }) } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 5fb0126cdd09c..fa0b747f45b99 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1393,15 +1393,16 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { fn fold_method(&mut self, m: ast::Method) -> ast::Method { match m { - ast::MethDecl(generics, abi, explicit_self, fn_style, decl, body) => { + ast::MethDecl(sig, 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) + = expand_and_rename_fn_decl_and_block(sig.decl, body, self); + ast::MethDecl(ast::MethodSig { + generics: self.fold_generics(sig.generics), + abi: sig.abi, + explicit_self: self.fold_explicit_self(sig.explicit_self), + unsafety: sig.unsafety, + decl: rewritten_fn_decl + }, rewritten_body) } ast::MethMac(mac) => ast::MethMac(mac) } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index d99f1600cb388..d7982ef839969 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -977,15 +977,7 @@ pub fn noop_fold_trait_item(i: P, folder: &mut T) 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) - }) - } + RequiredMethod(sig) => RequiredMethod(noop_fold_method_sig(sig, folder)), ProvidedMethod(m) => ProvidedMethod(folder.fold_method(m)), TypeTraitItem(bounds, default) => { TypeTraitItem(folder.fold_bounds(bounds), @@ -1110,23 +1102,24 @@ pub fn noop_fold_foreign_item(ni: P, folder: &mut T) -> // Default fold over a method. 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, - folder.fold_explicit_self(explicit_self), - unsafety, - folder.fold_fn_decl(decl), + MethDecl(sig, body) => { + MethDecl(noop_fold_method_sig(sig, folder), folder.fold_block(body)) }, MethMac(mac) => MethMac(folder.fold_mac(mac)) } } +pub fn noop_fold_method_sig(sig: MethodSig, folder: &mut T) -> MethodSig { + MethodSig { + generics: folder.fold_generics(sig.generics), + abi: sig.abi, + explicit_self: folder.fold_explicit_self(sig.explicit_self), + unsafety: sig.unsafety, + decl: folder.fold_fn_decl(sig.decl) + } +} + pub fn noop_fold_pat(p: P, folder: &mut T) -> P { p.map(|Pat {id, node, span}| Pat { id: folder.new_id(id), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a38508d2cf50b..2e77bd6df1886 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -51,8 +51,7 @@ use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue}; use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef}; use ast::{TtDelimited, TtSequence, TtToken}; use ast::{TupleVariantKind, Ty, Ty_, TypeBinding}; -use ast::{TyFixedLengthVec, TyBareFn}; -use ast::{TyTypeof, TyInfer, TypeMethod}; +use ast::{TyFixedLengthVec, TyBareFn, TyTypeof, TyInfer}; use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr}; use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq}; use ast::{TypeImplItem, TypeTraitItem}; @@ -1341,31 +1340,27 @@ impl<'a> Parser<'a> { }); p.parse_where_clause(&mut generics); + let sig = ast::MethodSig { + unsafety: style, + decl: d, + generics: generics, + abi: abi, + explicit_self: explicit_self, + }; let hi = p.last_span.hi; let node = match p.token { token::Semi => { p.bump(); debug!("parse_trait_methods(): parsing required method"); - RequiredMethod(TypeMethod { - unsafety: style, - decl: d, - generics: generics, - abi: abi, - explicit_self: explicit_self, - }) + RequiredMethod(sig) } token::OpenDelim(token::Brace) => { debug!("parse_trait_methods(): parsing provided method"); let (inner_attrs, body) = p.parse_inner_attrs_and_block(); attrs.push_all(&inner_attrs[..]); - ProvidedMethod(ast::MethDecl(generics, - abi, - explicit_self, - style, - d, - body)) + ProvidedMethod(ast::MethDecl(sig, body)) } _ => { @@ -4758,13 +4753,13 @@ impl<'a> Parser<'a> { let body_span = body.span; let mut new_attrs = attrs; new_attrs.push_all(&inner_attrs[..]); - (ast::MethDecl(generics, - abi, - explicit_self, - unsafety, - decl, - body), - body_span.hi, new_attrs, ident) + (ast::MethDecl(ast::MethodSig { + generics: generics, + abi: abi, + explicit_self: explicit_self, + unsafety: unsafety, + decl: decl + }, body), body_span.hi, new_attrs, ident) } }; P(ImplItem { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index a457355698d1f..20c8df4299304 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -375,8 +375,9 @@ pub fn fun_to_string(decl: &ast::FnDecl, unsafety: ast::Unsafety, name: ast::Ide opt_explicit_self: Option<&ast::ExplicitSelf_>, generics: &ast::Generics) -> String { $to_string(|s| { - try!(s.print_fn(decl, Some(unsafety), abi::Rust, - name, generics, opt_explicit_self, ast::Inherited)); + try!(s.head("")); + try!(s.print_fn(decl, unsafety, abi::Rust, Some(name), + generics, opt_explicit_self, ast::Inherited)); try!(s.end()); // Close the head box s.end() // Close the outer box }) @@ -759,8 +760,10 @@ impl<'a> State<'a> { try!(self.print_outer_attributes(&item.attrs)); match item.node { ast::ForeignItemFn(ref decl, ref generics) => { - try!(self.print_fn(&**decl, None, abi::Rust, item.ident, generics, - None, item.vis)); + try!(self.head("")); + try!(self.print_fn(&**decl, ast::Unsafety::Normal, + abi::Rust, Some(item.ident), + generics, None, item.vis)); try!(self.end()); // end head-ibox try!(word(&mut self.s, ";")); self.end() // end the outer fn box @@ -861,11 +864,12 @@ impl<'a> State<'a> { try!(self.end()); // end the outer cbox } ast::ItemFn(ref decl, unsafety, abi, ref typarams, ref body) => { + try!(self.head("")); try!(self.print_fn( - &**decl, - Some(unsafety), + decl, + unsafety, abi, - item.ident, + Some(item.ident), typarams, None, item.vis @@ -1227,17 +1231,18 @@ impl<'a> State<'a> { } } - 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(ident), - &m.generics, - Some(&m.explicit_self.node))); - word(&mut self.s, ";") + pub fn print_method_sig(&mut self, + ident: ast::Ident, + m: &ast::MethodSig, + vis: ast::Visibility) + -> io::Result<()> { + self.print_fn(&m.decl, + m.unsafety, + m.abi, + Some(ident), + &m.generics, + Some(&m.explicit_self.node), + vis) } pub fn print_trait_item(&mut self, ti: &ast::TraitItem) @@ -1246,8 +1251,9 @@ impl<'a> State<'a> { try!(self.maybe_print_comment(ti.span.lo)); try!(self.print_outer_attributes(&ti.attrs)); match ti.node { - ast::RequiredMethod(ref ty_m) => { - self.print_ty_method(ti.ident, ty_m) + ast::RequiredMethod(ref sig) => { + try!(self.print_method_sig(ti.ident, sig, ast::Inherited)); + word(&mut self.s, ";") } ast::ProvidedMethod(ref m) => { self.print_method(ti.ident, &ti.attrs, ast::Inherited, m) @@ -1280,20 +1286,10 @@ impl<'a> State<'a> { meth: &ast::Method) -> io::Result<()> { match *meth { - ast::MethDecl(ref generics, - abi, - ref explicit_self, - unsafety, - ref decl, - ref body) => { - try!(self.print_fn(&**decl, - Some(unsafety), - abi, - ident, - generics, - Some(&explicit_self.node), - vis)); - try!(word(&mut self.s, " ")); + ast::MethDecl(ref sig, ref body) => { + try!(self.head("")); + try!(self.print_method_sig(ident, sig, vis)); + try!(self.nbsp()); self.print_block_with_attrs(&**body, attrs) }, ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _), @@ -2328,16 +2324,18 @@ impl<'a> State<'a> { pub fn print_fn(&mut self, decl: &ast::FnDecl, - unsafety: Option, + unsafety: ast::Unsafety, abi: abi::Abi, - name: ast::Ident, + name: Option, generics: &ast::Generics, opt_explicit_self: Option<&ast::ExplicitSelf_>, vis: ast::Visibility) -> io::Result<()> { - try!(self.head("")); try!(self.print_fn_header_info(unsafety, abi, vis)); - try!(self.nbsp()); - try!(self.print_ident(name)); + + if let Some(name) = name { + try!(self.nbsp()); + try!(self.print_ident(name)); + } try!(self.print_generics(generics)); try!(self.print_fn_args_and_ret(decl, opt_explicit_self)); self.print_where_clause(generics) @@ -2704,25 +2702,14 @@ impl<'a> State<'a> { abi: abi::Abi, unsafety: ast::Unsafety, decl: &ast::FnDecl, - id: Option, + name: Option, generics: &ast::Generics, opt_explicit_self: Option<&ast::ExplicitSelf_>) -> io::Result<()> { try!(self.ibox(indent_unit)); - try!(self.print_fn_header_info(Some(unsafety), abi, ast::Inherited)); - - match id { - Some(id) => { - try!(word(&mut self.s, " ")); - try!(self.print_ident(id)); - } - _ => () - } - - try!(self.print_generics(generics)); - try!(zerobreak(&mut self.s)); - try!(self.print_fn_args_and_ret(decl, opt_explicit_self)); - try!(self.print_where_clause(generics)); + try!(self.print_fn(decl, unsafety, abi, name, + generics, opt_explicit_self, + ast::Inherited)); self.end() } @@ -2944,14 +2931,6 @@ impl<'a> State<'a> { } } - pub fn print_opt_unsafety(&mut self, - opt_unsafety: Option) -> io::Result<()> { - match opt_unsafety { - Some(unsafety) => self.print_unsafety(unsafety), - None => Ok(()) - } - } - pub fn print_opt_abi_and_extern_if_nondefault(&mut self, opt_abi: Option) -> io::Result<()> { @@ -2977,11 +2956,11 @@ impl<'a> State<'a> { } pub fn print_fn_header_info(&mut self, - opt_unsafety: Option, + unsafety: ast::Unsafety, abi: abi::Abi, vis: ast::Visibility) -> io::Result<()> { try!(word(&mut self.s, &visibility_qualified(vis, ""))); - try!(self.print_opt_unsafety(opt_unsafety)); + try!(self.print_unsafety(unsafety)); if abi != abi::Rust { try!(self.word_nbsp("extern")); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 867f98f6077de..4375e17ce0be9 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -602,11 +602,11 @@ fn walk_method_helper<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, method: &'v Method) { match *method { - MethDecl(_, _, _, _, ref decl, ref body) => { + MethDecl(ref sig, ref body) => { visitor.visit_ident(span, ident); visitor.visit_fn(FkMethod(ident, method), - &**decl, - &**body, + &sig.decl, + body, span, id); }, @@ -627,9 +627,9 @@ pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V, } FkMethod(_, method) => { match *method { - MethDecl(ref generics, _, ref explicit_self, _, _, _) => { - visitor.visit_generics(generics); - visitor.visit_explicit_self(explicit_self); + MethDecl(ref sig, _) => { + visitor.visit_generics(&sig.generics); + visitor.visit_explicit_self(&sig.explicit_self); } MethMac(ref mac) => visitor.visit_mac(mac) } @@ -646,10 +646,10 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai visitor.visit_attribute(attr); } match trait_item.node { - RequiredMethod(ref method_type) => { - visitor.visit_explicit_self(&method_type.explicit_self); - visitor.visit_generics(&method_type.generics); - walk_fn_decl(visitor, &method_type.decl); + RequiredMethod(ref sig) => { + visitor.visit_explicit_self(&sig.explicit_self); + visitor.visit_generics(&sig.generics); + walk_fn_decl(visitor, &sig.decl); } ProvidedMethod(ref method) => { walk_method_helper(visitor, diff --git a/src/test/compile-fail/impl-duplicate-methods.rs b/src/test/compile-fail/impl-duplicate-methods.rs index c0c951dd8b108..3b4def8c50869 100644 --- a/src/test/compile-fail/impl-duplicate-methods.rs +++ b/src/test/compile-fail/impl-duplicate-methods.rs @@ -11,7 +11,7 @@ struct Foo; impl Foo { fn orange(&self){} - fn orange(&self){} //~ ERROR error: duplicate method in trait impl + fn orange(&self){} //~ ERROR error: duplicate method } fn main() {} diff --git a/src/test/compile-fail/issue-4265.rs b/src/test/compile-fail/issue-4265.rs index ab18e0bcddcf0..553436607d159 100644 --- a/src/test/compile-fail/issue-4265.rs +++ b/src/test/compile-fail/issue-4265.rs @@ -17,7 +17,7 @@ impl Foo { Foo { baz: 0 }.bar(); } - fn bar() { //~ ERROR duplicate method in trait impl + fn bar() { //~ ERROR duplicate method } } From 9da918548d77182ca64f375fb6da24036d5ad60c Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Wed, 11 Mar 2015 23:38:58 +0200 Subject: [PATCH 4/4] syntax: move MethMac to MacImplItem and combine {Provided,Required}Method into MethodTraitItem. --- src/librustc/metadata/encoder.rs | 39 +++--- src/librustc/middle/dead.rs | 13 +- src/librustc/middle/effect.rs | 5 +- src/librustc/middle/infer/error_reporting.rs | 28 ++-- src/librustc/middle/reachable.rs | 27 ++-- src/librustc/middle/resolve_lifetime.rs | 9 +- src/librustc/middle/ty.rs | 15 ++- src/librustc/util/ppaux.rs | 3 +- src/librustc_lint/builtin.rs | 20 +-- src/librustc_privacy/lib.rs | 45 ++++--- src/librustc_resolve/build_reduced_graph.rs | 3 +- src/librustc_resolve/lib.rs | 29 ++--- src/librustc_trans/save/mod.rs | 107 +++++---------- src/librustc_trans/trans/base.rs | 26 ++-- src/librustc_trans/trans/debuginfo.rs | 26 ++-- src/librustc_trans/trans/inline.rs | 18 +-- src/librustc_trans/trans/meth.rs | 22 ++-- src/librustc_trans/trans/monomorphize.rs | 15 ++- src/librustc_typeck/check/mod.rs | 44 +++---- src/librustc_typeck/check/wf.rs | 2 +- src/librustc_typeck/coherence/mod.rs | 6 +- src/librustc_typeck/collect.rs | 39 +++--- src/librustdoc/clean/mod.rs | 34 +++-- src/libsyntax/ast.rs | 15 +-- src/libsyntax/ast_map/blocks.rs | 28 ++-- src/libsyntax/ast_map/mod.rs | 22 ++-- src/libsyntax/ast_util.rs | 32 +---- src/libsyntax/ext/base.rs | 12 +- src/libsyntax/ext/deriving/generic/mod.rs | 4 +- src/libsyntax/ext/expand.rs | 130 +++++++++---------- src/libsyntax/ext/tt/macro_rules.rs | 10 +- src/libsyntax/fold.rs | 29 ++--- src/libsyntax/parse/parser.rs | 31 +++-- src/libsyntax/print/pprust.rs | 42 +++--- src/libsyntax/visit.rs | 58 ++------- src/test/auxiliary/macro_crate_test.rs | 23 +++- src/test/compile-fail/lint-missing-doc.rs | 2 +- 37 files changed, 464 insertions(+), 549 deletions(-) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index eb41a26fa7701..611d8bc27d19d 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -827,7 +827,7 @@ 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())); if let Some(impl_item) = impl_item_opt { - if let ast::MethodImplItem(ref ast_method) = impl_item.node { + if let ast::MethodImplItem(ref sig, _) = 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(); @@ -838,7 +838,7 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, if !any_types { encode_symbol(ecx, rbml_w, m.def_id.node); } - encode_method_argument_names(rbml_w, &ast_method.pe_sig().decl); + encode_method_argument_names(rbml_w, &sig.decl); } } @@ -1362,28 +1362,25 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_parent_sort(rbml_w, 't'); let trait_item = &*ms[i]; - let encode_trait_item = |rbml_w: &mut Encoder| { - // If this is a static method, we've already - // encoded this. - if is_nonstatic_method { - // FIXME: I feel like there is something funny - // going on. - encode_bounds_and_type_for_item(rbml_w, ecx, item_def_id.def_id().local_id()); - } - }; encode_attributes(rbml_w, &trait_item.attrs); match trait_item.node { - ast::RequiredMethod(ref m) => { - encode_trait_item(rbml_w); - encode_item_sort(rbml_w, 'r'); - encode_method_argument_names(rbml_w, &*m.decl); - } + ast::MethodTraitItem(ref sig, ref body) => { + // If this is a static method, we've already + // encoded this. + if is_nonstatic_method { + // FIXME: I feel like there is something funny + // going on. + encode_bounds_and_type_for_item(rbml_w, ecx, + item_def_id.def_id().local_id()); + } - ast::ProvidedMethod(ref m) => { - 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_sig().decl); + if body.is_some() { + encode_item_sort(rbml_w, 'p'); + encode_inlined_item(ecx, rbml_w, IITraitItemRef(def_id, trait_item)); + } else { + encode_item_sort(rbml_w, 'r'); + } + encode_method_argument_names(rbml_w, &sig.decl); } ast::TypeTraitItem(..) => { diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 6517378c75cd1..5efea66ab0c6c 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -18,7 +18,7 @@ use util::nodemap::NodeSet; use std::collections::HashSet; use syntax::{ast, ast_map, codemap}; -use syntax::ast_util::{local_def, is_local, PostExpansionMethod}; +use syntax::ast_util::{local_def, is_local}; use syntax::attr::{self, AttrMetaMethods}; use syntax::visit::{self, Visitor}; @@ -353,7 +353,7 @@ impl<'v> Visitor<'v> for LifeSeeder { ast::ItemTrait(_, _, _, ref trait_items) => { for trait_item in trait_items { match trait_item.node { - ast::ProvidedMethod(_) => { + ast::MethodTraitItem(_, Some(_)) => { if has_allow_dead_code_or_lang_attr(&trait_item.attrs) { self.worklist.push(trait_item.id); } @@ -365,13 +365,14 @@ impl<'v> Visitor<'v> for LifeSeeder { ast::ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => { for impl_item in impl_items { match impl_item.node { - ast::MethodImplItem(_) => { + 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(_) => {} + ast::MacImplItem(_) => panic!("unexpanded macro") } } } @@ -578,10 +579,10 @@ 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.node { - ast::ProvidedMethod(ref method) => { - visit::walk_block(self, method.pe_body()) + ast::MethodTraitItem(_, Some(ref body)) => { + visit::walk_block(self, body) } - ast::RequiredMethod(_) | + ast::MethodTraitItem(_, None) | ast::TypeTraitItem(..) => {} } } diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 02f2908a9e6d5..378f3db082339 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -18,7 +18,6 @@ use middle::ty::MethodCall; use util::ppaux; use syntax::ast; -use syntax::ast_util::PostExpansionMethod; use syntax::codemap::Span; use syntax::visit; use syntax::visit::Visitor; @@ -90,8 +89,8 @@ 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) => - (true, method.pe_sig().unsafety == ast::Unsafety::Unsafe), + visit::FkMethod(_, sig) => + (true, sig.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 823acdc169120..1ca56596a0147 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -83,7 +83,7 @@ use std::rc::Rc; use std::string::String; use syntax::ast; use syntax::ast_map; -use syntax::ast_util::{name_to_dummy_lifetime, PostExpansionMethod}; +use syntax::ast_util::name_to_dummy_lifetime; use syntax::owned_slice::OwnedSlice; use syntax::codemap; use syntax::parse::token; @@ -848,25 +848,26 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { } ast_map::NodeImplItem(item) => { match item.node { - ast::MethodImplItem(ref m) => { - Some((&m.pe_sig().decl, - &m.pe_sig().generics, - m.pe_sig().unsafety, + ast::MethodImplItem(ref sig, _) => { + Some((&sig.decl, + &sig.generics, + sig.unsafety, item.ident, - Some(&m.pe_sig().explicit_self.node), + Some(&sig.explicit_self.node), item.span)) } ast::TypeImplItem(_) => None, + ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro") } }, ast_map::NodeTraitItem(item) => { match item.node { - ast::ProvidedMethod(ref m) => { - Some((&m.pe_sig().decl, - &m.pe_sig().generics, - m.pe_sig().unsafety, + ast::MethodTraitItem(ref sig, Some(_)) => { + Some((&sig.decl, + &sig.generics, + sig.unsafety, item.ident, - Some(&m.pe_sig().explicit_self.node), + Some(&sig.explicit_self.node), item.span)) } _ => None @@ -1731,11 +1732,12 @@ fn lifetimes_in_scope(tcx: &ty::ctxt, }, ast_map::NodeImplItem(ii) => { match ii.node { - ast::MethodImplItem(ref m) => { - taken.push_all(&m.pe_sig().generics.lifetimes); + ast::MethodImplItem(ref sig, _) => { + taken.push_all(&sig.generics.lifetimes); Some(ii.id) } ast::TypeImplItem(_) => None, + ast::MacImplItem(_) => tcx.sess.bug("unexpanded macro") } } _ => None diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 75e9c60698ba3..7ded344414ce6 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -25,7 +25,7 @@ use std::collections::HashSet; use syntax::abi; use syntax::ast; use syntax::ast_map; -use syntax::ast_util::{is_local, PostExpansionMethod}; +use syntax::ast_util::is_local; use syntax::attr; use syntax::visit::Visitor; use syntax::visit; @@ -53,11 +53,11 @@ fn item_might_be_inlined(item: &ast::Item) -> bool { } } -fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method, +fn method_might_be_inlined(tcx: &ty::ctxt, sig: &ast::MethodSig, impl_item: &ast::ImplItem, impl_src: ast::DefId) -> bool { if attr::requests_inline(&impl_item.attrs) || - generics_require_inlining(&method.pe_sig().generics) { + generics_require_inlining(&sig.generics) { return true } if is_local(impl_src) { @@ -183,15 +183,14 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { } Some(ast_map::NodeTraitItem(trait_method)) => { match trait_method.node { - ast::RequiredMethod(_) => false, - ast::ProvidedMethod(_) => true, + ast::MethodTraitItem(_, ref body) => body.is_some(), ast::TypeTraitItem(..) => false, } } Some(ast_map::NodeImplItem(impl_item)) => { match impl_item.node { - ast::MethodImplItem(ref method) => { - if generics_require_inlining(&method.pe_sig().generics) || + ast::MethodImplItem(ref sig, _) => { + if generics_require_inlining(&sig.generics) || attr::requests_inline(&impl_item.attrs) { true } else { @@ -214,6 +213,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { } } ast::TypeImplItem(_) => false, + ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro") } } Some(_) => false, @@ -303,24 +303,25 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { } ast_map::NodeTraitItem(trait_method) => { match trait_method.node { - ast::RequiredMethod(..) => { + ast::MethodTraitItem(_, None) => { // Keep going, nothing to get exported } - ast::ProvidedMethod(ref method) => { - visit::walk_block(self, &*method.pe_body()); + ast::MethodTraitItem(_, Some(ref body)) => { + visit::walk_block(self, body); } ast::TypeTraitItem(..) => {} } } ast_map::NodeImplItem(impl_item) => { match impl_item.node { - ast::MethodImplItem(ref method) => { + ast::MethodImplItem(ref sig, ref body) => { let did = self.tcx.map.get_parent_did(search_item); - if method_might_be_inlined(self.tcx, method, impl_item, did) { - visit::walk_block(self, method.pe_body()) + if method_might_be_inlined(self.tcx, sig, impl_item, did) { + visit::walk_block(self, body) } } ast::TypeImplItem(_) => {} + ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro") } } // Nothing to recurse on for these diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 32d52bcbf74ee..e33a255343161 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -25,7 +25,6 @@ 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; @@ -148,8 +147,8 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { visit::walk_fn(this, fk, fd, b, s) }) } - visit::FkMethod(_, m) => { - self.visit_early_late(subst::FnSpace, &m.pe_sig().generics, |this| { + visit::FkMethod(_, sig) => { + self.visit_early_late(subst::FnSpace, &sig.generics, |this| { visit::walk_fn(this, fk, fd, b, s) }) } @@ -191,9 +190,9 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { } fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) { - if let ast::RequiredMethod(ref m) = trait_item.node { + if let ast::MethodTraitItem(ref sig, None) = trait_item.node { self.visit_early_late( - subst::FnSpace, &m.generics, + subst::FnSpace, &sig.generics, |this| visit::walk_trait_item(this, trait_item)) } else { visit::walk_trait_item(self, trait_item); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 32b85d8c0a9be..14d61a3700879 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -82,7 +82,7 @@ use syntax::abi; use syntax::ast::{CrateNum, DefId, Ident, ItemTrait, LOCAL_CRATE}; use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId}; use syntax::ast::{StmtExpr, StmtSemi, StructField, UnnamedField, Visibility}; -use syntax::ast_util::{self, is_local, lit_is_str, local_def, PostExpansionMethod}; +use syntax::ast_util::{self, is_local, lit_is_str, local_def}; use syntax::attr::{self, AttrMetaMethods}; use syntax::codemap::Span; use syntax::parse::token::{self, InternedString, special_idents}; @@ -2287,7 +2287,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { match cx.map.find(id) { Some(ast_map::NodeImplItem(ref impl_item)) => { match impl_item.node { - ast::MethodImplItem(ref method) => { + ast::MethodImplItem(_, ref body) => { let method_def_id = ast_util::local_def(id); match ty::impl_or_trait_item(cx, method_def_id) { MethodTraitItem(ref method_ty) => { @@ -2298,7 +2298,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { impl_item.span, method_generics, method_bounds, - method.pe_body().id) + body.id) } TypeTraitItem(_) => { cx.sess @@ -2313,18 +2313,19 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { can't create a parameter environment \ for type impl items") } + ast::MacImplItem(_) => cx.sess.bug("unexpanded macro") } } Some(ast_map::NodeTraitItem(trait_item)) => { match trait_item.node { - ast::RequiredMethod(_) => { + ast::MethodTraitItem(_, None) => { cx.sess.span_bug(trait_item.span, "ParameterEnvironment::for_item(): can't create a parameter \ environment for required trait \ methods") } - ast::ProvidedMethod(ref method) => { + ast::MethodTraitItem(_, Some(ref body)) => { let method_def_id = ast_util::local_def(id); match ty::impl_or_trait_item(cx, method_def_id) { MethodTraitItem(ref method_ty) => { @@ -2335,7 +2336,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { trait_item.span, method_generics, method_bounds, - method.pe_body().id) + body.id) } TypeTraitItem(_) => { cx.sess @@ -5082,7 +5083,7 @@ 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(_) = ti.node { + if let ast::MethodTraitItem(_, Some(_)) = ti.node { match impl_or_trait_item(cx, ast_util::local_def(ti.id)) { MethodTraitItem(m) => Some(m), TypeTraitItem(_) => { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index f1041809701e1..3a0b5832c9f5b 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -829,8 +829,7 @@ impl<'tcx> Repr<'tcx> for ty::TraitDef<'tcx> { impl<'tcx> Repr<'tcx> for ast::TraitItem { fn repr(&self, _tcx: &ctxt) -> String { let kind = match self.node { - ast::RequiredMethod(_) => "RequiredMethod", - ast::ProvidedMethod(_) => "ProvidedMethod", + ast::MethodTraitItem(..) => "MethodTraitItem", ast::TypeTraitItem(..) => "TypeTraitItem", }; format!("{}({}, id={})", kind, self.ident, self.id) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 687b4cb8723df..074591fb927d2 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -46,7 +46,7 @@ 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::{self, is_shift_binop, local_def, PostExpansionMethod}; +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}; @@ -1005,7 +1005,7 @@ impl LintPass for NonSnakeCase { } fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) { - if let ast::RequiredMethod(_) = trait_item.node { + if let ast::MethodTraitItem(_, None) = trait_item.node { self.check_snake_case(cx, "trait method", trait_item.ident, trait_item.span); } } @@ -1318,8 +1318,8 @@ impl LintPass for UnsafeCode { visit::FkItemFn(_, _, ast::Unsafety::Unsafe, _) => cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` function"), - visit::FkMethod(_, m) => { - if m.pe_sig().unsafety == ast::Unsafety::Unsafe { + visit::FkMethod(_, sig) => { + if sig.unsafety == ast::Unsafety::Unsafe { cx.span_lint(UNSAFE_CODE, span, "implementation of an `unsafe` method") } }, @@ -1329,8 +1329,8 @@ impl LintPass for UnsafeCode { } 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 { + if let ast::MethodTraitItem(ref sig, None) = trait_item.node { + if sig.unsafety == ast::Unsafety::Unsafe { cx.span_lint(UNSAFE_CODE, trait_item.span, "declaration of an `unsafe` method") } @@ -1564,8 +1564,7 @@ impl LintPass for MissingDoc { 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::MethodTraitItem(..) => "a trait method", ast::TypeTraitItem(..) => "an associated type" }; self.check_missing_docs_attrs(cx, Some(trait_item.id), @@ -1580,8 +1579,9 @@ impl LintPass for MissingDoc { } let desc = match impl_item.node { - ast::MethodImplItem(_) => "a method", - ast::TypeImplItem(_) => "an associated type" + ast::MethodImplItem(..) => "a method", + ast::TypeImplItem(_) => "an associated type", + ast::MacImplItem(_) => "an impl item macro" }; self.check_missing_docs_attrs(cx, Some(impl_item.id), &impl_item.attrs, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 9b069962de409..27f807ebe429b 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -48,7 +48,7 @@ use rustc::middle::ty::{self, Ty}; use rustc::util::nodemap::{NodeMap, NodeSet}; use syntax::{ast, ast_map}; -use syntax::ast_util::{is_local, local_def, PostExpansionMethod}; +use syntax::ast_util::{is_local, local_def}; use syntax::codemap::Span; use syntax::parse::token; use syntax::visit::{self, Visitor}; @@ -273,17 +273,17 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> { if public_ty || public_trait { for impl_item in impl_items { match impl_item.node { - ast::MethodImplItem(ref method) => { - let meth_public = - match method.pe_sig().explicit_self.node { - ast::SelfStatic => public_ty, - _ => true, - } && impl_item.vis == ast::Public; + ast::MethodImplItem(ref sig, _) => { + let meth_public = match sig.explicit_self.node { + ast::SelfStatic => public_ty, + _ => true, + } && impl_item.vis == ast::Public; if meth_public || tr.is_some() { self.exported_items.insert(impl_item.id); } } - ast::TypeImplItem(_) => {} + ast::TypeImplItem(_) | + ast::MacImplItem(_) => {} } } } @@ -491,7 +491,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { // where the method was defined? Some(ast_map::NodeImplItem(ii)) => { match ii.node { - ast::MethodImplItem(_) => { + ast::MethodImplItem(..) => { let imp = self.tcx.map .get_parent_did(closest_private_id); match ty::impl_trait_ref(self.tcx, imp) { @@ -502,7 +502,8 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { _ => ii.vis } } - ast::TypeImplItem(_) => return Allowable, + ast::TypeImplItem(_) | + ast::MacImplItem(_) => return Allowable, } } Some(ast_map::NodeTraitItem(_)) => { @@ -1125,10 +1126,11 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> { ast::ItemImpl(_, _, _, _, _, ref impl_items) => { for impl_item in impl_items { match impl_item.node { - ast::MethodImplItem(_) => { + ast::MethodImplItem(..) => { check_inherited(tcx, impl_item.span, impl_item.vis); } - ast::TypeImplItem(_) => {} + ast::TypeImplItem(_) | + ast::MacImplItem(_) => {} } } } @@ -1302,10 +1304,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { impl_items.iter() .any(|impl_item| { match impl_item.node { - ast::MethodImplItem(_) => { + ast::MethodImplItem(..) => { self.exported_items.contains(&impl_item.id) } - ast::TypeImplItem(_) => false, + ast::TypeImplItem(_) | + ast::MacImplItem(_) => false, } }); @@ -1340,10 +1343,11 @@ 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.node { - ast::MethodImplItem(..) => {}, ast::TypeImplItem(ref ty) => { self.visit_ty(ty); } + ast::MethodImplItem(..) | + ast::MacImplItem(_) => {}, } } } @@ -1354,16 +1358,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { let mut found_pub_static = false; for impl_item in impl_items { match impl_item.node { - ast::MethodImplItem(ref method) => { - if method.pe_sig().explicit_self.node == - ast::SelfStatic && - self.exported_items - .contains(&impl_item.id) { + ast::MethodImplItem(ref sig, _) => { + if sig.explicit_self.node == ast::SelfStatic && + self.exported_items.contains(&impl_item.id) { found_pub_static = true; visit::walk_impl_item(self, impl_item); } } - ast::TypeImplItem(_) => {} + ast::TypeImplItem(_) | + ast::MacImplItem(_) => {} } } if found_pub_static { diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index dd762f07b7246..1cbbcad955090 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -531,8 +531,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { trait_item.span); match trait_item.node { - ast::RequiredMethod(_) | - ast::ProvidedMethod(_) => { + ast::MethodTraitItem(..) => { let def = DefMethod(local_def(trait_item.id), FromTrait(local_def(item.id))); // NB: not IMPORTABLE diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 296a9794f1cea..e49fdc9c5d356 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -82,7 +82,7 @@ use syntax::ast::{TyRptr, TyStr, TyUs, TyU8, TyU16, TyU32, TyU64, TyUint}; use syntax::ast::{TypeImplItem}; use syntax::ast; use syntax::ast_map; -use syntax::ast_util::{PostExpansionMethod, local_def, walk_pat}; +use syntax::ast_util::{local_def, walk_pat}; use syntax::attr::AttrMetaMethods; use syntax::ext::mtwt; use syntax::parse::token::{self, special_names, special_idents}; @@ -242,9 +242,9 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { self.visit_generics(generics); ItemRibKind } - visit::FkMethod(_, method) => { - self.visit_generics(&method.pe_sig().generics); - self.visit_explicit_self(&method.pe_sig().explicit_self); + visit::FkMethod(_, sig) => { + self.visit_generics(&sig.generics); + self.visit_explicit_self(&sig.explicit_self); MethodRibKind } visit::FkFnBlock(..) => ClosureRibKind(node_id) @@ -2814,16 +2814,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // FIXME #4951: Do we need a node ID here? let type_parameters = match trait_item.node { - ast::RequiredMethod(ref sig) => { + ast::MethodTraitItem(ref sig, _) => { HasTypeParameters(&sig.generics, FnSpace, MethodRibKind) } - ast::ProvidedMethod(ref m) => { - HasTypeParameters(&m.pe_sig().generics, - FnSpace, - MethodRibKind) - } ast::TypeTraitItem(..) => { this.check_if_primitive_type_name(trait_item.ident.name, trait_item.span); @@ -3066,7 +3061,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { this.with_current_self_type(self_type, |this| { for impl_item in impl_items { match impl_item.node { - MethodImplItem(ref method) => { + MethodImplItem(ref sig, _) => { // If this is a trait impl, ensure the method // exists in trait this.check_trait_item(impl_item.ident.name, @@ -3075,7 +3070,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // We also need a new scope for the method- // specific type parameters. let type_parameters = - HasTypeParameters(&method.pe_sig().generics, + HasTypeParameters(&sig.generics, FnSpace, MethodRibKind); this.with_type_parameter_rib(type_parameters, |this| { @@ -3090,6 +3085,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { this.visit_ty(ty); } + ast::MacImplItem(_) => {} } } }); @@ -3953,19 +3949,18 @@ 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) { + let sig = match this.ast_map.get(did.node) { ast_map::NodeTraitItem(trait_item) => match trait_item.node { - ast::RequiredMethod(ref m) => &m.explicit_self, - ast::ProvidedMethod(ref m) => &m.pe_sig().explicit_self, + ast::MethodTraitItem(ref sig, _) => sig, _ => return false }, ast_map::NodeImplItem(impl_item) => match impl_item.node { - ast::MethodImplItem(ref m) => &m.pe_sig().explicit_self, + ast::MethodImplItem(ref sig, _) => sig, _ => return false }, _ => return false }; - explicit_self.node == ast::SelfStatic + sig.explicit_self.node == ast::SelfStatic } else { csearch::is_static_method(&this.session.cstore, did) } diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 2b1def22ed9ab..83bb5efb425d2 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -37,7 +37,7 @@ use std::env; use std::fs::{self, File}; use std::path::{Path, PathBuf}; -use syntax::ast_util::{self, PostExpansionMethod}; +use syntax::ast_util; use syntax::ast::{self, NodeId, DefId}; use syntax::ast_map::NodeItem; use syntax::attr; @@ -284,7 +284,8 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { } } - fn process_method(&mut self, method: &ast::Method, + fn process_method(&mut self, sig: &ast::MethodSig, + body: Option<&ast::Block>, id: ast::NodeId, ident: ast::Ident, span: Span) { if generated_code(span) { @@ -351,8 +352,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { }, }; - let qualname = format!("{}::{}", qualname, &get_ident(ident)); - let qualname = &qualname[..]; + let qualname = &format!("{}::{}", qualname, &get_ident(ident)); // record the decl for this def (if it has one) let decl_id = ty::trait_item_of_item(&self.analysis.ty_cx, @@ -364,39 +364,44 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { } ty::TypeTraitItemId(_) => false, } { - Some(def_id) + Some(def_id.def_id()) } else { None } }); - let decl_id = match decl_id { - None => None, - Some(id) => Some(id.def_id()), - }; let sub_span = self.span.sub_span_after_keyword(span, keywords::Fn); - self.fmt.method_str(span, - sub_span, - id, - qualname, - decl_id, - scope_id); - - self.process_formals(&method.pe_sig().decl.inputs, qualname); + if body.is_some() { + self.fmt.method_str(span, + sub_span, + id, + qualname, + decl_id, + scope_id); + self.process_formals(&sig.decl.inputs, qualname); + } else { + self.fmt.method_decl_str(span, + sub_span, + id, + qualname, + scope_id); + } // walk arg and return types - for arg in &method.pe_sig().decl.inputs { - self.visit_ty(&*arg.ty); + for arg in &sig.decl.inputs { + self.visit_ty(&arg.ty); } - if let ast::Return(ref ret_ty) = method.pe_sig().decl.output { - self.visit_ty(&**ret_ty); + if let ast::Return(ref ret_ty) = sig.decl.output { + self.visit_ty(ret_ty); } // walk the fn body - self.nest(id, |v| v.visit_block(&*method.pe_body())); + if let Some(body) = body { + self.nest(id, |v| v.visit_block(body)); + } - self.process_generic_params(&method.pe_sig().generics, + self.process_generic_params(&sig.generics, span, qualname, id); @@ -1226,51 +1231,9 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) { match trait_item.node { - ast::RequiredMethod(ref method_type) => { - 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(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(trait_item.span, - &format!("Could not find trait for method {}", - trait_item.id)); - }, - }; - - qualname.push_str(&get_ident(trait_item.ident)); - let qualname = &qualname[..]; - - let sub_span = self.span.sub_span_after_keyword(trait_item.span, keywords::Fn); - self.fmt.method_decl_str(trait_item.span, - sub_span, - trait_item.id, - qualname, - scope_id); - - // walk arg and return types - for arg in &method_type.decl.inputs { - self.visit_ty(&*arg.ty); - } - - if let ast::Return(ref ret_ty) = method_type.decl.output { - self.visit_ty(&**ret_ty); - } - - self.process_generic_params(&method_type.generics, - trait_item.span, - qualname, - trait_item.id); - } - ast::ProvidedMethod(ref method) => { - self.process_method(method, trait_item.id, trait_item.ident, trait_item.span); + ast::MethodTraitItem(ref sig, ref body) => { + self.process_method(sig, body.as_ref().map(|x| &**x), + trait_item.id, trait_item.ident, trait_item.span); } ast::TypeTraitItem(..) => {} } @@ -1278,10 +1241,12 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { 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::MethodImplItem(ref sig, ref body) => { + self.process_method(sig, Some(body), impl_item.id, + impl_item.ident, impl_item.span); } - ast::TypeImplItem(_) => {} + ast::TypeImplItem(_) | + ast::MacImplItem(_) => {} } } diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 9616bf8b64893..74326d4ea919c 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, PostExpansionMethod}; +use syntax::ast_util::local_def; use syntax::attr::AttrMetaMethods; use syntax::attr; use syntax::codemap::Span; @@ -1263,15 +1263,15 @@ 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_item)) => { match trait_item.node { - ast::ProvidedMethod(ref m) => m.pe_body(), - ast::RequiredMethod(_) => { + ast::MethodTraitItem(_, Some(ref body)) => body, + ast::MethodTraitItem(_, None) => { tcx.sess.bug("unexpected variant: required trait method \ in has_nested_returns") } @@ -1283,16 +1283,20 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option) } Some(ast_map::NodeImplItem(impl_item)) => { match impl_item.node { - ast::MethodImplItem(ref m) => m.pe_body(), + ast::MethodImplItem(_, ref body) => body, ast::TypeImplItem(_) => { tcx.sess.bug("unexpected variant: associated type impl item in \ has_nested_returns") } + ast::MacImplItem(_) => { + tcx.sess.bug("unexpected variant: unexpanded macro impl item in \ + has_nested_returns") + } } } 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") } } @@ -2805,11 +2809,11 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { ast_map::NodeTraitItem(trait_item) => { debug!("get_item_val(): processing a NodeTraitItem"); match trait_item.node { - ast::RequiredMethod(_) | ast::TypeTraitItem(..) => { + ast::MethodTraitItem(_, None) | ast::TypeTraitItem(..) => { ccx.sess().span_bug(trait_item.span, "unexpected variant: required trait method in get_item_val()"); } - ast::ProvidedMethod(_) => { + ast::MethodTraitItem(_, Some(_)) => { register_method(ccx, id, &trait_item.attrs, trait_item.span) } } @@ -2817,13 +2821,17 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { ast_map::NodeImplItem(impl_item) => { match impl_item.node { - ast::MethodImplItem(_) => { + 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()") } + ast::MacImplItem(_) => { + ccx.sess().span_bug(impl_item.span, + "unexpected variant: unexpanded macro in get_item_val()") + } } } diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 11495c7e6a37a..b5ab2c2825127 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -217,7 +217,6 @@ use std::rc::{Rc, Weak}; use syntax::util::interner::Interner; use syntax::codemap::{Span, Pos}; use syntax::{ast, codemap, ast_util, ast_map, attr}; -use syntax::ast_util::PostExpansionMethod; use syntax::parse::token::{self, special_idents}; const DW_LANG_RUST: c_uint = 0x9000; @@ -1292,7 +1291,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, match item.node { ast::ItemFn(ref fn_decl, _, _, ref generics, ref top_level_block) => { - (item.ident, fn_decl, generics, &**top_level_block, item.span, true) + (item.ident, fn_decl, generics, top_level_block, item.span, true) } _ => { cx.sess().span_bug(item.span, @@ -1302,15 +1301,15 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } ast_map::NodeImplItem(impl_item) => { match impl_item.node { - ast::MethodImplItem(ref method) => { + ast::MethodImplItem(ref sig, ref body) => { if contains_nodebug_attribute(&impl_item.attrs) { return FunctionDebugContext::FunctionWithoutDebugInfo; } (impl_item.ident, - &method.pe_sig().decl, - &method.pe_sig().generics, - method.pe_body(), + &sig.decl, + &sig.generics, + body, impl_item.span, true) } @@ -1319,6 +1318,11 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, "create_function_debug_context() \ called on associated type?!") } + ast::MacImplItem(_) => { + cx.sess().span_bug(impl_item.span, + "create_function_debug_context() \ + called on unexpanded macro?!") + } } } ast_map::NodeExpr(ref expr) => { @@ -1330,7 +1334,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // This is not quite right. It should actually inherit // the generics of the enclosing function. &empty_generics, - &**top_level_block, + top_level_block, expr.span, // Don't try to lookup the item path: false) @@ -1341,15 +1345,15 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } ast_map::NodeTraitItem(trait_item) => { match trait_item.node { - ast::ProvidedMethod(ref method) => { + ast::MethodTraitItem(ref sig, Some(ref body)) => { if contains_nodebug_attribute(&trait_item.attrs) { return FunctionDebugContext::FunctionWithoutDebugInfo; } (trait_item.ident, - &method.pe_sig().decl, - &method.pe_sig().generics, - method.pe_body(), + &sig.decl, + &sig.generics, + body, trait_item.span, true) } diff --git a/src/librustc_trans/trans/inline.rs b/src/librustc_trans/trans/inline.rs index eacc40edcc662..2034c6223c134 100644 --- a/src/librustc_trans/trans/inline.rs +++ b/src/librustc_trans/trans/inline.rs @@ -17,7 +17,7 @@ use trans::common::*; use middle::ty; use syntax::ast; -use syntax::ast_util::{local_def, PostExpansionMethod}; +use syntax::ast_util::local_def; fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) -> Option { @@ -146,19 +146,19 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1); // Translate monomorphic impl methods immediately. - if let ast::MethodImplItem(ref mth) = impl_item.node { + if let ast::MethodImplItem(ref sig, ref body) = impl_item.node { let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did); if impl_tpt.generics.types.is_empty() && - mth.pe_sig().generics.ty_params.is_empty() { + sig.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_sig().decl, - &*mth.pe_body(), - llfn, - empty_substs, - impl_item.id, - &[]); + &sig.decl, + body, + llfn, + empty_substs, + impl_item.id, + &[]); // Use InternalLinkage so LLVM can optimize more aggressively. SetLinkage(llfn, InternalLinkage); } diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index 8df086fd232a5..ba3798d7d8028 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -41,7 +41,6 @@ use std::rc::Rc; use syntax::abi::{Rust, RustCall}; use syntax::parse::token; use syntax::{ast, ast_map, attr, visit}; -use syntax::ast_util::PostExpansionMethod; use syntax::codemap::DUMMY_SP; use syntax::ptr::P; @@ -69,29 +68,25 @@ pub fn trans_impl(ccx: &CrateContext, if !generics.ty_params.is_empty() { for impl_item in impl_items { match impl_item.node { - ast::MethodImplItem(_) => { + ast::MethodImplItem(..) => { visit::walk_impl_item(&mut v, impl_item); } - ast::TypeImplItem(_) => {} + ast::TypeImplItem(_) | + ast::MacImplItem(_) => {} } } return; } for impl_item in impl_items { match impl_item.node { - ast::MethodImplItem(ref method) => { - if method.pe_sig().generics.ty_params.len() == 0 { + ast::MethodImplItem(ref sig, ref body) => { + if sig.generics.ty_params.len() == 0 { 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, impl_item.id); let empty_substs = tcx.mk_substs(Substs::trans_empty()); - trans_fn(ccx, - &method.pe_sig().decl, - method.pe_body(), - llfn, - empty_substs, - impl_item.id, - &[]); + trans_fn(ccx, &sig.decl, body, llfn, + empty_substs, impl_item.id, &[]); update_linkage(ccx, llfn, Some(impl_item.id), @@ -100,7 +95,8 @@ pub fn trans_impl(ccx: &CrateContext, } visit::walk_impl_item(&mut v, impl_item); } - ast::TypeImplItem(_) => {} + ast::TypeImplItem(_) | + ast::MacImplItem(_) => {} } } } diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index 80271a72c6859..2083e737f89b1 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -29,7 +29,7 @@ use util::ppaux::Repr; use syntax::abi; use syntax::ast; use syntax::ast_map; -use syntax::ast_util::{local_def, PostExpansionMethod}; +use syntax::ast_util::local_def; use syntax::attr; use syntax::codemap::DUMMY_SP; use std::hash::{Hasher, Hash, SipHasher}; @@ -218,13 +218,13 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } ast_map::NodeImplItem(impl_item) => { match impl_item.node { - ast::MethodImplItem(ref mth) => { + ast::MethodImplItem(ref sig, ref body) => { let d = mk_lldecl(abi::Rust); let needs_body = setup_lldecl(d, &impl_item.attrs); if needs_body { trans_fn(ccx, - &mth.pe_sig().decl, - mth.pe_body(), + &sig.decl, + body, d, psubsts, impl_item.id, @@ -235,15 +235,18 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ast::TypeImplItem(_) => { ccx.sess().bug("can't monomorphize an associated type") } + ast::MacImplItem(_) => { + ccx.sess().bug("can't monomorphize an unexpanded macro") + } } } ast_map::NodeTraitItem(trait_item) => { match trait_item.node { - ast::ProvidedMethod(ref mth) => { + ast::MethodTraitItem(ref sig, Some(ref body)) => { let d = mk_lldecl(abi::Rust); let needs_body = setup_lldecl(d, &trait_item.attrs); if needs_body { - trans_fn(ccx, &mth.pe_sig().decl, mth.pe_body(), d, + trans_fn(ccx, &sig.decl, body, d, psubsts, trait_item.id, &[]); } d diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 470e1d54c7f77..41951ab2b6200 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -119,8 +119,8 @@ use std::iter::repeat; use std::slice; use syntax::{self, abi, attr}; use syntax::attr::AttrMetaMethods; -use syntax::ast::{self, ProvidedMethod, RequiredMethod, TypeTraitItem, DefId, Visibility}; -use syntax::ast_util::{self, local_def, PostExpansionMethod}; +use syntax::ast::{self, DefId, Visibility}; +use syntax::ast_util::{self, local_def}; use syntax::codemap::{self, Span}; use syntax::owned_slice::OwnedSlice; use syntax::parse::token; @@ -740,11 +740,12 @@ pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) { for impl_item in impl_items { match impl_item.node { - ast::MethodImplItem(ref m) => { - check_method_body(ccx, &impl_pty.generics, m, + ast::MethodImplItem(ref sig, ref body) => { + check_method_body(ccx, &impl_pty.generics, sig, body, impl_item.id, impl_item.span); } - ast::TypeImplItem(_) => { + ast::TypeImplItem(_) | + ast::MacImplItem(_) => { // Nothing to do here. } } @@ -756,15 +757,15 @@ pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) { let trait_def = ty::lookup_trait_def(ccx.tcx, local_def(it.id)); for trait_item in trait_items { match trait_item.node { - RequiredMethod(..) => { + ast::MethodTraitItem(_, None) => { // Nothing to do, since required methods don't have // bodies to check. } - ProvidedMethod(ref m) => { - check_method_body(ccx, &trait_def.generics, m, + ast::MethodTraitItem(ref sig, Some(ref body)) => { + check_method_body(ccx, &trait_def.generics, sig, body, trait_item.id, trait_item.span); } - TypeTraitItem(..) => { + ast::TypeTraitItem(..) => { // Nothing to do. } } @@ -857,7 +858,8 @@ 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, + sig: &'tcx ast::MethodSig, + body: &'tcx ast::Block, id: ast::NodeId, span: Span) { debug!("check_method_body(item_generics={}, id={})", item_generics.repr(ccx.tcx), id); @@ -866,13 +868,7 @@ fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, 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_sig().decl, - &*method.pe_body(), - id, - span, - fty, - param_env); + check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env); } fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, @@ -887,7 +883,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // and compatible with trait signature for impl_item in impl_items { match impl_item.node { - ast::MethodImplItem(ref impl_method) => { + ast::MethodImplItem(_, ref body) => { 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); @@ -905,7 +901,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, compare_impl_method(ccx.tcx, &**impl_method_ty, impl_item.span, - impl_method.pe_body().id, + body.id, &**trait_method_ty, &*impl_trait_ref); } @@ -969,6 +965,8 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } } } + ast::MacImplItem(_) => tcx.sess.span_bug(impl_item.span, + "unexpanded macro") } } @@ -981,10 +979,11 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let is_implemented = impl_items.iter().any(|ii| { match ii.node { - ast::MethodImplItem(_) => { + ast::MethodImplItem(..) => { ii.ident.name == trait_method.name } - ast::TypeImplItem(_) => false, + ast::TypeImplItem(_) | + ast::MacImplItem(_) => false, } }); let is_provided = @@ -999,7 +998,8 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ast::TypeImplItem(_) => { ii.ident.name == associated_type.name } - ast::MethodImplItem(_) => false, + ast::MethodImplItem(..) | + ast::MacImplItem(_) => false, } }); if !is_implemented { diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index 0e50938abc447..adbf4c6b210e8 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -499,7 +499,7 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> { } fn visit_trait_item(&mut self, trait_item: &'v ast::TraitItem) { - if let ast::RequiredMethod(_) = trait_item.node { + if let ast::MethodTraitItem(_, None) = 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( diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index a4eab5b7a2650..6b0fb8ac71af0 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -279,12 +279,16 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { let mut items: Vec = impl_items.iter().map(|impl_item| { match impl_item.node { - ast::MethodImplItem(_) => { + ast::MethodImplItem(..) => { MethodTraitItemId(local_def(impl_item.id)) } ast::TypeImplItem(_) => { TypeTraitItemId(local_def(impl_item.id)) } + ast::MacImplItem(_) => { + self.crate_context.tcx.sess.span_bug(impl_item.span, + "unexpanded macro"); + } } }).collect(); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index a2ca228b11a94..2372680576797 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -89,7 +89,7 @@ use std::rc::Rc; use syntax::abi; use syntax::ast; use syntax::ast_map; -use syntax::ast_util::{local_def, PostExpansionMethod}; +use syntax::ast_util::local_def; use syntax::codemap::Span; use syntax::parse::token::{special_idents}; use syntax::parse::token; @@ -847,7 +847,6 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { // Convert all the associated types. for impl_item in impl_items { match impl_item.node { - ast::MethodImplItem(_) => {} ast::TypeImplItem(ref ty) => { if opt_trait_ref.is_none() { span_err!(tcx.sess, impl_item.span, E0202, @@ -867,20 +866,23 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { ty::GenericPredicates::empty()); write_ty_to_tcx(tcx, impl_item.id, typ); } + ast::MethodImplItem(..) | + ast::MacImplItem(_) => {} } } let methods = impl_items.iter().filter_map(|ii| { match ii.node { - ast::MethodImplItem(ref m) => { + ast::MethodImplItem(ref sig, _) => { // if the method specifies a visibility, use that, otherwise // 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 = ii.vis.inherit_from(parent_visibility); - Some((m.pe_sig(), ii.id, ii.ident, method_vis, ii.span)) + Some((sig, ii.id, ii.ident, method_vis, ii.span)) } - ast::TypeImplItem(_) => None + ast::TypeImplItem(_) | + ast::MacImplItem(_) => None } }); convert_methods(ccx, @@ -892,16 +894,17 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { for impl_item in impl_items { match impl_item.node { - ast::MethodImplItem(ref method) => { - let body_id = method.pe_body().id; + ast::MethodImplItem(ref sig, ref body) => { + let body_id = body.id; check_method_self_type(ccx, &BindingRscope::new(), ccx.method_ty(impl_item.id), selfty, - &method.pe_sig().explicit_self, + &sig.explicit_self, body_id); } - ast::TypeImplItem(_) => {} + ast::TypeImplItem(_) | + ast::MacImplItem(_) => {} } } @@ -930,8 +933,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { // Convert all the associated types. for trait_item in trait_items { match trait_item.node { - ast::RequiredMethod(_) | - ast::ProvidedMethod(_) => {} + ast::MethodTraitItem(..) => {} ast::TypeTraitItem(..) => { convert_associated_type(ccx, TraitContainer(local_def(it.id)), trait_item.ident, trait_item.id, ast::Public); @@ -941,8 +943,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { let methods = trait_items.iter().filter_map(|ti| { let sig = match ti.node { - ast::RequiredMethod(ref sig) => sig, - ast::ProvidedMethod(ref m) => m.pe_sig(), + ast::MethodTraitItem(ref sig, _) => sig, ast::TypeTraitItem(..) => return None, }; Some((sig, ti.id, ti.ident, ast::Inherited, ti.span)) @@ -960,8 +961,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { 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(_) => { + ast::MethodTraitItem(..) => { ty::MethodTraitItemId(def_id) } ast::TypeTraitItem(..) => { @@ -975,8 +975,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { // we have a method type stored for every method. for trait_item in trait_items { let sig = match trait_item.node { - ast::RequiredMethod(ref sig) => sig, - ast::ProvidedMethod(ref method) => method.pe_sig(), + ast::MethodTraitItem(ref sig, _) => sig, ast::TypeTraitItem(..) => continue }; check_method_self_type(ccx, @@ -1196,7 +1195,7 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| { match trait_item.node { - ast::RequiredMethod(_) | ast::ProvidedMethod(_) => None, + ast::MethodTraitItem(..) => None, ast::TypeTraitItem(..) => Some(trait_item.ident.name), } }).collect(); @@ -1269,7 +1268,7 @@ fn trait_defines_associated_type_named(ccx: &CrateCtxt, trait_items.iter().any(|trait_item| { match trait_item.node { ast::TypeTraitItem(..) => trait_item.ident.name == assoc_name, - ast::RequiredMethod(_) | ast::ProvidedMethod(_) => false, + ast::MethodTraitItem(..) => false, } }) } @@ -1329,7 +1328,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item) trait_items.iter().flat_map(|trait_item| { let bounds = match trait_item.node { ast::TypeTraitItem(ref bounds, _) => bounds, - ast::RequiredMethod(..) | ast::ProvidedMethod(..) => { + ast::MethodTraitItem(..) => { return vec!().into_iter(); } }; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 05139bf1eab91..e91e95961c521 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -28,7 +28,6 @@ use syntax; use syntax::abi; use syntax::ast; use syntax::ast_util; -use syntax::ast_util::PostExpansionMethod; use syntax::attr; use syntax::attr::{AttributeMethods, AttrMetaMethods}; use syntax::codemap; @@ -949,10 +948,10 @@ pub struct Method { pub abi: abi::Abi } -impl Clean for ast::Method { +impl Clean for ast::MethodSig { fn clean(&self, cx: &DocContext) -> Method { - let all_inputs = &self.pe_sig().decl.inputs; - let inputs = match self.pe_sig().explicit_self.node { + let all_inputs = &self.decl.inputs; + let inputs = match self.explicit_self.node { ast::SelfStatic => &**all_inputs, _ => &all_inputs[1..] }; @@ -960,15 +959,15 @@ impl Clean for ast::Method { inputs: Arguments { values: inputs.clean(cx), }, - output: self.pe_sig().decl.output.clean(cx), + output: self.decl.output.clean(cx), attrs: Vec::new() }; Method { - generics: self.pe_sig().generics.clean(cx), - self_: self.pe_sig().explicit_self.node.clean(cx), - unsafety: self.pe_sig().unsafety.clone(), + generics: self.generics.clean(cx), + self_: self.explicit_self.node.clean(cx), + unsafety: self.unsafety.clone(), decl: decl, - abi: self.pe_sig().abi + abi: self.abi } } } @@ -1190,8 +1189,12 @@ impl Clean for ast::PolyTraitRef { 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::MethodTraitItem(ref sig, Some(_)) => { + MethodItem(sig.clean(cx)) + } + ast::MethodTraitItem(ref sig, None) => { + TyMethodItem(sig.clean(cx)) + } ast::TypeTraitItem(ref bounds, ref default) => { AssociatedTypeItem(bounds.clean(cx), default.clean(cx)) } @@ -1211,7 +1214,9 @@ impl Clean for ast::TraitItem { 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::MethodImplItem(ref sig, _) => { + MethodItem(sig.clean(cx)) + } ast::TypeImplItem(ref ty) => TypedefItem(Typedef { type_: ty.clean(cx), generics: Generics { @@ -1220,6 +1225,11 @@ impl Clean for ast::ImplItem { where_predicates: Vec::new() }, }), + ast::MacImplItem(_) => { + MacroItem(Macro { + source: self.span.to_src(cx), + }) + } }; Item { name: Some(self.ident.clean(cx)), diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 0a08b0b12072f..657ffcaece9f8 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -33,7 +33,6 @@ pub use self::LocalSource::*; pub use self::Mac_::*; pub use self::MacStmtStyle::*; pub use self::MetaItem_::*; -pub use self::Method::*; pub use self::Mutability::*; pub use self::Pat_::*; pub use self::PathListItem_::*; @@ -1084,8 +1083,7 @@ pub struct TraitItem { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum TraitItem_ { - RequiredMethod(MethodSig), - ProvidedMethod(Method), + MethodTraitItem(MethodSig, Option>), TypeTraitItem(TyParamBounds, Option>), } @@ -1101,8 +1099,9 @@ pub struct ImplItem { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum ImplItem_ { - MethodImplItem(Method), + MethodImplItem(MethodSig, P), TypeImplItem(P), + MacImplItem(Mac), } #[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Copy)] @@ -1416,14 +1415,6 @@ pub enum ExplicitSelf_ { pub type ExplicitSelf = Spanned; -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum Method { - /// Represents a method declaration - MethDecl(MethodSig, P), - /// Represents a macro in method position - MethMac(Mac), -} - #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct Mod { /// A span from the first token past `{` to the last token until `}`. diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs index 345ccf902cd8a..16a339cdcb530 100644 --- a/src/libsyntax/ast_map/blocks.rs +++ b/src/libsyntax/ast_map/blocks.rs @@ -28,7 +28,6 @@ use ast::{Block, FnDecl, NodeId}; use ast; use ast_map::{Node}; use ast_map; -use ast_util::PostExpansionMethod; use codemap::Span; use visit; @@ -65,7 +64,7 @@ impl MaybeFnLike for ast::Item { impl MaybeFnLike for ast::TraitItem { fn is_fn_like(&self) -> bool { - match self.node { ast::ProvidedMethod(_) => true, _ => false, } + match self.node { ast::MethodTraitItem(_, Some(_)) => true, _ => false, } } } @@ -156,25 +155,25 @@ impl<'a> FnLikeNode<'a> { pub fn body(self) -> &'a Block { self.handle(|i: ItemFnParts<'a>| &*i.body, - |_, _, m: &'a ast::Method, _| m.pe_body(), + |_, _, _: &'a ast::MethodSig, body: &'a ast::Block, _| body, |c: ClosureParts<'a>| c.body) } pub fn decl(self) -> &'a FnDecl { self.handle(|i: ItemFnParts<'a>| &*i.decl, - |_, _, m: &'a ast::Method, _| &m.pe_sig().decl, + |_, _, sig: &'a ast::MethodSig, _, _| &sig.decl, |c: ClosureParts<'a>| c.decl) } pub fn span(self) -> Span { self.handle(|i: ItemFnParts| i.span, - |_, _, _: &'a ast::Method, span| span, + |_, _, _: &'a ast::MethodSig, _, span| span, |c: ClosureParts| c.span) } pub fn id(self) -> NodeId { self.handle(|i: ItemFnParts| i.id, - |id, _, _: &'a ast::Method, _| id, + |id, _, _: &'a ast::MethodSig, _, _| id, |c: ClosureParts| c.id) } @@ -185,15 +184,15 @@ impl<'a> FnLikeNode<'a> { let closure = |_: ClosureParts| { visit::FkFnBlock }; - let method = |_, ident, m: &'a ast::Method, _| { - visit::FkMethod(ident, m) + let method = |_, ident, sig: &'a ast::MethodSig, _, _| { + visit::FkMethod(ident, sig) }; self.handle(item, method, closure) } fn handle(self, item_fn: I, method: M, closure: C) -> A where I: FnOnce(ItemFnParts<'a>) -> A, - M: FnOnce(NodeId, ast::Ident, &'a ast::Method, Span) -> A, + M: FnOnce(NodeId, ast::Ident, &'a ast::MethodSig, &'a ast::Block, Span) -> A, C: FnOnce(ClosureParts<'a>) -> A, { match self.node { @@ -206,13 +205,18 @@ impl<'a> FnLikeNode<'a> { _ => panic!("item FnLikeNode that is not fn-like"), }, ast_map::NodeTraitItem(ti) => match ti.node { - ast::ProvidedMethod(ref m) => method(ti.id, ti.ident, m, ti.span), + ast::MethodTraitItem(ref sig, Some(ref body)) => { + method(ti.id, ti.ident, sig, body, ti.span) + } _ => panic!("trait method FnLikeNode that is not fn-like"), }, ast_map::NodeImplItem(ii) => { match ii.node { - ast::MethodImplItem(ref m) => method(ii.id, ii.ident, m, ii.span), - ast::TypeImplItem(_) => { + ast::MethodImplItem(ref sig, ref body) => { + method(ii.id, ii.ident, sig, body, ii.span) + } + ast::TypeImplItem(_) | + ast::MacImplItem(_) => { panic!("impl method FnLikeNode that is not fn-like") } } diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index 606c6b640df2e..48bb044cb1854 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -929,16 +929,10 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { } Some(NodeImplItem(ii)) => { match ii.node { - MethodImplItem(ref m) => { - match *m { - MethDecl(..) => - format!("method {} in {}{}", - token::get_ident(ii.ident), - map.path_to_string(id), id_str), - MethMac(ref mac) => - format!("method macro {}{}", - pprust::mac_to_string(mac), id_str) - } + MethodImplItem(..) => { + format!("method {} in {}{}", + token::get_ident(ii.ident), + map.path_to_string(id), id_str) } TypeImplItem(_) => { format!("assoc type {} in {}{}", @@ -946,13 +940,17 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { map.path_to_string(id), id_str) } + MacImplItem(ref mac) => { + format!("method macro {}{}", + pprust::mac_to_string(mac), id_str) + } } } Some(NodeTraitItem(ti)) => { let kind = match ti.node { - RequiredMethod(_) => "required method", - ProvidedMethod(_) => "provided method", + MethodTraitItem(..) => "trait method", TypeTraitItem(..) => "assoc type", +// ConstTraitItem(..) => "assoc constant" }; format!("{} {} in {}{}", diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 91ddc8beec81c..cec824e79ff5a 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -459,8 +459,8 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { visit::FkItemFn(_, generics, _, _) => { self.visit_generics_helper(generics) } - visit::FkMethod(_, m) => { - self.visit_generics_helper(&m.pe_sig().generics) + visit::FkMethod(_, sig) => { + self.visit_generics_helper(&sig.generics) } visit::FkFnBlock => {} } @@ -647,34 +647,6 @@ pub fn lit_is_str(lit: &Lit) -> bool { } } -/// Macro invocations are guaranteed not to occur after expansion is complete. -/// Extracting fields of a method requires a dynamic check to make sure that it's -/// not a macro invocation. This check is guaranteed to succeed, assuming -/// that the invocations are indeed gone. -pub trait PostExpansionMethod { - fn pe_sig<'a>(&'a self) -> &'a ast::MethodSig; - fn pe_body<'a>(&'a self) -> &'a ast::Block; -} - -macro_rules! mf_method{ - ($meth_name:ident, $field_ty:ty, $field_pat:pat, $result:expr) => { - fn $meth_name<'a>(&'a self) -> $field_ty { - match *self { - $field_pat => $result, - MethMac(_) => { - panic!("expected an AST without macro invocations"); - } - } - } - } -} - - -impl PostExpansionMethod for Method { - mf_method! { pe_sig, &'a ast::MethodSig,MethDecl(ref sig, _), sig } - mf_method! { pe_body, &'a ast::Block,MethDecl(_, ref body), body } -} - #[cfg(test)] mod test { use ast::*; diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index cad5f97a4a5bb..35449bde0b2e0 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -228,8 +228,8 @@ pub trait MacResult { None } - /// Create zero or more methods. - fn make_methods(self: Box) -> Option>> { + /// Create zero or more impl items. + fn make_impl_items(self: Box) -> Option>> { None } @@ -275,7 +275,7 @@ make_MacEager! { expr: P, pat: P, items: SmallVector>, - methods: SmallVector>, + impl_items: SmallVector>, stmt: P, } @@ -288,8 +288,8 @@ impl MacResult for MacEager { self.items } - fn make_methods(self: Box) -> Option>> { - self.methods + fn make_impl_items(self: Box) -> Option>> { + self.impl_items } fn make_stmt(self: Box) -> Option> { @@ -377,7 +377,7 @@ impl MacResult for DummyResult { Some(SmallVector::zero()) } } - fn make_methods(self: Box) -> Option>> { + fn make_impl_items(self: Box) -> Option>> { if self.expr_only { None } else { diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index d4b0f7d1dcb85..58b6d96607df7 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -724,13 +724,13 @@ impl<'a> MethodDef<'a> { span: trait_.span, vis: ast::Inherited, ident: method_ident, - node: ast::MethodImplItem(ast::MethDecl(ast::MethodSig { + node: ast::MethodImplItem(ast::MethodSig { generics: fn_generics, abi: abi, explicit_self: explicit_self, unsafety: ast::Unsafety::Normal, decl: fn_decl - }, body_block)) + }, body_block) }) } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index fa0b747f45b99..830248b5682f3 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -25,7 +25,6 @@ use ext::base::*; use feature_gate::{self, Features}; use fold; use fold::*; -use owned_slice::OwnedSlice; use parse; use parse::token::{fresh_mark, fresh_name, intern}; use parse::token; @@ -1175,42 +1174,26 @@ fn expand_annotatable(a: Annotatable, noop_fold_item(it, fld).into_iter().map(|i| Annotatable::Item(i)).collect() } }, + Annotatable::TraitItem(it) => match it.node { - ast::ProvidedMethod(ast::MethMac(_)) => { - // HACK(eddyb): Expand method macros in a trait as if they were in an impl. - let ii = it.and_then(|ti| match ti.node { - ast::ProvidedMethod(m) => P(ast::ImplItem { - id: ti.id, - ident: ti.ident, - attrs: ti.attrs, - vis: ast::Inherited, - node: ast::MethodImplItem(m), - span: ti.span - }), + ast::MethodTraitItem(_, Some(_)) => SmallVector::one(it.map(|ti| ast::TraitItem { + id: ti.id, + ident: ti.ident, + attrs: ti.attrs, + node: match ti.node { + ast::MethodTraitItem(sig, Some(body)) => { + let (sig, body) = expand_and_rename_method(sig, body, fld); + ast::MethodTraitItem(sig, Some(body)) + } _ => unreachable!() - }); - expand_method(ii, fld).into_iter().map(|ii| { - Annotatable::TraitItem(ii.and_then(|ii| P(ast::TraitItem { - id: ii.id, - ident: ii.ident, - attrs: ii.attrs, - node: match ii.node { - ast::MethodImplItem(m) => ast::ProvidedMethod(m), - ast::TypeImplItem(ty) => { - ast::TypeTraitItem(OwnedSlice::empty(), Some(ty)) - } - }, - span: ii.span - }))) - }).collect() - } - _ => { - fold::noop_fold_trait_item(it, fld).into_iter() - .map(|ti| Annotatable::TraitItem(ti)).collect() - } - }, + }, + span: fld.new_span(ti.span) + })), + _ => fold::noop_fold_trait_item(it, fld) + }.into_iter().map(Annotatable::TraitItem).collect(), + Annotatable::ImplItem(ii) => { - expand_method(ii, fld).into_iter().map(Annotatable::ImplItem).collect() + expand_impl_item(ii, fld).into_iter().map(Annotatable::ImplItem).collect() } }; @@ -1291,35 +1274,47 @@ fn expand_item_multi_modifier(mut it: Annotatable, expand_item_multi_modifier(it, fld) } -// expand an impl item if it's a method macro -fn expand_method(ii: P, fld: &mut MacroExpander) +fn expand_impl_item(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(_)) => { + ast::MethodImplItem(..) => SmallVector::one(ii.map(|ii| ast::ImplItem { + id: ii.id, + ident: ii.ident, + attrs: ii.attrs, + vis: ii.vis, + node: match ii.node { + ast::MethodImplItem(sig, body) => { + let (sig, body) = expand_and_rename_method(sig, body, fld); + ast::MethodImplItem(sig, body) + } + _ => unreachable!() + }, + span: fld.new_span(ii.span) + })), + ast::MacImplItem(_) => { let (span, mac) = ii.and_then(|ii| match ii.node { - ast::MethodImplItem(ast::MethMac(mac)) => (ii.span, mac), + ast::MacImplItem(mac) => (ii.span, mac), _ => unreachable!() }); - let maybe_new_methods = + let maybe_new_items = expand_mac_invoc(mac, span, - |r| r.make_methods(), - |meths, mark| meths.move_map(|m| mark_method(m, mark)), + |r| r.make_impl_items(), + |meths, mark| meths.move_map(|m| mark_impl_item(m, mark)), fld); - match maybe_new_methods { - Some(methods) => { + match maybe_new_items { + Some(impl_items) => { // expand again if necessary - let new_methods = methods.into_iter() - .flat_map(|m| expand_method(m, fld).into_iter()) - .collect(); + let new_items = impl_items.into_iter().flat_map(|ii| { + expand_impl_item(ii, fld).into_iter() + }).collect(); fld.cx.bt_pop(); - new_methods + new_items } None => SmallVector::zero() } } - _ => SmallVector::one(ii) + _ => fold::noop_fold_impl_item(ii, fld) } } @@ -1328,7 +1323,7 @@ fn expand_method(ii: P, fld: &mut MacroExpander) /// the block, returning both the new FnDecl and the new Block. fn expand_and_rename_fn_decl_and_block(fn_decl: P, block: P, fld: &mut MacroExpander) - -> (P, P) { + -> (P, P) { let expanded_decl = fld.fold_fn_decl(fn_decl); let idents = fn_decl_arg_bindings(&*expanded_decl); let renames = @@ -1342,6 +1337,20 @@ fn expand_and_rename_fn_decl_and_block(fn_decl: P, block: P, + fld: &mut MacroExpander) + -> (ast::MethodSig, P) { + let (rewritten_fn_decl, rewritten_body) + = expand_and_rename_fn_decl_and_block(sig.decl, body, fld); + (ast::MethodSig { + generics: fld.fold_generics(sig.generics), + abi: sig.abi, + explicit_self: fld.fold_explicit_self(sig.explicit_self), + unsafety: sig.unsafety, + decl: rewritten_fn_decl + }, rewritten_body) +} + /// A tree-folder that performs macro expansion pub struct MacroExpander<'a, 'b:'a> { pub cx: &'a mut ExtCtxt<'b>, @@ -1391,23 +1400,6 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { expand_arm(arm, self) } - fn fold_method(&mut self, m: ast::Method) -> ast::Method { - match m { - ast::MethDecl(sig, body) => { - let (rewritten_fn_decl, rewritten_body) - = expand_and_rename_fn_decl_and_block(sig.decl, body, self); - ast::MethDecl(ast::MethodSig { - generics: self.fold_generics(sig.generics), - abi: sig.abi, - explicit_self: self.fold_explicit_self(sig.explicit_self), - unsafety: sig.unsafety, - decl: rewritten_fn_decl - }, rewritten_body) - } - ast::MethMac(mac) => ast::MethMac(mac) - } - } - fn fold_trait_item(&mut self, i: P) -> SmallVector> { expand_annotatable(Annotatable::TraitItem(i), self) .into_iter().map(|i| i.expect_trait_item()).collect() @@ -1561,9 +1553,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(ii: P, m: Mrk) -> P { +fn mark_impl_item(ii: P, m: Mrk) -> P { Marker{mark:m}.fold_impl_item(ii) - .expect_one("marking an impl item didn't return exactly one method") + .expect_one("marking an impl item didn't return exactly one impl item") } /// Check that there are no macro invocations left in the AST: diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index dad50af9a9192..7575d4b5ecdbe 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -71,7 +71,7 @@ impl<'a> MacResult for ParserAnyMacro<'a> { loop { let mut parser = self.parser.borrow_mut(); // so... do outer attributes attached to the macro invocation - // just disappear? This question applies to make_methods, as + // just disappear? This question applies to make_impl_items, as // well. match parser.parse_item_with_outer_attributes() { Some(item) => ret.push(item), @@ -82,16 +82,14 @@ impl<'a> MacResult for ParserAnyMacro<'a> { Some(ret) } - fn make_methods(self: Box>) - -> Option>> { + fn make_impl_items(self: Box>) + -> Option>> { let mut ret = SmallVector::zero(); loop { let mut parser = self.parser.borrow_mut(); match parser.token { token::Eof => break, - _ => { - ret.push(parser.parse_method_with_outer_attributes()); - } + _ => ret.push(parser.parse_impl_item_with_outer_attributes()) } } self.ensure_complete_parse(false); diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index d7982ef839969..105a61d085725 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -110,10 +110,6 @@ pub trait Folder : Sized { noop_fold_fn_decl(d, self) } - fn fold_method(&mut self, m: Method) -> Method { - noop_fold_method(m, self) - } - fn fold_block(&mut self, b: P) -> P { noop_fold_block(b, self) } @@ -977,8 +973,10 @@ pub fn noop_fold_trait_item(i: P, folder: &mut T) ident: folder.fold_ident(ident), attrs: fold_attrs(attrs, folder), node: match node { - RequiredMethod(sig) => RequiredMethod(noop_fold_method_sig(sig, folder)), - ProvidedMethod(m) => ProvidedMethod(folder.fold_method(m)), + MethodTraitItem(sig, body) => { + MethodTraitItem(noop_fold_method_sig(sig, folder), + body.map(|x| folder.fold_block(x))) + } TypeTraitItem(bounds, default) => { TypeTraitItem(folder.fold_bounds(bounds), default.map(|x| folder.fold_ty(x))) @@ -996,8 +994,12 @@ pub fn noop_fold_impl_item(i: P, folder: &mut T) attrs: fold_attrs(attrs, folder), vis: vis, node: match node { - MethodImplItem(m) => MethodImplItem(folder.fold_method(m)), - TypeImplItem(ty) => TypeImplItem(folder.fold_ty(ty)) + MethodImplItem(sig, body) => { + MethodImplItem(noop_fold_method_sig(sig, folder), + folder.fold_block(body)) + } + TypeImplItem(ty) => TypeImplItem(folder.fold_ty(ty)), + MacImplItem(mac) => MacImplItem(folder.fold_mac(mac)) }, span: folder.new_span(span) })) @@ -1099,17 +1101,6 @@ pub fn noop_fold_foreign_item(ni: P, folder: &mut T) -> }) } -// Default fold over a method. -pub fn noop_fold_method(method: Method, folder: &mut T) -> Method { - match method { - MethDecl(sig, body) => { - MethDecl(noop_fold_method_sig(sig, folder), - folder.fold_block(body)) - }, - MethMac(mac) => MethMac(folder.fold_mac(mac)) - } -} - pub fn noop_fold_method_sig(sig: MethodSig, folder: &mut T) -> MethodSig { MethodSig { generics: folder.fold_generics(sig.generics), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2e77bd6df1886..9f851e5de1948 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -13,7 +13,7 @@ pub use self::PathParsingMode::*; use abi; use ast::{BareFnTy}; use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; -use ast::{ProvidedMethod, Public, Unsafety}; +use ast::{Public, Unsafety}; use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue}; use ast::{BiBitAnd, BiBitOr, BiBitXor, BiRem, BiLt, BiGt, Block}; use ast::{BlockCheckMode, CaptureByRef, CaptureByValue, CaptureClause}; @@ -42,8 +42,7 @@ use ast::{MutTy, BiMul, Mutability}; use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, NodeId, UnNot}; use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct}; use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle}; -use ast::{PolyTraitRef}; -use ast::{QSelf, RequiredMethod}; +use ast::{PolyTraitRef, QSelf}; use ast::{Return, BiShl, BiShr, Stmt, StmtDecl}; use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField}; use ast::{StructVariantKind, BiSub, StrStyle}; @@ -1349,18 +1348,18 @@ impl<'a> Parser<'a> { }; let hi = p.last_span.hi; - let node = match p.token { + let body = match p.token { token::Semi => { p.bump(); debug!("parse_trait_methods(): parsing required method"); - RequiredMethod(sig) + None } token::OpenDelim(token::Brace) => { debug!("parse_trait_methods(): parsing provided method"); let (inner_attrs, body) = p.parse_inner_attrs_and_block(); attrs.push_all(&inner_attrs[..]); - ProvidedMethod(ast::MethDecl(sig, body)) + Some(body) } _ => { @@ -1374,7 +1373,7 @@ impl<'a> Parser<'a> { id: ast::DUMMY_NODE_ID, ident: ident, attrs: attrs, - node: node, + node: ast::MethodTraitItem(sig, body), span: mk_sp(lo, hi), }) } @@ -4682,11 +4681,15 @@ impl<'a> Parser<'a> { (ident, ItemFn(decl, unsafety, abi, generics, body), Some(inner_attrs)) } - /// Parse a method in a trait impl - pub fn parse_method_with_outer_attributes(&mut self) -> P { + /// Parse an impl item. + pub fn parse_impl_item_with_outer_attributes(&mut self) -> P { let attrs = self.parse_outer_attributes(); - let visa = self.parse_visibility(); - self.parse_method(attrs, visa) + let vis = self.parse_visibility(); + if self.eat_keyword(keywords::Type) { + self.parse_assoc_ty_in_impl(attrs, vis) + } else { + self.parse_method(attrs, vis) + } } fn complain_if_pub_macro(&mut self, visa: Visibility, span: Span) { @@ -4733,7 +4736,7 @@ impl<'a> Parser<'a> { if delim != token::Brace { self.expect(&token::Semi) } - (ast::MethMac(m), self.span.hi, attrs, + (ast::MacImplItem(m), self.span.hi, attrs, token::special_idents::invalid) } else { let unsafety = self.parse_unsafety(); @@ -4753,7 +4756,7 @@ impl<'a> Parser<'a> { let body_span = body.span; let mut new_attrs = attrs; new_attrs.push_all(&inner_attrs[..]); - (ast::MethDecl(ast::MethodSig { + (MethodImplItem(ast::MethodSig { generics: generics, abi: abi, explicit_self: explicit_self, @@ -4767,7 +4770,7 @@ impl<'a> Parser<'a> { attrs: new_attrs, vis: vis, ident: ident, - node: MethodImplItem(method_), + node: method_, span: mk_sp(lo, hi), }) } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 20c8df4299304..07303ba51ff70 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1251,12 +1251,17 @@ impl<'a> State<'a> { try!(self.maybe_print_comment(ti.span.lo)); try!(self.print_outer_attributes(&ti.attrs)); match ti.node { - ast::RequiredMethod(ref sig) => { + ast::MethodTraitItem(ref sig, ref body) => { + if body.is_some() { + try!(self.head("")); + } try!(self.print_method_sig(ti.ident, sig, ast::Inherited)); - word(&mut self.s, ";") - } - ast::ProvidedMethod(ref m) => { - self.print_method(ti.ident, &ti.attrs, ast::Inherited, m) + if let Some(ref body) = *body { + try!(self.nbsp()); + self.print_block_with_attrs(body, &ti.attrs) + } else { + word(&mut self.s, ";") + } } ast::TypeTraitItem(ref bounds, ref default) => { self.print_associated_type(ti.ident, Some(bounds), @@ -1270,30 +1275,17 @@ impl<'a> State<'a> { try!(self.maybe_print_comment(ii.span.lo)); try!(self.print_outer_attributes(&ii.attrs)); match ii.node { - ast::MethodImplItem(ref m) => { - self.print_method(ii.ident, &ii.attrs, ii.vis, m) + ast::MethodImplItem(ref sig, ref body) => { + try!(self.head("")); + try!(self.print_method_sig(ii.ident, sig, ii.vis)); + try!(self.nbsp()); + self.print_block_with_attrs(body, &ii.attrs) } ast::TypeImplItem(ref ty) => { self.print_associated_type(ii.ident, None, Some(ty)) } - } - } - - pub fn print_method(&mut self, - ident: ast::Ident, - attrs: &[ast::Attribute], - vis: ast::Visibility, - meth: &ast::Method) - -> io::Result<()> { - match *meth { - ast::MethDecl(ref sig, ref body) => { - try!(self.head("")); - try!(self.print_method_sig(ident, sig, vis)); - try!(self.nbsp()); - self.print_block_with_attrs(&**body, attrs) - }, - ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _), - ..}) => { + ast::MacImplItem(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _), + ..}) => { // code copied from ItemMac: try!(self.print_path(pth, false, 0)); try!(word(&mut self.s, "! ")); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 4375e17ce0be9..638ddd3ea2e5b 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -38,7 +38,7 @@ pub enum FnKind<'a> { FkItemFn(Ident, &'a Generics, Unsafety, Abi), /// fn foo(&self) - FkMethod(Ident, &'a Method), + FkMethod(Ident, &'a MethodSig), /// |x, y| ... /// proc(x, y) ... @@ -592,28 +592,6 @@ pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: & walk_fn_ret_ty(visitor, &function_declaration.output) } -// Note: there is no visit_method() method in the visitor, instead override -// visit_fn() and check for FkMethod(). I named this visit_method_helper() -// because it is not a default impl of any method, though I doubt that really -// clarifies anything. - Niko -fn walk_method_helper<'v, V: Visitor<'v>>(visitor: &mut V, - id: NodeId, - ident: Ident, - span: Span, - method: &'v Method) { - match *method { - MethDecl(ref sig, ref body) => { - visitor.visit_ident(span, ident); - visitor.visit_fn(FkMethod(ident, method), - &sig.decl, - body, - span, - id); - }, - MethMac(ref mac) => visitor.visit_mac(mac) - } -} - pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'v>, function_declaration: &'v FnDecl, @@ -625,14 +603,9 @@ pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V, FkItemFn(_, generics, _, _) => { visitor.visit_generics(generics); } - FkMethod(_, method) => { - match *method { - MethDecl(ref sig, _) => { - visitor.visit_generics(&sig.generics); - visitor.visit_explicit_self(&sig.explicit_self); - } - MethMac(ref mac) => visitor.visit_mac(mac) - } + FkMethod(_, sig) => { + visitor.visit_generics(&sig.generics); + visitor.visit_explicit_self(&sig.explicit_self); } FkFnBlock(..) => {} } @@ -646,17 +619,14 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai visitor.visit_attribute(attr); } match trait_item.node { - RequiredMethod(ref sig) => { + MethodTraitItem(ref sig, None) => { visitor.visit_explicit_self(&sig.explicit_self); visitor.visit_generics(&sig.generics); walk_fn_decl(visitor, &sig.decl); } - ProvidedMethod(ref method) => { - walk_method_helper(visitor, - trait_item.id, - trait_item.ident, - trait_item.span, - method); + MethodTraitItem(ref sig, Some(ref body)) => { + visitor.visit_fn(FkMethod(trait_item.ident, sig), &sig.decl, + body, trait_item.span, trait_item.id); } TypeTraitItem(ref bounds, ref default) => { walk_ty_param_bounds_helper(visitor, bounds); @@ -671,16 +641,16 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt visitor.visit_attribute(attr); } match impl_item.node { - MethodImplItem(ref method) => { - walk_method_helper(visitor, - impl_item.id, - impl_item.ident, - impl_item.span, - method); + MethodImplItem(ref sig, ref body) => { + visitor.visit_fn(FkMethod(impl_item.ident, sig), &sig.decl, + body, impl_item.span, impl_item.id); } TypeImplItem(ref ty) => { visitor.visit_ty(ty); } + MacImplItem(ref mac) => { + visitor.visit_mac(mac); + } } } diff --git a/src/test/auxiliary/macro_crate_test.rs b/src/test/auxiliary/macro_crate_test.rs index 8218fa0c4892a..36a34bc6c8b41 100644 --- a/src/test/auxiliary/macro_crate_test.rs +++ b/src/test/auxiliary/macro_crate_test.rs @@ -16,7 +16,7 @@ extern crate syntax; extern crate rustc; -use syntax::ast::{TokenTree, Item, MetaItem, ImplItem, TraitItem, Method}; +use syntax::ast::{self, TokenTree, Item, MetaItem}; use syntax::codemap::Span; use syntax::ext::base::*; use syntax::parse::token; @@ -81,7 +81,26 @@ fn expand_into_foo_multi(cx: &mut ExtCtxt, ..(*quote_item!(cx, enum Foo2 { Bar2, Baz2 }).unwrap()).clone() })) } - it => it + Annotatable::ImplItem(it) => { + quote_item!(cx, impl X { fn foo(&self) -> i32 { 42 } }).unwrap().and_then(|i| { + match i.node { + ast::ItemImpl(_, _, _, _, _, mut items) => { + Annotatable::ImplItem(items.pop().expect("impl method not found")) + } + _ => unreachable!("impl parsed to something other than impl") + } + }) + } + Annotatable::TraitItem(it) => { + quote_item!(cx, trait X { fn foo(&self) -> i32 { 0 } }).unwrap().and_then(|i| { + match i.node { + ast::ItemTrait(_, _, _, mut items) => { + Annotatable::TraitItem(items.pop().expect("trait method not found")) + } + _ => unreachable!("trait parsed to something other than trait") + } + }) + } } } diff --git a/src/test/compile-fail/lint-missing-doc.rs b/src/test/compile-fail/lint-missing-doc.rs index 788236a27a55b..04db6c8c8f39c 100644 --- a/src/test/compile-fail/lint-missing-doc.rs +++ b/src/test/compile-fail/lint-missing-doc.rs @@ -60,7 +60,7 @@ trait B { pub trait C { //~ ERROR: missing documentation for a trait fn foo(&self); //~ ERROR: missing documentation for a trait method - fn foo_with_impl(&self) {} //~ ERROR: missing documentation for a default method + fn foo_with_impl(&self) {} //~ ERROR: missing documentation for a trait method } #[allow(missing_docs)]