auto merge of #15691 : jbclements/rust/method-field-cleanup, r=alexcrichton

This patch applies the excellent suggestion of @pnkfelix to group the helper methods for method field access into a Trait, making the code much more readable, and much more similar to the way it was before.
This commit is contained in:
bors 2014-07-16 10:26:16 +00:00
commit efbbb51ec0
18 changed files with 180 additions and 134 deletions

View File

@ -43,6 +43,7 @@ use syntax::ast_map::{PathElem, PathElems};
use syntax::ast_map; use syntax::ast_map;
use syntax::ast_util::*; use syntax::ast_util::*;
use syntax::ast_util; use syntax::ast_util;
use syntax::ast_util::PostExpansionMethod;
use syntax::attr; use syntax::attr;
use syntax::attr::AttrMetaMethods; use syntax::attr::AttrMetaMethods;
use syntax::diagnostic::SpanHandler; use syntax::diagnostic::SpanHandler;
@ -798,7 +799,7 @@ fn encode_info_for_method(ecx: &EncodeContext,
} else { } else {
encode_symbol(ecx, ebml_w, m.def_id.node); encode_symbol(ecx, ebml_w, m.def_id.node);
} }
encode_method_argument_names(ebml_w, method_fn_decl(&*ast_method)); encode_method_argument_names(ebml_w, &*ast_method.pe_fn_decl());
} }
ebml_w.end_tag(); ebml_w.end_tag();
@ -1240,7 +1241,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
encode_method_sort(ebml_w, 'p'); encode_method_sort(ebml_w, 'p');
encode_inlined_item(ecx, ebml_w, encode_inlined_item(ecx, ebml_w,
IIMethodRef(def_id, true, &*m)); IIMethodRef(def_id, true, &*m));
encode_method_argument_names(ebml_w, method_fn_decl(m)); encode_method_argument_names(ebml_w, m.pe_fn_decl());
} }
} }

View File

@ -31,6 +31,7 @@ use middle::{ty, typeck};
use util::ppaux::ty_to_string; use util::ppaux::ty_to_string;
use syntax::{ast, ast_map, ast_util, codemap, fold}; use syntax::{ast, ast_map, ast_util, codemap, fold};
use syntax::ast_util::PostExpansionMethod;
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::fold::Folder; use syntax::fold::Folder;
use syntax::parse::token; use syntax::parse::token;
@ -136,7 +137,7 @@ pub fn decode_inlined_item(cdata: &cstore::crate_metadata,
let ident = match ii { let ident = match ii {
ast::IIItem(i) => i.ident, ast::IIItem(i) => i.ident,
ast::IIForeign(i) => i.ident, ast::IIForeign(i) => i.ident,
ast::IIMethod(_, _, m) => ast_util::method_ident(&*m), ast::IIMethod(_, _, m) => m.pe_ident(),
}; };
debug!("Fn named: {}", token::get_ident(ident)); debug!("Fn named: {}", token::get_ident(ident));
debug!("< Decoded inlined fn: {}::{}", debug!("< Decoded inlined fn: {}::{}",

View File

@ -22,8 +22,7 @@ use util::nodemap::NodeSet;
use std::collections::HashSet; use std::collections::HashSet;
use syntax::ast; use syntax::ast;
use syntax::ast_map; use syntax::ast_map;
use syntax::ast_util; use syntax::ast_util::{local_def, is_local, PostExpansionMethod};
use syntax::ast_util::{local_def, is_local};
use syntax::attr::AttrMetaMethods; use syntax::attr::AttrMetaMethods;
use syntax::attr; use syntax::attr;
use syntax::codemap; use syntax::codemap;
@ -213,7 +212,7 @@ impl<'a> MarkSymbolVisitor<'a> {
visit::walk_trait_method(self, &*trait_method, ctxt); visit::walk_trait_method(self, &*trait_method, ctxt);
} }
ast_map::NodeMethod(method) => { ast_map::NodeMethod(method) => {
visit::walk_block(self, ast_util::method_body(&*method), ctxt); visit::walk_block(self, method.pe_body(), ctxt);
} }
ast_map::NodeForeignItem(foreign_item) => { ast_map::NodeForeignItem(foreign_item) => {
visit::walk_foreign_item(self, &*foreign_item, ctxt); visit::walk_foreign_item(self, &*foreign_item, ctxt);
@ -521,8 +520,7 @@ impl<'a> Visitor<()> for DeadVisitor<'a> {
// Overwrite so that we don't warn the trait method itself. // Overwrite so that we don't warn the trait method itself.
fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) { fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
match *trait_method { match *trait_method {
ast::Provided(ref method) => visit::walk_block(self, ast::Provided(ref method) => visit::walk_block(self, method.pe_body(), ()),
ast_util::method_body(&**method), ()),
ast::Required(_) => () ast::Required(_) => ()
} }
} }

View File

@ -17,7 +17,7 @@ use middle::typeck::MethodCall;
use util::ppaux; use util::ppaux;
use syntax::ast; use syntax::ast;
use syntax::ast_util; use syntax::ast_util::PostExpansionMethod;
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::visit; use syntax::visit;
use syntax::visit::Visitor; use syntax::visit::Visitor;
@ -95,7 +95,7 @@ impl<'a> Visitor<()> for EffectCheckVisitor<'a> {
visit::FkItemFn(_, _, fn_style, _) => visit::FkItemFn(_, _, fn_style, _) =>
(true, fn_style == ast::UnsafeFn), (true, fn_style == ast::UnsafeFn),
visit::FkMethod(_, _, method) => visit::FkMethod(_, _, method) =>
(true, ast_util::method_fn_style(method) == ast::UnsafeFn), (true, method.pe_fn_style() == ast::UnsafeFn),
_ => (false, false), _ => (false, false),
}; };

View File

@ -26,8 +26,7 @@ use util::nodemap::{NodeMap, NodeSet};
use syntax::ast; use syntax::ast;
use syntax::ast_map; use syntax::ast_map;
use syntax::ast_util; use syntax::ast_util::{is_local, local_def, PostExpansionMethod};
use syntax::ast_util::{is_local, local_def};
use syntax::attr; use syntax::attr;
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::parse::token; use syntax::parse::token;
@ -264,10 +263,10 @@ impl<'a> Visitor<()> for EmbargoVisitor<'a> {
if public_ty || public_trait { if public_ty || public_trait {
for method in methods.iter() { for method in methods.iter() {
let meth_public = match ast_util::method_explicit_self(&**method).node { let meth_public = match method.pe_explicit_self().node {
ast::SelfStatic => public_ty, ast::SelfStatic => public_ty,
_ => true, _ => true,
} && ast_util::method_vis(&**method) == ast::Public; } && method.pe_vis() == ast::Public;
if meth_public || tr.is_some() { if meth_public || tr.is_some() {
self.exported_items.insert(method.id); self.exported_items.insert(method.id);
} }
@ -457,8 +456,8 @@ impl<'a> PrivacyVisitor<'a> {
let imp = self.tcx.map.get_parent_did(closest_private_id); let imp = self.tcx.map.get_parent_did(closest_private_id);
match ty::impl_trait_ref(self.tcx, imp) { match ty::impl_trait_ref(self.tcx, imp) {
Some(..) => return Allowable, Some(..) => return Allowable,
_ if ast_util::method_vis(&**m) == ast::Public => return Allowable, _ if m.pe_vis() == ast::Public => return Allowable,
_ => ast_util::method_vis(&**m) _ => m.pe_vis()
} }
} }
Some(ast_map::NodeTraitMethod(_)) => { Some(ast_map::NodeTraitMethod(_)) => {
@ -1079,7 +1078,7 @@ impl<'a> SanePrivacyVisitor<'a> {
"visibility qualifiers have no effect on trait \ "visibility qualifiers have no effect on trait \
impls"); impls");
for m in methods.iter() { for m in methods.iter() {
check_inherited(m.span, ast_util::method_vis(&**m), ""); check_inherited(m.span, m.pe_vis(), "");
} }
} }
@ -1111,7 +1110,7 @@ impl<'a> SanePrivacyVisitor<'a> {
for m in methods.iter() { for m in methods.iter() {
match *m { match *m {
ast::Provided(ref m) => { ast::Provided(ref m) => {
check_inherited(m.span, ast_util::method_vis(&**m), check_inherited(m.span, m.pe_vis(),
"unnecessary visibility"); "unnecessary visibility");
} }
ast::Required(ref m) => { ast::Required(ref m) => {
@ -1149,7 +1148,7 @@ impl<'a> SanePrivacyVisitor<'a> {
match item.node { match item.node {
ast::ItemImpl(_, _, _, ref methods) => { ast::ItemImpl(_, _, _, ref methods) => {
for m in methods.iter() { for m in methods.iter() {
check_inherited(tcx, m.span, ast_util::method_vis(&**m)); check_inherited(tcx, m.span, m.pe_vis());
} }
} }
ast::ItemForeignMod(ref fm) => { ast::ItemForeignMod(ref fm) => {
@ -1175,7 +1174,7 @@ impl<'a> SanePrivacyVisitor<'a> {
match *m { match *m {
ast::Required(..) => {} ast::Required(..) => {}
ast::Provided(ref m) => check_inherited(tcx, m.span, ast::Provided(ref m) => check_inherited(tcx, m.span,
ast_util::method_vis(&**m)), m.pe_vis()),
} }
} }
} }
@ -1345,7 +1344,7 @@ impl<'a> Visitor<()> for VisiblePrivateTypesVisitor<'a> {
// methods will be visible as `Public::foo`. // methods will be visible as `Public::foo`.
let mut found_pub_static = false; let mut found_pub_static = false;
for method in methods.iter() { for method in methods.iter() {
if ast_util::method_explicit_self(&**method).node == ast::SelfStatic && if method.pe_explicit_self().node == ast::SelfStatic &&
self.exported_items.contains(&method.id) { self.exported_items.contains(&method.id) {
found_pub_static = true; found_pub_static = true;
visit::walk_method_helper(self, &**method, ()); visit::walk_method_helper(self, &**method, ());

View File

@ -26,7 +26,7 @@ use std::collections::HashSet;
use syntax::abi; use syntax::abi;
use syntax::ast; use syntax::ast;
use syntax::ast_map; use syntax::ast_map;
use syntax::ast_util::is_local; use syntax::ast_util::{is_local, PostExpansionMethod};
use syntax::ast_util; use syntax::ast_util;
use syntax::attr::{InlineAlways, InlineHint, InlineNever, InlineNone}; use syntax::attr::{InlineAlways, InlineHint, InlineNever, InlineNone};
use syntax::attr; use syntax::attr;
@ -68,7 +68,7 @@ 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, method: &ast::Method,
impl_src: ast::DefId) -> bool { impl_src: ast::DefId) -> bool {
if attributes_specify_inlining(method.attrs.as_slice()) || if attributes_specify_inlining(method.attrs.as_slice()) ||
generics_require_inlining(ast_util::method_generics(&*method)) { generics_require_inlining(method.pe_generics()) {
return true return true
} }
if is_local(impl_src) { if is_local(impl_src) {
@ -200,7 +200,7 @@ impl<'a> ReachableContext<'a> {
} }
} }
Some(ast_map::NodeMethod(method)) => { Some(ast_map::NodeMethod(method)) => {
if generics_require_inlining(ast_util::method_generics(&*method)) || if generics_require_inlining(method.pe_generics()) ||
attributes_specify_inlining(method.attrs.as_slice()) { attributes_specify_inlining(method.attrs.as_slice()) {
true true
} else { } else {
@ -316,14 +316,14 @@ impl<'a> ReachableContext<'a> {
// Keep going, nothing to get exported // Keep going, nothing to get exported
} }
ast::Provided(ref method) => { ast::Provided(ref method) => {
visit::walk_block(self, ast_util::method_body(&**method), ()) visit::walk_block(self, method.pe_body(), ())
} }
} }
} }
ast_map::NodeMethod(method) => { ast_map::NodeMethod(method) => {
let did = self.tcx.map.get_parent_did(search_item); let did = self.tcx.map.get_parent_did(search_item);
if method_might_be_inlined(self.tcx, &*method, did) { if method_might_be_inlined(self.tcx, &*method, did) {
visit::walk_block(self, ast_util::method_body(&*method), ()) visit::walk_block(self, method.pe_body(), ())
} }
} }
// Nothing to recurse on for these // Nothing to recurse on for these

View File

@ -22,8 +22,7 @@ use util::nodemap::{NodeMap, DefIdSet, FnvHashMap};
use syntax::ast::*; use syntax::ast::*;
use syntax::ast; use syntax::ast;
use syntax::ast_util; use syntax::ast_util::{local_def, PostExpansionMethod};
use syntax::ast_util::{local_def};
use syntax::ast_util::{walk_pat, trait_method_to_ty_method}; use syntax::ast_util::{walk_pat, trait_method_to_ty_method};
use syntax::ext::mtwt; use syntax::ext::mtwt;
use syntax::parse::token::special_names; use syntax::parse::token::special_names;
@ -1299,20 +1298,20 @@ impl<'a> Resolver<'a> {
// For each method... // For each method...
for method in methods.iter() { for method in methods.iter() {
// Add the method to the module. // Add the method to the module.
let ident = ast_util::method_ident(&**method); let ident = method.pe_ident();
let method_name_bindings = let method_name_bindings =
self.add_child(ident, self.add_child(ident,
new_parent.clone(), new_parent.clone(),
ForbidDuplicateValues, ForbidDuplicateValues,
method.span); method.span);
let def = match ast_util::method_explicit_self(&**method).node { let def = match method.pe_explicit_self().node {
SelfStatic => { SelfStatic => {
// Static methods become // Static methods become
// `def_static_method`s. // `def_static_method`s.
DefStaticMethod(local_def(method.id), DefStaticMethod(local_def(method.id),
FromImpl(local_def( FromImpl(local_def(
item.id)), item.id)),
ast_util::method_fn_style(&**method)) method.pe_fn_style())
} }
_ => { _ => {
// Non-static methods become // Non-static methods become
@ -1321,7 +1320,7 @@ impl<'a> Resolver<'a> {
} }
}; };
let is_public = ast_util::method_vis(&**method) == ast::Public; let is_public = method.pe_vis() == ast::Public;
method_name_bindings.define_value(def, method_name_bindings.define_value(def,
method.span, method.span,
is_public); is_public);
@ -4004,15 +4003,14 @@ impl<'a> Resolver<'a> {
fn resolve_method(&mut self, fn resolve_method(&mut self,
rib_kind: RibKind, rib_kind: RibKind,
method: &Method) { method: &Method) {
let method_generics = ast_util::method_generics(method); let method_generics = method.pe_generics();
let type_parameters = HasTypeParameters(method_generics, let type_parameters = HasTypeParameters(method_generics,
FnSpace, FnSpace,
method.id, method.id,
rib_kind); rib_kind);
self.resolve_function(rib_kind, Some(ast_util::method_fn_decl(method)), self.resolve_function(rib_kind, Some(method.pe_fn_decl()), type_parameters,
type_parameters, method.pe_body());
ast_util::method_body(method));
} }
fn with_current_self_type<T>(&mut self, self_type: &Ty, f: |&mut Resolver| -> T) -> T { fn with_current_self_type<T>(&mut self, self_type: &Ty, f: |&mut Resolver| -> T) -> T {
@ -4083,7 +4081,7 @@ impl<'a> Resolver<'a> {
fn check_trait_method(&self, method: &Method) { fn check_trait_method(&self, method: &Method) {
// If there is a TraitRef in scope for an impl, then the method must be in the trait. // If there is a TraitRef in scope for an impl, then the method must be in the trait.
for &(did, ref trait_ref) in self.current_trait_ref.iter() { for &(did, ref trait_ref) in self.current_trait_ref.iter() {
let method_name = ast_util::method_ident(method).name; let method_name = method.pe_ident().name;
if self.method_map.borrow().find(&(method_name, did)).is_none() { if self.method_map.borrow().find(&(method_name, did)).is_none() {
let path_str = self.path_idents_to_string(&trait_ref.path); let path_str = self.path_idents_to_string(&trait_ref.path);

View File

@ -43,6 +43,7 @@ use std::os;
use syntax::ast; use syntax::ast;
use syntax::ast_util; use syntax::ast_util;
use syntax::ast_util::PostExpansionMethod;
use syntax::ast::{NodeId,DefId}; use syntax::ast::{NodeId,DefId};
use syntax::ast_map::NodeItem; use syntax::ast_map::NodeItem;
use syntax::attr; use syntax::attr;
@ -333,7 +334,7 @@ impl <'l> DxrVisitor<'l> {
}, },
}; };
qualname.push_str(get_ident(ast_util::method_ident(&*method)).get()); qualname.push_str(get_ident(method.pe_ident()).get());
let qualname = qualname.as_slice(); let qualname = qualname.as_slice();
// record the decl for this def (if it has one) // record the decl for this def (if it has one)
@ -349,18 +350,17 @@ impl <'l> DxrVisitor<'l> {
decl_id, decl_id,
scope_id); scope_id);
let m_decl = ast_util::method_fn_decl(&*method); self.process_formals(&method.pe_fn_decl().inputs, qualname, e);
self.process_formals(&m_decl.inputs, qualname, e);
// walk arg and return types // walk arg and return types
for arg in m_decl.inputs.iter() { for arg in method.pe_fn_decl().inputs.iter() {
self.visit_ty(&*arg.ty, e); self.visit_ty(&*arg.ty, e);
} }
self.visit_ty(m_decl.output, e); self.visit_ty(method.pe_fn_decl().output, e);
// walk the fn body // walk the fn body
self.visit_block(ast_util::method_body(&*method), DxrVisitorEnv::new_nested(method.id)); self.visit_block(method.pe_body(), DxrVisitorEnv::new_nested(method.id));
self.process_generic_params(ast_util::method_generics(&*method), self.process_generic_params(method.pe_generics(),
method.span, method.span,
qualname, qualname,
method.id, method.id,

View File

@ -207,6 +207,7 @@ use std::rc::{Rc, Weak};
use syntax::util::interner::Interner; use syntax::util::interner::Interner;
use syntax::codemap::{Span, Pos}; use syntax::codemap::{Span, Pos};
use syntax::{abi, ast, codemap, ast_util, ast_map}; use syntax::{abi, ast, codemap, ast_util, ast_map};
use syntax::ast_util::PostExpansionMethod;
use syntax::owned_slice::OwnedSlice; use syntax::owned_slice::OwnedSlice;
use syntax::parse::token; use syntax::parse::token;
use syntax::parse::token::special_idents; use syntax::parse::token::special_idents;
@ -1138,10 +1139,10 @@ pub fn create_function_debug_context(cx: &CrateContext,
} }
} }
ast_map::NodeMethod(ref method) => { ast_map::NodeMethod(ref method) => {
(ast_util::method_ident(&**method), (method.pe_ident(),
ast_util::method_fn_decl(&**method), method.pe_fn_decl(),
ast_util::method_generics(&**method), method.pe_generics(),
ast_util::method_body(&**method), method.pe_body(),
method.span, method.span,
true) true)
} }
@ -1167,10 +1168,10 @@ pub fn create_function_debug_context(cx: &CrateContext,
ast_map::NodeTraitMethod(ref trait_method) => { ast_map::NodeTraitMethod(ref trait_method) => {
match **trait_method { match **trait_method {
ast::Provided(ref method) => { ast::Provided(ref method) => {
(ast_util::method_ident(&**method), (method.pe_ident(),
ast_util::method_fn_decl(&**method), method.pe_fn_decl(),
ast_util::method_generics(&**method), method.pe_generics(),
ast_util::method_body(&**method), method.pe_body(),
method.span, method.span,
true) true)
} }

View File

@ -16,7 +16,7 @@ use middle::trans::common::*;
use middle::ty; use middle::ty;
use syntax::ast; use syntax::ast;
use syntax::ast_util::local_def; use syntax::ast_util::{local_def, PostExpansionMethod};
use syntax::ast_util; use syntax::ast_util;
pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
@ -128,12 +128,11 @@ pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did); let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did);
let unparameterized = let unparameterized =
impl_tpt.generics.types.is_empty() && impl_tpt.generics.types.is_empty() &&
ast_util::method_generics(&*mth).ty_params.is_empty(); mth.pe_generics().ty_params.is_empty();
if unparameterized { if unparameterized {
let llfn = get_item_val(ccx, mth.id); let llfn = get_item_val(ccx, mth.id);
trans_fn(ccx, ast_util::method_fn_decl(&*mth), trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), llfn,
ast_util::method_body(&*mth), llfn,
&param_substs::empty(), mth.id, []); &param_substs::empty(), mth.id, []);
} }
local_def(mth.id) local_def(mth.id)

View File

@ -37,7 +37,8 @@ use std::c_str::ToCStr;
use std::gc::Gc; use std::gc::Gc;
use syntax::abi::Rust; use syntax::abi::Rust;
use syntax::parse::token; use syntax::parse::token;
use syntax::{ast, ast_map, visit, ast_util}; use syntax::{ast, ast_map, visit};
use syntax::ast_util::PostExpansionMethod;
/** /**
The main "translation" pass for methods. Generates code The main "translation" pass for methods. Generates code
@ -65,10 +66,9 @@ pub fn trans_impl(ccx: &CrateContext,
return; return;
} }
for method in methods.iter() { for method in methods.iter() {
if ast_util::method_generics(&**method).ty_params.len() == 0u { if method.pe_generics().ty_params.len() == 0u {
let llfn = get_item_val(ccx, method.id); let llfn = get_item_val(ccx, method.id);
trans_fn(ccx, ast_util::method_fn_decl(&**method), trans_fn(ccx, method.pe_fn_decl(), method.pe_body(),
ast_util::method_body(&**method),
llfn, &param_substs::empty(), method.id, []); llfn, &param_substs::empty(), method.id, []);
} else { } else {
let mut v = TransItemVisitor{ ccx: ccx }; let mut v = TransItemVisitor{ ccx: ccx };
@ -160,7 +160,7 @@ pub fn trans_static_method_callee(bcx: &Block,
ast_map::NodeTraitMethod(method) => { ast_map::NodeTraitMethod(method) => {
let ident = match *method { let ident = match *method {
ast::Required(ref m) => m.ident, ast::Required(ref m) => m.ident,
ast::Provided(ref m) => ast_util::method_ident(&**m) ast::Provided(ref m) => m.pe_ident()
}; };
ident.name ident.name
} }

View File

@ -25,8 +25,7 @@ use util::ppaux::Repr;
use syntax::abi; use syntax::abi;
use syntax::ast; use syntax::ast;
use syntax::ast_map; use syntax::ast_map;
use syntax::ast_util; use syntax::ast_util::{local_def, PostExpansionMethod};
use syntax::ast_util::local_def;
use std::hash::{sip, Hash}; use std::hash::{sip, Hash};
pub fn monomorphic_fn(ccx: &CrateContext, pub fn monomorphic_fn(ccx: &CrateContext,
@ -182,8 +181,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
ast_map::NodeMethod(mth) => { ast_map::NodeMethod(mth) => {
let d = mk_lldecl(); let d = mk_lldecl();
set_llvm_fn_attrs(mth.attrs.as_slice(), d); set_llvm_fn_attrs(mth.attrs.as_slice(), d);
trans_fn(ccx, ast_util::method_fn_decl(&*mth), trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), d, &psubsts, mth.id, []);
ast_util::method_body(&*mth), d, &psubsts, mth.id, []);
d d
} }
ast_map::NodeTraitMethod(method) => { ast_map::NodeTraitMethod(method) => {
@ -191,8 +189,8 @@ pub fn monomorphic_fn(ccx: &CrateContext,
ast::Provided(mth) => { ast::Provided(mth) => {
let d = mk_lldecl(); let d = mk_lldecl();
set_llvm_fn_attrs(mth.attrs.as_slice(), d); set_llvm_fn_attrs(mth.attrs.as_slice(), d);
trans_fn(ccx, ast_util::method_fn_decl(&*mth), trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), d,
ast_util::method_body(&*mth), d, &psubsts, mth.id, []); &psubsts, mth.id, []);
d d
} }
_ => { _ => {

View File

@ -125,7 +125,7 @@ use syntax::abi;
use syntax::ast::{Provided, Required}; use syntax::ast::{Provided, Required};
use syntax::ast; use syntax::ast;
use syntax::ast_map; use syntax::ast_map;
use syntax::ast_util::local_def; use syntax::ast_util::{local_def, PostExpansionMethod};
use syntax::ast_util; use syntax::ast_util;
use syntax::attr; use syntax::attr;
use syntax::codemap::Span; use syntax::codemap::Span;
@ -757,16 +757,14 @@ fn check_method_body(ccx: &CrateCtxt,
let method_def_id = local_def(method.id); let method_def_id = local_def(method.id);
let method_ty = ty::method(ccx.tcx, method_def_id); let method_ty = ty::method(ccx.tcx, method_def_id);
let method_generics = &method_ty.generics; let method_generics = &method_ty.generics;
let m_body = ast_util::method_body(&*method);
let param_env = ty::construct_parameter_environment(ccx.tcx, let param_env = ty::construct_parameter_environment(ccx.tcx,
method_generics, method_generics,
m_body.id); method.pe_body().id);
let fty = ty::node_id_to_type(ccx.tcx, method.id); let fty = ty::node_id_to_type(ccx.tcx, method.id);
check_bare_fn(ccx, ast_util::method_fn_decl(&*method), check_bare_fn(ccx, method.pe_fn_decl(), method.pe_body(), method.id, fty, param_env);
m_body, method.id, fty, param_env);
} }
fn check_impl_methods_against_trait(ccx: &CrateCtxt, fn check_impl_methods_against_trait(ccx: &CrateCtxt,
@ -794,7 +792,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
compare_impl_method(ccx.tcx, compare_impl_method(ccx.tcx,
&*impl_method_ty, &*impl_method_ty,
impl_method.span, impl_method.span,
ast_util::method_body(&**impl_method).id, impl_method.pe_body().id,
&**trait_method_ty, &**trait_method_ty,
&impl_trait_ref.substs); &impl_trait_ref.substs);
} }
@ -817,7 +815,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
for trait_method in trait_methods.iter() { for trait_method in trait_methods.iter() {
let is_implemented = let is_implemented =
impl_methods.iter().any( impl_methods.iter().any(
|m| ast_util::method_ident(&**m).name == trait_method.ident.name); |m| m.pe_ident().name == trait_method.ident.name);
let is_provided = let is_provided =
provided_methods.iter().any( provided_methods.iter().any(
|m| m.ident.name == trait_method.ident.name); |m| m.ident.name == trait_method.ident.name);

View File

@ -57,8 +57,7 @@ use syntax::ast::{StaticRegionTyParamBound, OtherRegionTyParamBound};
use syntax::ast::{TraitTyParamBound, UnboxedFnTyParamBound}; use syntax::ast::{TraitTyParamBound, UnboxedFnTyParamBound};
use syntax::ast; use syntax::ast;
use syntax::ast_map; use syntax::ast_map;
use syntax::ast_util; use syntax::ast_util::{local_def, split_trait_methods, PostExpansionMethod};
use syntax::ast_util::{local_def, method_ident, split_trait_methods};
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::codemap; use syntax::codemap;
use syntax::owned_slice::OwnedSlice; use syntax::owned_slice::OwnedSlice;
@ -214,11 +213,8 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
&ast::Provided(ref m) => { &ast::Provided(ref m) => {
ty_method_of_trait_method( ty_method_of_trait_method(
ccx, trait_id, &trait_def.generics, ccx, trait_id, &trait_def.generics,
&m.id, &ast_util::method_ident(&**m), &m.id, &m.pe_ident(), m.pe_explicit_self(),
ast_util::method_explicit_self(&**m), m.pe_generics(), &m.pe_fn_style(), m.pe_fn_decl())
ast_util::method_generics(&**m),
&ast_util::method_fn_style(&**m),
ast_util::method_fn_decl(&**m))
} }
}); });
@ -334,7 +330,7 @@ fn convert_methods(ccx: &CrateCtxt,
let tcx = ccx.tcx; let tcx = ccx.tcx;
let mut seen_methods = HashSet::new(); let mut seen_methods = HashSet::new();
for m in ms.iter() { for m in ms.iter() {
if !seen_methods.insert(ast_util::method_ident(&**m).repr(tcx)) { if !seen_methods.insert(m.pe_ident().repr(ccx.tcx)) {
tcx.sess.span_err(m.span, "duplicate method in trait impl"); tcx.sess.span_err(m.span, "duplicate method in trait impl");
} }
@ -346,9 +342,9 @@ fn convert_methods(ccx: &CrateCtxt,
rcvr_visibility)); rcvr_visibility));
let fty = ty::mk_bare_fn(tcx, mty.fty.clone()); let fty = ty::mk_bare_fn(tcx, mty.fty.clone());
debug!("method {} (id {}) has type {}", debug!("method {} (id {}) has type {}",
method_ident(&**m).repr(tcx), m.pe_ident().repr(ccx.tcx),
m.id, m.id,
fty.repr(tcx)); fty.repr(ccx.tcx));
tcx.tcache.borrow_mut().insert( tcx.tcache.borrow_mut().insert(
local_def(m.id), local_def(m.id),
Polytype { Polytype {
@ -369,24 +365,23 @@ fn convert_methods(ccx: &CrateCtxt,
rcvr_visibility: ast::Visibility) rcvr_visibility: ast::Visibility)
-> ty::Method -> ty::Method
{ {
let fty = astconv::ty_of_method(ccx, m.id, ast_util::method_fn_style(&*m), let fty = astconv::ty_of_method(ccx, m.id, m.pe_fn_style(),
untransformed_rcvr_ty, untransformed_rcvr_ty,
*ast_util::method_explicit_self(&*m), *m.pe_explicit_self(), m.pe_fn_decl());
ast_util::method_fn_decl(&*m));
// if the method specifies a visibility, use that, otherwise // if the method specifies a visibility, use that, otherwise
// inherit the visibility from the impl (so `foo` in `pub impl // inherit the visibility from the impl (so `foo` in `pub impl
// { fn foo(); }` is public, but private in `priv impl { fn // { fn foo(); }` is public, but private in `priv impl { fn
// foo(); }`). // foo(); }`).
let method_vis = ast_util::method_vis(&*m).inherit_from(rcvr_visibility); let method_vis = m.pe_vis().inherit_from(rcvr_visibility);
let m_ty_generics = let m_ty_generics =
ty_generics_for_fn_or_method(ccx, ast_util::method_generics(&*m), ty_generics_for_fn_or_method(ccx, m.pe_generics(),
(*rcvr_ty_generics).clone()); (*rcvr_ty_generics).clone());
ty::Method::new(ast_util::method_ident(&*m), ty::Method::new(m.pe_ident(),
m_ty_generics, m_ty_generics,
fty, fty,
ast_util::method_explicit_self(&*m).node, m.pe_explicit_self().node,
method_vis, method_vis,
local_def(m.id), local_def(m.id),
container, container,

View File

@ -84,7 +84,7 @@ use std::string::String;
use syntax::ast; use syntax::ast;
use syntax::ast_map; use syntax::ast_map;
use syntax::ast_util; use syntax::ast_util;
use syntax::ast_util::name_to_dummy_lifetime; use syntax::ast_util::{name_to_dummy_lifetime, PostExpansionMethod};
use syntax::owned_slice::OwnedSlice; use syntax::owned_slice::OwnedSlice;
use syntax::codemap; use syntax::codemap;
use syntax::parse::token; use syntax::parse::token;
@ -700,11 +700,8 @@ impl<'a> ErrorReporting for InferCtxt<'a> {
} }
} }
ast_map::NodeMethod(ref m) => { ast_map::NodeMethod(ref m) => {
Some((ast_util::method_fn_decl(&**m), Some((m.pe_fn_decl(), m.pe_generics(), m.pe_fn_style(),
ast_util::method_generics(&**m), m.pe_ident(), Some(m.pe_explicit_self().node), m.span))
ast_util::method_fn_style(&**m),
ast_util::method_ident(&**m),
Some(ast_util::method_explicit_self(&**m).node), m.span))
}, },
_ => None _ => None
}, },
@ -1455,7 +1452,7 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
_ => None _ => None
}, },
ast_map::NodeMethod(m) => { ast_map::NodeMethod(m) => {
taken.push_all(ast_util::method_generics(&*m).lifetimes.as_slice()); taken.push_all(m.pe_generics().lifetimes.as_slice());
Some(m.id) Some(m.id)
}, },
_ => None _ => None

View File

@ -14,6 +14,7 @@
use syntax; use syntax;
use syntax::ast; use syntax::ast;
use syntax::ast_util; use syntax::ast_util;
use syntax::ast_util::PostExpansionMethod;
use syntax::attr; use syntax::attr;
use syntax::attr::{AttributeMethods, AttrMetaMethods}; use syntax::attr::{AttributeMethods, AttrMetaMethods};
use syntax::codemap::Pos; use syntax::codemap::Pos;
@ -695,30 +696,30 @@ pub struct Method {
impl Clean<Item> for ast::Method { impl Clean<Item> for ast::Method {
fn clean(&self) -> Item { fn clean(&self) -> Item {
let fn_decl = ast_util::method_fn_decl(self); let all_inputs = &self.pe_fn_decl().inputs;
let inputs = match ast_util::method_explicit_self(self).node { let inputs = match self.pe_explicit_self().node {
ast::SelfStatic => fn_decl.inputs.as_slice(), ast::SelfStatic => all_inputs.as_slice(),
_ => fn_decl.inputs.slice_from(1) _ => all_inputs.slice_from(1)
}; };
let decl = FnDecl { let decl = FnDecl {
inputs: Arguments { inputs: Arguments {
values: inputs.iter().map(|x| x.clean()).collect(), values: inputs.iter().map(|x| x.clean()).collect(),
}, },
output: (fn_decl.output.clean()), output: (self.pe_fn_decl().output.clean()),
cf: fn_decl.cf.clean(), cf: self.pe_fn_decl().cf.clean(),
attrs: Vec::new() attrs: Vec::new()
}; };
Item { Item {
name: Some(ast_util::method_ident(self).clean()), name: Some(self.pe_ident().clean()),
attrs: self.attrs.clean().move_iter().collect(), attrs: self.attrs.clean().move_iter().collect(),
source: self.span.clean(), source: self.span.clean(),
def_id: ast_util::local_def(self.id), def_id: ast_util::local_def(self.id),
visibility: ast_util::method_vis(self).clean(), visibility: self.pe_vis().clean(),
stability: get_stability(ast_util::local_def(self.id)), stability: get_stability(ast_util::local_def(self.id)),
inner: MethodItem(Method { inner: MethodItem(Method {
generics: ast_util::method_generics(self).clean(), generics: self.pe_generics().clean(),
self_: ast_util::method_explicit_self(self).node.clean(), self_: self.pe_explicit_self().node.clean(),
fn_style: ast_util::method_fn_style(self).clone(), fn_style: self.pe_fn_style().clone(),
decl: decl, decl: decl,
}), }),
} }

View File

@ -26,7 +26,7 @@ use ast::{P, Block, FnDecl, NodeId};
use ast; use ast;
use ast_map::{Node}; use ast_map::{Node};
use ast_map; use ast_map;
use ast_util; use ast_util::PostExpansionMethod;
use codemap::Span; use codemap::Span;
use visit; use visit;
@ -152,13 +152,13 @@ impl FnLikeNode {
pub fn body<'a>(&'a self) -> P<Block> { pub fn body<'a>(&'a self) -> P<Block> {
self.handle(|i: ItemFnParts| i.body, self.handle(|i: ItemFnParts| i.body,
|m: &'a ast::Method| ast_util::method_body(m), |m: &'a ast::Method| m.pe_body(),
|c: ClosureParts| c.body) |c: ClosureParts| c.body)
} }
pub fn decl<'a>(&'a self) -> P<FnDecl> { pub fn decl<'a>(&'a self) -> P<FnDecl> {
self.handle(|i: ItemFnParts| i.decl, self.handle(|i: ItemFnParts| i.decl,
|m: &'a ast::Method| ast_util::method_fn_decl(m), |m: &'a ast::Method| m.pe_fn_decl(),
|c: ClosureParts| c.decl) |c: ClosureParts| c.decl)
} }
@ -182,7 +182,7 @@ impl FnLikeNode {
visit::FkFnBlock visit::FkFnBlock
}; };
let method = |m: &'a ast::Method| { let method = |m: &'a ast::Method| {
visit::FkMethod(ast_util::method_ident(m), ast_util::method_generics(m), m) visit::FkMethod(m.pe_ident(), m.pe_generics(), m)
}; };
self.handle(item, method, closure) self.handle(item, method, closure)
} }

View File

@ -742,16 +742,48 @@ pub fn static_has_significant_address(mutbl: ast::Mutability,
inline == InlineNever || inline == InlineNone inline == InlineNever || inline == InlineNone
} }
/// Macro invocations are guaranteed not to occur after expansion is complete. /// 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 /// Extracting fields of a method requires a dynamic check to make sure that it's
/// not a macro invocation, though this check is guaranteed to succeed, assuming /// not a macro invocation. This check is guaranteed to succeed, assuming
/// that the invocations are indeed gone. /// that the invocations are indeed gone.
macro_rules! method_field_extractor { pub trait PostExpansionMethod {
($fn_name:ident, $field_ty:ty, $field_pat:pat, $result:ident) => { fn pe_ident(&self) -> ast::Ident;
/// Returns the ident of a Method. To be used after expansion is complete fn pe_generics<'a>(&'a self) -> &'a ast::Generics;
pub fn $fn_name<'a>(method: &'a ast::Method) -> $field_ty { fn pe_explicit_self<'a>(&'a self) -> &'a ast::ExplicitSelf;
match method.node { fn pe_fn_style(&self) -> ast::FnStyle;
fn pe_fn_decl(&self) -> P<ast::FnDecl>;
fn pe_body(&self) -> P<ast::Block>;
fn pe_vis(&self) -> ast::Visibility;
}
/// can't use the standard cfg(stage0) tricks here, because the error occurs in
/// parsing, before cfg gets a chance to save the day. (yes, interleaved parsing
/// / expansion / configuring would solve this problem...)
// NOTE: remove after next snapshot
/// to be more specific: after a snapshot, swap out the "PRE" stuff, and
// swap in the "POST" stuff.
/// PRE
macro_rules! mf_method_body{
($slf:ident, $field_pat:pat, $result:ident) => {
match $slf.node {
$field_pat => $result,
MethMac(_) => {
fail!("expected an AST without macro invocations");
}
}
}
}
/// POST
/*
#[cfg(not(stage0))]
macro_rules! mf_method{
($meth_name:ident, $field_ty:ty, $field_pat:pat, $result:ident) => {
fn $meth_name<'a>(&'a self) -> $field_ty {
match self.node {
$field_pat => $result, $field_pat => $result,
MethMac(_) => { MethMac(_) => {
fail!("expected an AST without macro invocations"); fail!("expected an AST without macro invocations");
@ -759,20 +791,49 @@ macro_rules! method_field_extractor {
} }
} }
} }
}*/
// PRE
impl PostExpansionMethod for Method {
fn pe_ident(&self) -> ast::Ident {
mf_method_body!(self,MethDecl(ident,_,_,_,_,_,_),ident)
}
fn pe_generics<'a>(&'a self) -> &'a ast::Generics {
mf_method_body!(self,MethDecl(_,ref generics,_,_,_,_,_),generics)
}
fn pe_explicit_self<'a>(&'a self) -> &'a ast::ExplicitSelf {
mf_method_body!(self,MethDecl(_,_,ref explicit_self,_,_,_,_),explicit_self)
}
fn pe_fn_style(&self) -> ast::FnStyle{
mf_method_body!(self,MethDecl(_,_,_,fn_style,_,_,_),fn_style)
}
fn pe_fn_decl(&self) -> P<ast::FnDecl> {
mf_method_body!(self,MethDecl(_,_,_,_,decl,_,_),decl)
}
fn pe_body(&self) -> P<ast::Block> {
mf_method_body!(self,MethDecl(_,_,_,_,_,body,_),body)
}
fn pe_vis(&self) -> ast::Visibility {
mf_method_body!(self,MethDecl(_,_,_,_,_,_,vis),vis)
}
} }
// Note: this is unhygienic in the lifetime 'a. In order to fix this, we'd have to // POST
// add :lifetime as a macro argument type, so that the 'a could be supplied by the macro /*
// invocation. #[cfg(not(stage0))]
pub method_field_extractor!(method_ident,ast::Ident,MethDecl(ident,_,_,_,_,_,_),ident) impl PostExpansionMethod for Method {
pub method_field_extractor!(method_generics,&'a ast::Generics, mf_method!(pe_ident,ast::Ident,MethDecl(ident,_,_,_,_,_,_),ident)
MethDecl(_,ref generics,_,_,_,_,_),generics) mf_method!(pe_generics,&'a ast::Generics,
pub method_field_extractor!(method_explicit_self,&'a ast::ExplicitSelf, MethDecl(_,ref generics,_,_,_,_,_),generics)
MethDecl(_,_,ref explicit_self,_,_,_,_),explicit_self) mf_method!(pe_explicit_self,&'a ast::ExplicitSelf,
pub method_field_extractor!(method_fn_style,ast::FnStyle,MethDecl(_,_,_,fn_style,_,_,_),fn_style) MethDecl(_,_,ref explicit_self,_,_,_,_),explicit_self)
pub method_field_extractor!(method_fn_decl,P<ast::FnDecl>,MethDecl(_,_,_,_,decl,_,_),decl) mf_method!(pe_fn_style,ast::FnStyle,MethDecl(_,_,_,fn_style,_,_,_),fn_style)
pub method_field_extractor!(method_body,P<ast::Block>,MethDecl(_,_,_,_,_,body,_),body) mf_method!(pe_fn_decl,P<ast::FnDecl>,MethDecl(_,_,_,_,decl,_,_),decl)
pub method_field_extractor!(method_vis,ast::Visibility,MethDecl(_,_,_,_,_,_,vis),vis) mf_method!(pe_body,P<ast::Block>,MethDecl(_,_,_,_,_,body,_),body)
mf_method!(pe_vis,ast::Visibility,MethDecl(_,_,_,_,_,_,vis),vis)
}
*/
#[cfg(test)] #[cfg(test)]
mod test { mod test {
@ -799,4 +860,3 @@ mod test {
.iter().map(ident_to_segment).collect::<Vec<PathSegment>>().as_slice())); .iter().map(ident_to_segment).collect::<Vec<PathSegment>>().as_slice()));
} }
} }