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)]