syntax: move MethMac to MacImplItem and combine {Provided,Required}Method into MethodTraitItem.

This commit is contained in:
Eduard Burtescu 2015-03-11 23:38:58 +02:00
parent ce10fa8d12
commit 9da918548d
37 changed files with 466 additions and 551 deletions

View File

@ -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(..) => {

View File

@ -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(..) => {}
}
}

View File

@ -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),
};

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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(_) => {

View File

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

View File

@ -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,

View File

@ -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 {

View File

@ -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

View File

@ -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)
}

View File

@ -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);
// walk arg and return types
for arg in &method.pe_sig().decl.inputs {
self.visit_ty(&*arg.ty);
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);
}
if let ast::Return(ref ret_ty) = method.pe_sig().decl.output {
self.visit_ty(&**ret_ty);
// walk arg and return types
for arg in &sig.decl.inputs {
self.visit_ty(&arg.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(_) => {}
}
}

View File

@ -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<cfg::CFG>)
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<cfg::CFG>)
}
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()")
}
}
}

View File

@ -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)
}

View File

@ -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<ast::DefId> {
@ -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);
}

View File

@ -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(_) => {}
}
}
}

View File

@ -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

View File

@ -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 {

View File

@ -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(

View File

@ -279,12 +279,16 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
let mut items: Vec<ImplOrTraitItemId> =
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();

View File

@ -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();
}
};

View File

@ -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<Method> for ast::Method {
impl Clean<Method> 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<Method> 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<PolyTrait> for ast::PolyTraitRef {
impl Clean<Item> 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<Item> for ast::TraitItem {
impl Clean<Item> 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<Item> for ast::ImplItem {
where_predicates: Vec::new()
},
}),
ast::MacImplItem(_) => {
MacroItem(Macro {
source: self.span.to_src(cx),
})
}
};
Item {
name: Some(self.ident.clean(cx)),

View File

@ -33,7 +33,6 @@ pub use self::LocalSource::*;
pub use self::Mac_::*;
pub use self::MacStmtStyle::*;
pub use self::MetaItem_::*;
pub use self::Method::*;
pub use self::Mutability::*;
pub use self::Pat_::*;
pub use self::PathListItem_::*;
@ -1084,8 +1083,7 @@ pub struct TraitItem {
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum TraitItem_ {
RequiredMethod(MethodSig),
ProvidedMethod(Method),
MethodTraitItem(MethodSig, Option<P<Block>>),
TypeTraitItem(TyParamBounds, Option<P<Ty>>),
}
@ -1101,8 +1099,9 @@ pub struct ImplItem {
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum ImplItem_ {
MethodImplItem(Method),
MethodImplItem(MethodSig, P<Block>),
TypeImplItem(P<Ty>),
MacImplItem(Mac),
}
#[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
@ -1416,14 +1415,6 @@ pub enum ExplicitSelf_ {
pub type ExplicitSelf = Spanned<ExplicitSelf_>;
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum Method {
/// Represents a method declaration
MethDecl(MethodSig, P<Block>),
/// Represents a macro in method position
MethMac(Mac),
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Mod {
/// A span from the first token past `{` to the last token until `}`.

View File

@ -28,7 +28,6 @@ use ast::{Block, FnDecl, NodeId};
use ast;
use ast_map::{Node};
use ast_map;
use ast_util::PostExpansionMethod;
use codemap::Span;
use visit;
@ -65,7 +64,7 @@ impl MaybeFnLike for ast::Item {
impl MaybeFnLike for ast::TraitItem {
fn is_fn_like(&self) -> bool {
match self.node { ast::ProvidedMethod(_) => true, _ => false, }
match self.node { ast::MethodTraitItem(_, Some(_)) => true, _ => false, }
}
}
@ -156,25 +155,25 @@ impl<'a> FnLikeNode<'a> {
pub fn body(self) -> &'a Block {
self.handle(|i: ItemFnParts<'a>| &*i.body,
|_, _, m: &'a ast::Method, _| m.pe_body(),
|_, _, _: &'a ast::MethodSig, body: &'a ast::Block, _| body,
|c: ClosureParts<'a>| c.body)
}
pub fn decl(self) -> &'a FnDecl {
self.handle(|i: ItemFnParts<'a>| &*i.decl,
|_, _, m: &'a ast::Method, _| &m.pe_sig().decl,
|_, _, sig: &'a ast::MethodSig, _, _| &sig.decl,
|c: ClosureParts<'a>| c.decl)
}
pub fn span(self) -> Span {
self.handle(|i: ItemFnParts| i.span,
|_, _, _: &'a ast::Method, span| span,
|_, _, _: &'a ast::MethodSig, _, span| span,
|c: ClosureParts| c.span)
}
pub fn id(self) -> NodeId {
self.handle(|i: ItemFnParts| i.id,
|id, _, _: &'a ast::Method, _| id,
|id, _, _: &'a ast::MethodSig, _, _| id,
|c: ClosureParts| c.id)
}
@ -185,15 +184,15 @@ impl<'a> FnLikeNode<'a> {
let closure = |_: ClosureParts| {
visit::FkFnBlock
};
let method = |_, ident, m: &'a ast::Method, _| {
visit::FkMethod(ident, m)
let method = |_, ident, sig: &'a ast::MethodSig, _, _| {
visit::FkMethod(ident, sig)
};
self.handle(item, method, closure)
}
fn handle<A, I, M, C>(self, item_fn: I, method: M, closure: C) -> A where
I: FnOnce(ItemFnParts<'a>) -> A,
M: FnOnce(NodeId, ast::Ident, &'a ast::Method, Span) -> A,
M: FnOnce(NodeId, ast::Ident, &'a ast::MethodSig, &'a ast::Block, Span) -> A,
C: FnOnce(ClosureParts<'a>) -> A,
{
match self.node {
@ -206,13 +205,18 @@ impl<'a> FnLikeNode<'a> {
_ => panic!("item FnLikeNode that is not fn-like"),
},
ast_map::NodeTraitItem(ti) => match ti.node {
ast::ProvidedMethod(ref m) => method(ti.id, ti.ident, m, ti.span),
ast::MethodTraitItem(ref sig, Some(ref body)) => {
method(ti.id, ti.ident, sig, body, ti.span)
}
_ => panic!("trait method FnLikeNode that is not fn-like"),
},
ast_map::NodeImplItem(ii) => {
match ii.node {
ast::MethodImplItem(ref m) => method(ii.id, ii.ident, m, ii.span),
ast::TypeImplItem(_) => {
ast::MethodImplItem(ref sig, ref body) => {
method(ii.id, ii.ident, sig, body, ii.span)
}
ast::TypeImplItem(_) |
ast::MacImplItem(_) => {
panic!("impl method FnLikeNode that is not fn-like")
}
}

View File

@ -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 {}{}",

View File

@ -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::*;

View File

@ -228,8 +228,8 @@ pub trait MacResult {
None
}
/// Create zero or more methods.
fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> {
/// Create zero or more impl items.
fn make_impl_items(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> {
None
}
@ -275,7 +275,7 @@ make_MacEager! {
expr: P<ast::Expr>,
pat: P<ast::Pat>,
items: SmallVector<P<ast::Item>>,
methods: SmallVector<P<ast::ImplItem>>,
impl_items: SmallVector<P<ast::ImplItem>>,
stmt: P<ast::Stmt>,
}
@ -288,8 +288,8 @@ impl MacResult for MacEager {
self.items
}
fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> {
self.methods
fn make_impl_items(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> {
self.impl_items
}
fn make_stmt(self: Box<Self>) -> Option<P<ast::Stmt>> {
@ -377,7 +377,7 @@ impl MacResult for DummyResult {
Some(SmallVector::zero())
}
}
fn make_methods(self: Box<DummyResult>) -> Option<SmallVector<P<ast::ImplItem>>> {
fn make_impl_items(self: Box<DummyResult>) -> Option<SmallVector<P<ast::ImplItem>>> {
if self.expr_only {
None
} else {

View File

@ -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)
})
}

View File

@ -25,7 +25,6 @@ use ext::base::*;
use feature_gate::{self, Features};
use fold;
use fold::*;
use owned_slice::OwnedSlice;
use parse;
use parse::token::{fresh_mark, fresh_name, intern};
use parse::token;
@ -1175,42 +1174,26 @@ fn expand_annotatable(a: Annotatable,
noop_fold_item(it, fld).into_iter().map(|i| Annotatable::Item(i)).collect()
}
},
Annotatable::TraitItem(it) => match it.node {
ast::ProvidedMethod(ast::MethMac(_)) => {
// HACK(eddyb): Expand method macros in a trait as if they were in an impl.
let ii = it.and_then(|ti| match ti.node {
ast::ProvidedMethod(m) => P(ast::ImplItem {
id: ti.id,
ident: ti.ident,
attrs: ti.attrs,
vis: ast::Inherited,
node: ast::MethodImplItem(m),
span: ti.span
}),
ast::MethodTraitItem(_, Some(_)) => SmallVector::one(it.map(|ti| ast::TraitItem {
id: ti.id,
ident: ti.ident,
attrs: ti.attrs,
node: match ti.node {
ast::MethodTraitItem(sig, Some(body)) => {
let (sig, body) = expand_and_rename_method(sig, body, fld);
ast::MethodTraitItem(sig, Some(body))
}
_ => unreachable!()
});
expand_method(ii, fld).into_iter().map(|ii| {
Annotatable::TraitItem(ii.and_then(|ii| P(ast::TraitItem {
id: ii.id,
ident: ii.ident,
attrs: ii.attrs,
node: match ii.node {
ast::MethodImplItem(m) => ast::ProvidedMethod(m),
ast::TypeImplItem(ty) => {
ast::TypeTraitItem(OwnedSlice::empty(), Some(ty))
}
},
span: ii.span
})))
}).collect()
}
_ => {
fold::noop_fold_trait_item(it, fld).into_iter()
.map(|ti| Annotatable::TraitItem(ti)).collect()
}
},
},
span: fld.new_span(ti.span)
})),
_ => fold::noop_fold_trait_item(it, fld)
}.into_iter().map(Annotatable::TraitItem).collect(),
Annotatable::ImplItem(ii) => {
expand_method(ii, fld).into_iter().map(Annotatable::ImplItem).collect()
expand_impl_item(ii, fld).into_iter().map(Annotatable::ImplItem).collect()
}
};
@ -1291,35 +1274,47 @@ fn expand_item_multi_modifier(mut it: Annotatable,
expand_item_multi_modifier(it, fld)
}
// expand an impl item if it's a method macro
fn expand_method(ii: P<ast::ImplItem>, fld: &mut MacroExpander)
fn expand_impl_item(ii: P<ast::ImplItem>, fld: &mut MacroExpander)
-> SmallVector<P<ast::ImplItem>> {
let ii = fold::noop_fold_impl_item(ii, fld).expect_one("expected one impl item");
match ii.node {
ast::MethodImplItem(ast::MethMac(_)) => {
ast::MethodImplItem(..) => SmallVector::one(ii.map(|ii| ast::ImplItem {
id: ii.id,
ident: ii.ident,
attrs: ii.attrs,
vis: ii.vis,
node: match ii.node {
ast::MethodImplItem(sig, body) => {
let (sig, body) = expand_and_rename_method(sig, body, fld);
ast::MethodImplItem(sig, body)
}
_ => unreachable!()
},
span: fld.new_span(ii.span)
})),
ast::MacImplItem(_) => {
let (span, mac) = ii.and_then(|ii| match ii.node {
ast::MethodImplItem(ast::MethMac(mac)) => (ii.span, mac),
ast::MacImplItem(mac) => (ii.span, mac),
_ => unreachable!()
});
let maybe_new_methods =
let maybe_new_items =
expand_mac_invoc(mac, span,
|r| r.make_methods(),
|meths, mark| meths.move_map(|m| mark_method(m, mark)),
|r| r.make_impl_items(),
|meths, mark| meths.move_map(|m| mark_impl_item(m, mark)),
fld);
match maybe_new_methods {
Some(methods) => {
match maybe_new_items {
Some(impl_items) => {
// expand again if necessary
let new_methods = methods.into_iter()
.flat_map(|m| expand_method(m, fld).into_iter())
.collect();
let new_items = impl_items.into_iter().flat_map(|ii| {
expand_impl_item(ii, fld).into_iter()
}).collect();
fld.cx.bt_pop();
new_methods
new_items
}
None => SmallVector::zero()
}
}
_ => SmallVector::one(ii)
_ => fold::noop_fold_impl_item(ii, fld)
}
}
@ -1328,7 +1323,7 @@ fn expand_method(ii: P<ast::ImplItem>, fld: &mut MacroExpander)
/// the block, returning both the new FnDecl and the new Block.
fn expand_and_rename_fn_decl_and_block(fn_decl: P<ast::FnDecl>, block: P<ast::Block>,
fld: &mut MacroExpander)
-> (P<ast::FnDecl>, P<ast::Block>) {
-> (P<ast::FnDecl>, P<ast::Block>) {
let expanded_decl = fld.fold_fn_decl(fn_decl);
let idents = fn_decl_arg_bindings(&*expanded_decl);
let renames =
@ -1342,6 +1337,20 @@ fn expand_and_rename_fn_decl_and_block(fn_decl: P<ast::FnDecl>, block: P<ast::Bl
(rewritten_fn_decl,rewritten_body)
}
fn expand_and_rename_method(sig: ast::MethodSig, body: P<ast::Block>,
fld: &mut MacroExpander)
-> (ast::MethodSig, P<ast::Block>) {
let (rewritten_fn_decl, rewritten_body)
= expand_and_rename_fn_decl_and_block(sig.decl, body, fld);
(ast::MethodSig {
generics: fld.fold_generics(sig.generics),
abi: sig.abi,
explicit_self: fld.fold_explicit_self(sig.explicit_self),
unsafety: sig.unsafety,
decl: rewritten_fn_decl
}, rewritten_body)
}
/// A tree-folder that performs macro expansion
pub struct MacroExpander<'a, 'b:'a> {
pub cx: &'a mut ExtCtxt<'b>,
@ -1391,23 +1400,6 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
expand_arm(arm, self)
}
fn fold_method(&mut self, m: ast::Method) -> ast::Method {
match m {
ast::MethDecl(sig, body) => {
let (rewritten_fn_decl, rewritten_body)
= expand_and_rename_fn_decl_and_block(sig.decl, body, self);
ast::MethDecl(ast::MethodSig {
generics: self.fold_generics(sig.generics),
abi: sig.abi,
explicit_self: self.fold_explicit_self(sig.explicit_self),
unsafety: sig.unsafety,
decl: rewritten_fn_decl
}, rewritten_body)
}
ast::MethMac(mac) => ast::MethMac(mac)
}
}
fn fold_trait_item(&mut self, i: P<ast::TraitItem>) -> SmallVector<P<ast::TraitItem>> {
expand_annotatable(Annotatable::TraitItem(i), self)
.into_iter().map(|i| i.expect_trait_item()).collect()
@ -1561,9 +1553,9 @@ fn mark_item(expr: P<ast::Item>, m: Mrk) -> P<ast::Item> {
}
// apply a given mark to the given item. Used following the expansion of a macro.
fn mark_method(ii: P<ast::ImplItem>, m: Mrk) -> P<ast::ImplItem> {
fn mark_impl_item(ii: P<ast::ImplItem>, m: Mrk) -> P<ast::ImplItem> {
Marker{mark:m}.fold_impl_item(ii)
.expect_one("marking an impl item didn't return exactly one method")
.expect_one("marking an impl item didn't return exactly one impl item")
}
/// Check that there are no macro invocations left in the AST:

View File

@ -71,7 +71,7 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
loop {
let mut parser = self.parser.borrow_mut();
// so... do outer attributes attached to the macro invocation
// just disappear? This question applies to make_methods, as
// just disappear? This question applies to make_impl_items, as
// well.
match parser.parse_item_with_outer_attributes() {
Some(item) => ret.push(item),
@ -82,16 +82,14 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
Some(ret)
}
fn make_methods(self: Box<ParserAnyMacro<'a>>)
-> Option<SmallVector<P<ast::ImplItem>>> {
fn make_impl_items(self: Box<ParserAnyMacro<'a>>)
-> Option<SmallVector<P<ast::ImplItem>>> {
let mut ret = SmallVector::zero();
loop {
let mut parser = self.parser.borrow_mut();
match parser.token {
token::Eof => break,
_ => {
ret.push(parser.parse_method_with_outer_attributes());
}
_ => ret.push(parser.parse_impl_item_with_outer_attributes())
}
}
self.ensure_complete_parse(false);

View File

@ -110,10 +110,6 @@ pub trait Folder : Sized {
noop_fold_fn_decl(d, self)
}
fn fold_method(&mut self, m: Method) -> Method {
noop_fold_method(m, self)
}
fn fold_block(&mut self, b: P<Block>) -> P<Block> {
noop_fold_block(b, self)
}
@ -977,8 +973,10 @@ pub fn noop_fold_trait_item<T: Folder>(i: P<TraitItem>, folder: &mut T)
ident: folder.fold_ident(ident),
attrs: fold_attrs(attrs, folder),
node: match node {
RequiredMethod(sig) => RequiredMethod(noop_fold_method_sig(sig, folder)),
ProvidedMethod(m) => ProvidedMethod(folder.fold_method(m)),
MethodTraitItem(sig, body) => {
MethodTraitItem(noop_fold_method_sig(sig, folder),
body.map(|x| folder.fold_block(x)))
}
TypeTraitItem(bounds, default) => {
TypeTraitItem(folder.fold_bounds(bounds),
default.map(|x| folder.fold_ty(x)))
@ -996,8 +994,12 @@ pub fn noop_fold_impl_item<T: Folder>(i: P<ImplItem>, folder: &mut T)
attrs: fold_attrs(attrs, folder),
vis: vis,
node: match node {
MethodImplItem(m) => MethodImplItem(folder.fold_method(m)),
TypeImplItem(ty) => TypeImplItem(folder.fold_ty(ty))
MethodImplItem(sig, body) => {
MethodImplItem(noop_fold_method_sig(sig, folder),
folder.fold_block(body))
}
TypeImplItem(ty) => TypeImplItem(folder.fold_ty(ty)),
MacImplItem(mac) => MacImplItem(folder.fold_mac(mac))
},
span: folder.new_span(span)
}))
@ -1099,17 +1101,6 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: P<ForeignItem>, folder: &mut T) ->
})
}
// Default fold over a method.
pub fn noop_fold_method<T: Folder>(method: Method, folder: &mut T) -> Method {
match method {
MethDecl(sig, body) => {
MethDecl(noop_fold_method_sig(sig, folder),
folder.fold_block(body))
},
MethMac(mac) => MethMac(folder.fold_mac(mac))
}
}
pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> MethodSig {
MethodSig {
generics: folder.fold_generics(sig.generics),

View File

@ -13,7 +13,7 @@ pub use self::PathParsingMode::*;
use abi;
use ast::{BareFnTy};
use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
use ast::{ProvidedMethod, Public, Unsafety};
use ast::{Public, Unsafety};
use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue};
use ast::{BiBitAnd, BiBitOr, BiBitXor, BiRem, BiLt, BiGt, Block};
use ast::{BlockCheckMode, CaptureByRef, CaptureByValue, CaptureClause};
@ -42,8 +42,7 @@ use ast::{MutTy, BiMul, Mutability};
use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, NodeId, UnNot};
use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct};
use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle};
use ast::{PolyTraitRef};
use ast::{QSelf, RequiredMethod};
use ast::{PolyTraitRef, QSelf};
use ast::{Return, BiShl, BiShr, Stmt, StmtDecl};
use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
use ast::{StructVariantKind, BiSub, StrStyle};
@ -1349,18 +1348,18 @@ impl<'a> Parser<'a> {
};
let hi = p.last_span.hi;
let node = match p.token {
let body = match p.token {
token::Semi => {
p.bump();
debug!("parse_trait_methods(): parsing required method");
RequiredMethod(sig)
None
}
token::OpenDelim(token::Brace) => {
debug!("parse_trait_methods(): parsing provided method");
let (inner_attrs, body) =
p.parse_inner_attrs_and_block();
attrs.push_all(&inner_attrs[..]);
ProvidedMethod(ast::MethDecl(sig, body))
Some(body)
}
_ => {
@ -1374,7 +1373,7 @@ impl<'a> Parser<'a> {
id: ast::DUMMY_NODE_ID,
ident: ident,
attrs: attrs,
node: node,
node: ast::MethodTraitItem(sig, body),
span: mk_sp(lo, hi),
})
}
@ -4682,11 +4681,15 @@ impl<'a> Parser<'a> {
(ident, ItemFn(decl, unsafety, abi, generics, body), Some(inner_attrs))
}
/// Parse a method in a trait impl
pub fn parse_method_with_outer_attributes(&mut self) -> P<ImplItem> {
/// Parse an impl item.
pub fn parse_impl_item_with_outer_attributes(&mut self) -> P<ImplItem> {
let attrs = self.parse_outer_attributes();
let visa = self.parse_visibility();
self.parse_method(attrs, visa)
let vis = self.parse_visibility();
if self.eat_keyword(keywords::Type) {
self.parse_assoc_ty_in_impl(attrs, vis)
} else {
self.parse_method(attrs, vis)
}
}
fn complain_if_pub_macro(&mut self, visa: Visibility, span: Span) {
@ -4733,7 +4736,7 @@ impl<'a> Parser<'a> {
if delim != token::Brace {
self.expect(&token::Semi)
}
(ast::MethMac(m), self.span.hi, attrs,
(ast::MacImplItem(m), self.span.hi, attrs,
token::special_idents::invalid)
} else {
let unsafety = self.parse_unsafety();
@ -4753,7 +4756,7 @@ impl<'a> Parser<'a> {
let body_span = body.span;
let mut new_attrs = attrs;
new_attrs.push_all(&inner_attrs[..]);
(ast::MethDecl(ast::MethodSig {
(MethodImplItem(ast::MethodSig {
generics: generics,
abi: abi,
explicit_self: explicit_self,
@ -4767,7 +4770,7 @@ impl<'a> Parser<'a> {
attrs: new_attrs,
vis: vis,
ident: ident,
node: MethodImplItem(method_),
node: method_,
span: mk_sp(lo, hi),
})
}

View File

@ -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, "! "));

View File

@ -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);
}
}
}

View File

@ -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")
}
})
}
}
}

View File

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