refactor Method definition to make space for macros
This change propagates to many locations, but because of the Macro Exterminator (or, more properly, the invariant that it protects), macro invocations can't occur downstream of expansion. This means that in librustc and librustdoc, extracting the desired field can simply assume that it can't be a macro invocation. Functions in ast_util abstract over this check.
This commit is contained in:
parent
e178ebf681
commit
b0b4b3122a
@ -799,7 +799,7 @@ fn encode_info_for_method(ecx: &EncodeContext,
|
||||
} else {
|
||||
encode_symbol(ecx, ebml_w, m.def_id.node);
|
||||
}
|
||||
encode_method_argument_names(ebml_w, &*ast_method.decl);
|
||||
encode_method_argument_names(ebml_w, method_fn_decl(&*ast_method));
|
||||
}
|
||||
|
||||
ebml_w.end_tag();
|
||||
@ -1241,7 +1241,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
|
||||
encode_method_sort(ebml_w, 'p');
|
||||
encode_inlined_item(ecx, ebml_w,
|
||||
IIMethodRef(def_id, true, &*m));
|
||||
encode_method_argument_names(ebml_w, &*m.decl);
|
||||
encode_method_argument_names(ebml_w, method_fn_decl(m));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,7 +136,7 @@ pub fn decode_inlined_item(cdata: &cstore::crate_metadata,
|
||||
let ident = match ii {
|
||||
ast::IIItem(i) => i.ident,
|
||||
ast::IIForeign(i) => i.ident,
|
||||
ast::IIMethod(_, _, m) => m.ident,
|
||||
ast::IIMethod(_, _, m) => ast_util::method_ident(&*m),
|
||||
};
|
||||
debug!("Fn named: {}", token::get_ident(ident));
|
||||
debug!("< Decoded inlined fn: {}::{}",
|
||||
|
@ -22,6 +22,7 @@
|
||||
use std::collections::HashSet;
|
||||
use syntax::ast;
|
||||
use syntax::ast_map;
|
||||
use syntax::ast_util;
|
||||
use syntax::ast_util::{local_def, is_local};
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::attr;
|
||||
@ -212,7 +213,7 @@ fn visit_node(&mut self, node: &ast_map::Node) {
|
||||
visit::walk_trait_method(self, &*trait_method, ctxt);
|
||||
}
|
||||
ast_map::NodeMethod(method) => {
|
||||
visit::walk_block(self, &*method.body, ctxt);
|
||||
visit::walk_block(self, ast_util::method_body(&*method), ctxt);
|
||||
}
|
||||
ast_map::NodeForeignItem(foreign_item) => {
|
||||
visit::walk_foreign_item(self, &*foreign_item, ctxt);
|
||||
@ -520,7 +521,8 @@ fn visit_struct_field(&mut self, field: &ast::StructField, _: ()) {
|
||||
// Overwrite so that we don't warn the trait method itself.
|
||||
fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
|
||||
match *trait_method {
|
||||
ast::Provided(ref method) => visit::walk_block(self, &*method.body, ()),
|
||||
ast::Provided(ref method) => visit::walk_block(self,
|
||||
ast_util::method_body(&**method), ()),
|
||||
ast::Required(_) => ()
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
use util::ppaux;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::ast_util;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::visit;
|
||||
use syntax::visit::Visitor;
|
||||
@ -94,7 +95,7 @@ fn visit_fn(&mut self, fn_kind: &visit::FnKind, fn_decl: &ast::FnDecl,
|
||||
visit::FkItemFn(_, _, fn_style, _) =>
|
||||
(true, fn_style == ast::UnsafeFn),
|
||||
visit::FkMethod(_, _, method) =>
|
||||
(true, method.fn_style == ast::UnsafeFn),
|
||||
(true, ast_util::method_fn_style(method) == ast::UnsafeFn),
|
||||
_ => (false, false),
|
||||
};
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::ast_map;
|
||||
use syntax::ast_util;
|
||||
use syntax::ast_util::{is_local, local_def};
|
||||
use syntax::attr;
|
||||
use syntax::codemap::Span;
|
||||
@ -263,10 +264,10 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
|
||||
|
||||
if public_ty || public_trait {
|
||||
for method in methods.iter() {
|
||||
let meth_public = match method.explicit_self.node {
|
||||
let meth_public = match ast_util::method_explicit_self(&**method).node {
|
||||
ast::SelfStatic => public_ty,
|
||||
_ => true,
|
||||
} && method.vis == ast::Public;
|
||||
} && ast_util::method_vis(&**method) == ast::Public;
|
||||
if meth_public || tr.is_some() {
|
||||
self.exported_items.insert(method.id);
|
||||
}
|
||||
@ -456,8 +457,8 @@ fn def_privacy(&self, did: ast::DefId) -> PrivacyResult {
|
||||
let imp = self.tcx.map.get_parent_did(closest_private_id);
|
||||
match ty::impl_trait_ref(self.tcx, imp) {
|
||||
Some(..) => return Allowable,
|
||||
_ if m.vis == ast::Public => return Allowable,
|
||||
_ => m.vis
|
||||
_ if ast_util::method_vis(&**m) == ast::Public => return Allowable,
|
||||
_ => ast_util::method_vis(&**m)
|
||||
}
|
||||
}
|
||||
Some(ast_map::NodeTraitMethod(_)) => {
|
||||
@ -1078,7 +1079,7 @@ fn check_sane_privacy(&self, item: &ast::Item) {
|
||||
"visibility qualifiers have no effect on trait \
|
||||
impls");
|
||||
for m in methods.iter() {
|
||||
check_inherited(m.span, m.vis, "");
|
||||
check_inherited(m.span, ast_util::method_vis(&**m), "");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1110,7 +1111,7 @@ fn check_sane_privacy(&self, item: &ast::Item) {
|
||||
for m in methods.iter() {
|
||||
match *m {
|
||||
ast::Provided(ref m) => {
|
||||
check_inherited(m.span, m.vis,
|
||||
check_inherited(m.span, ast_util::method_vis(&**m),
|
||||
"unnecessary visibility");
|
||||
}
|
||||
ast::Required(ref m) => {
|
||||
@ -1148,7 +1149,7 @@ fn check_inherited(tcx: &ty::ctxt, sp: Span, vis: ast::Visibility) {
|
||||
match item.node {
|
||||
ast::ItemImpl(_, _, _, ref methods) => {
|
||||
for m in methods.iter() {
|
||||
check_inherited(tcx, m.span, m.vis);
|
||||
check_inherited(tcx, m.span, ast_util::method_vis(&**m));
|
||||
}
|
||||
}
|
||||
ast::ItemForeignMod(ref fm) => {
|
||||
@ -1174,7 +1175,7 @@ fn check_inherited(tcx: &ty::ctxt, sp: Span, vis: ast::Visibility) {
|
||||
match *m {
|
||||
ast::Required(..) => {}
|
||||
ast::Provided(ref m) => check_inherited(tcx, m.span,
|
||||
m.vis),
|
||||
ast_util::method_vis(&**m)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1344,7 +1345,7 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
|
||||
// methods will be visible as `Public::foo`.
|
||||
let mut found_pub_static = false;
|
||||
for method in methods.iter() {
|
||||
if method.explicit_self.node == ast::SelfStatic &&
|
||||
if ast_util::method_explicit_self(&**method).node == ast::SelfStatic &&
|
||||
self.exported_items.contains(&method.id) {
|
||||
found_pub_static = true;
|
||||
visit::walk_method_helper(self, &**method, ());
|
||||
|
@ -68,7 +68,7 @@ fn item_might_be_inlined(item: &ast::Item) -> bool {
|
||||
fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method,
|
||||
impl_src: ast::DefId) -> bool {
|
||||
if attributes_specify_inlining(method.attrs.as_slice()) ||
|
||||
generics_require_inlining(&method.generics) {
|
||||
generics_require_inlining(ast_util::method_generics(&*method)) {
|
||||
return true
|
||||
}
|
||||
if is_local(impl_src) {
|
||||
@ -200,7 +200,7 @@ fn def_id_represents_local_inlined_item(&self, def_id: ast::DefId) -> bool {
|
||||
}
|
||||
}
|
||||
Some(ast_map::NodeMethod(method)) => {
|
||||
if generics_require_inlining(&method.generics) ||
|
||||
if generics_require_inlining(ast_util::method_generics(&*method)) ||
|
||||
attributes_specify_inlining(method.attrs.as_slice()) {
|
||||
true
|
||||
} else {
|
||||
@ -316,14 +316,14 @@ fn propagate_node(&mut self, node: &ast_map::Node,
|
||||
// Keep going, nothing to get exported
|
||||
}
|
||||
ast::Provided(ref method) => {
|
||||
visit::walk_block(self, &*method.body, ())
|
||||
visit::walk_block(self, ast_util::method_body(&**method), ())
|
||||
}
|
||||
}
|
||||
}
|
||||
ast_map::NodeMethod(method) => {
|
||||
let did = self.tcx.map.get_parent_did(search_item);
|
||||
if method_might_be_inlined(self.tcx, &*method, did) {
|
||||
visit::walk_block(self, &*method.body, ())
|
||||
visit::walk_block(self, ast_util::method_body(&*method), ())
|
||||
}
|
||||
}
|
||||
// Nothing to recurse on for these
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
use syntax::ast::*;
|
||||
use syntax::ast;
|
||||
use syntax::ast_util;
|
||||
use syntax::ast_util::{local_def};
|
||||
use syntax::ast_util::{walk_pat, trait_method_to_ty_method};
|
||||
use syntax::ext::mtwt;
|
||||
@ -1298,20 +1299,20 @@ fn build_reduced_graph_for_item(&mut self,
|
||||
// For each method...
|
||||
for method in methods.iter() {
|
||||
// Add the method to the module.
|
||||
let ident = method.ident;
|
||||
let ident = ast_util::method_ident(&**method);
|
||||
let method_name_bindings =
|
||||
self.add_child(ident,
|
||||
new_parent.clone(),
|
||||
ForbidDuplicateValues,
|
||||
method.span);
|
||||
let def = match method.explicit_self.node {
|
||||
let def = match ast_util::method_explicit_self(&**method).node {
|
||||
SelfStatic => {
|
||||
// Static methods become
|
||||
// `def_static_method`s.
|
||||
DefStaticMethod(local_def(method.id),
|
||||
FromImpl(local_def(
|
||||
item.id)),
|
||||
method.fn_style)
|
||||
ast_util::method_fn_style(&**method))
|
||||
}
|
||||
_ => {
|
||||
// Non-static methods become
|
||||
@ -1320,7 +1321,7 @@ fn build_reduced_graph_for_item(&mut self,
|
||||
}
|
||||
};
|
||||
|
||||
let is_public = method.vis == ast::Public;
|
||||
let is_public = ast_util::method_vis(&**method) == ast::Public;
|
||||
method_name_bindings.define_value(def,
|
||||
method.span,
|
||||
is_public);
|
||||
@ -4003,13 +4004,15 @@ fn resolve_struct(&mut self,
|
||||
fn resolve_method(&mut self,
|
||||
rib_kind: RibKind,
|
||||
method: &Method) {
|
||||
let method_generics = &method.generics;
|
||||
let method_generics = ast_util::method_generics(method);
|
||||
let type_parameters = HasTypeParameters(method_generics,
|
||||
FnSpace,
|
||||
method.id,
|
||||
rib_kind);
|
||||
|
||||
self.resolve_function(rib_kind, Some(method.decl), type_parameters, method.body);
|
||||
self.resolve_function(rib_kind, Some(ast_util::method_fn_decl(method)),
|
||||
type_parameters,
|
||||
ast_util::method_body(method));
|
||||
}
|
||||
|
||||
fn with_current_self_type<T>(&mut self, self_type: &Ty, f: |&mut Resolver| -> T) -> T {
|
||||
@ -4080,7 +4083,7 @@ fn resolve_implementation(&mut self,
|
||||
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.
|
||||
for &(did, ref trait_ref) in self.current_trait_ref.iter() {
|
||||
let method_name = method.ident.name;
|
||||
let method_name = ast_util::method_ident(method).name;
|
||||
|
||||
if self.method_map.borrow().find(&(method_name, did)).is_none() {
|
||||
let path_str = self.path_idents_to_string(&trait_ref.path);
|
||||
|
@ -333,7 +333,7 @@ fn process_method(&mut self, method: &ast::Method, e:DxrVisitorEnv) {
|
||||
},
|
||||
};
|
||||
|
||||
qualname.push_str(get_ident(method.ident).get());
|
||||
qualname.push_str(get_ident(ast_util::method_ident(&*method)).get());
|
||||
let qualname = qualname.as_slice();
|
||||
|
||||
// record the decl for this def (if it has one)
|
||||
@ -349,17 +349,18 @@ fn process_method(&mut self, method: &ast::Method, e:DxrVisitorEnv) {
|
||||
decl_id,
|
||||
scope_id);
|
||||
|
||||
self.process_formals(&method.decl.inputs, qualname, e);
|
||||
let m_decl = ast_util::method_fn_decl(&*method);
|
||||
self.process_formals(&m_decl.inputs, qualname, e);
|
||||
|
||||
// walk arg and return types
|
||||
for arg in method.decl.inputs.iter() {
|
||||
for arg in m_decl.inputs.iter() {
|
||||
self.visit_ty(&*arg.ty, e);
|
||||
}
|
||||
self.visit_ty(&*method.decl.output, e);
|
||||
self.visit_ty(m_decl.output, e);
|
||||
// walk the fn body
|
||||
self.visit_block(&*method.body, DxrVisitorEnv::new_nested(method.id));
|
||||
self.visit_block(ast_util::method_body(&*method), DxrVisitorEnv::new_nested(method.id));
|
||||
|
||||
self.process_generic_params(&method.generics,
|
||||
self.process_generic_params(ast_util::method_generics(&*method),
|
||||
method.span,
|
||||
qualname,
|
||||
method.id,
|
||||
|
@ -1138,10 +1138,10 @@ pub fn create_function_debug_context(cx: &CrateContext,
|
||||
}
|
||||
}
|
||||
ast_map::NodeMethod(ref method) => {
|
||||
(method.ident,
|
||||
method.decl,
|
||||
&method.generics,
|
||||
method.body,
|
||||
(ast_util::method_ident(&**method),
|
||||
ast_util::method_fn_decl(&**method),
|
||||
ast_util::method_generics(&**method),
|
||||
ast_util::method_body(&**method),
|
||||
method.span,
|
||||
true)
|
||||
}
|
||||
@ -1167,10 +1167,10 @@ pub fn create_function_debug_context(cx: &CrateContext,
|
||||
ast_map::NodeTraitMethod(ref trait_method) => {
|
||||
match **trait_method {
|
||||
ast::Provided(ref method) => {
|
||||
(method.ident,
|
||||
method.decl,
|
||||
&method.generics,
|
||||
method.body,
|
||||
(ast_util::method_ident(&**method),
|
||||
ast_util::method_fn_decl(&**method),
|
||||
ast_util::method_generics(&**method),
|
||||
ast_util::method_body(&**method),
|
||||
method.span,
|
||||
true)
|
||||
}
|
||||
|
@ -128,11 +128,12 @@ pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
|
||||
let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did);
|
||||
let unparameterized =
|
||||
impl_tpt.generics.types.is_empty() &&
|
||||
mth.generics.ty_params.is_empty();
|
||||
ast_util::method_generics(&*mth).ty_params.is_empty();
|
||||
|
||||
if unparameterized {
|
||||
let llfn = get_item_val(ccx, mth.id);
|
||||
trans_fn(ccx, &*mth.decl, &*mth.body, llfn,
|
||||
trans_fn(ccx, ast_util::method_fn_decl(&*mth),
|
||||
ast_util::method_body(&*mth), llfn,
|
||||
¶m_substs::empty(), mth.id, []);
|
||||
}
|
||||
local_def(mth.id)
|
||||
|
@ -38,7 +38,7 @@
|
||||
use std::gc::Gc;
|
||||
use syntax::abi::Rust;
|
||||
use syntax::parse::token;
|
||||
use syntax::{ast, ast_map, visit};
|
||||
use syntax::{ast, ast_map, visit, ast_util};
|
||||
|
||||
/**
|
||||
The main "translation" pass for methods. Generates code
|
||||
@ -66,9 +66,10 @@ pub fn trans_impl(ccx: &CrateContext,
|
||||
return;
|
||||
}
|
||||
for method in methods.iter() {
|
||||
if method.generics.ty_params.len() == 0u {
|
||||
if ast_util::method_generics(&**method).ty_params.len() == 0u {
|
||||
let llfn = get_item_val(ccx, method.id);
|
||||
trans_fn(ccx, &*method.decl, &*method.body,
|
||||
trans_fn(ccx, ast_util::method_fn_decl(&**method),
|
||||
ast_util::method_body(&**method),
|
||||
llfn, ¶m_substs::empty(), method.id, []);
|
||||
} else {
|
||||
let mut v = TransItemVisitor{ ccx: ccx };
|
||||
@ -160,7 +161,7 @@ pub fn trans_static_method_callee(bcx: &Block,
|
||||
ast_map::NodeTraitMethod(method) => {
|
||||
let ident = match *method {
|
||||
ast::Required(ref m) => m.ident,
|
||||
ast::Provided(ref m) => m.ident
|
||||
ast::Provided(ref m) => ast_util::method_ident(&**m)
|
||||
};
|
||||
ident.name
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
use syntax::abi;
|
||||
use syntax::ast;
|
||||
use syntax::ast_map;
|
||||
use syntax::ast_util;
|
||||
use syntax::ast_util::local_def;
|
||||
use std::hash::{sip, Hash};
|
||||
|
||||
@ -181,7 +182,8 @@ pub fn monomorphic_fn(ccx: &CrateContext,
|
||||
ast_map::NodeMethod(mth) => {
|
||||
let d = mk_lldecl();
|
||||
set_llvm_fn_attrs(mth.attrs.as_slice(), d);
|
||||
trans_fn(ccx, &*mth.decl, &*mth.body, d, &psubsts, mth.id, []);
|
||||
trans_fn(ccx, ast_util::method_fn_decl(&*mth),
|
||||
ast_util::method_body(&*mth), d, &psubsts, mth.id, []);
|
||||
d
|
||||
}
|
||||
ast_map::NodeTraitMethod(method) => {
|
||||
@ -189,7 +191,8 @@ pub fn monomorphic_fn(ccx: &CrateContext,
|
||||
ast::Provided(mth) => {
|
||||
let d = mk_lldecl();
|
||||
set_llvm_fn_attrs(mth.attrs.as_slice(), d);
|
||||
trans_fn(ccx, &*mth.decl, &*mth.body, d, &psubsts, mth.id, []);
|
||||
trans_fn(ccx, ast_util::method_fn_decl(&*mth),
|
||||
ast_util::method_body(&*mth), d, &psubsts, mth.id, []);
|
||||
d
|
||||
}
|
||||
_ => {
|
||||
|
@ -757,14 +757,16 @@ fn check_method_body(ccx: &CrateCtxt,
|
||||
let method_def_id = local_def(method.id);
|
||||
let method_ty = ty::method(ccx.tcx, method_def_id);
|
||||
let method_generics = &method_ty.generics;
|
||||
let m_body = ast_util::method_body(&*method);
|
||||
|
||||
let param_env = ty::construct_parameter_environment(ccx.tcx,
|
||||
method_generics,
|
||||
method.body.id);
|
||||
m_body.id);
|
||||
|
||||
let fty = ty::node_id_to_type(ccx.tcx, method.id);
|
||||
|
||||
check_bare_fn(ccx, &*method.decl, &*method.body, method.id, fty, param_env);
|
||||
check_bare_fn(ccx, ast_util::method_fn_decl(&*method),
|
||||
m_body, method.id, fty, param_env);
|
||||
}
|
||||
|
||||
fn check_impl_methods_against_trait(ccx: &CrateCtxt,
|
||||
@ -792,7 +794,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
|
||||
compare_impl_method(ccx.tcx,
|
||||
&*impl_method_ty,
|
||||
impl_method.span,
|
||||
impl_method.body.id,
|
||||
ast_util::method_body(&**impl_method).id,
|
||||
&**trait_method_ty,
|
||||
&impl_trait_ref.substs);
|
||||
}
|
||||
@ -815,7 +817,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
|
||||
for trait_method in trait_methods.iter() {
|
||||
let is_implemented =
|
||||
impl_methods.iter().any(
|
||||
|m| m.ident.name == trait_method.ident.name);
|
||||
|m| ast_util::method_ident(&**m).name == trait_method.ident.name);
|
||||
let is_provided =
|
||||
provided_methods.iter().any(
|
||||
|m| m.ident.name == trait_method.ident.name);
|
||||
|
@ -57,7 +57,8 @@
|
||||
use syntax::ast::{TraitTyParamBound, UnboxedFnTyParamBound};
|
||||
use syntax::ast;
|
||||
use syntax::ast_map;
|
||||
use syntax::ast_util::{local_def, split_trait_methods};
|
||||
use syntax::ast_util;
|
||||
use syntax::ast_util::{local_def, method_ident, split_trait_methods};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::codemap;
|
||||
use syntax::owned_slice::OwnedSlice;
|
||||
@ -213,8 +214,11 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
|
||||
&ast::Provided(ref m) => {
|
||||
ty_method_of_trait_method(
|
||||
ccx, trait_id, &trait_def.generics,
|
||||
&m.id, &m.ident, &m.explicit_self,
|
||||
&m.generics, &m.fn_style, &*m.decl)
|
||||
&m.id, &ast_util::method_ident(&**m),
|
||||
ast_util::method_explicit_self(&**m),
|
||||
ast_util::method_generics(&**m),
|
||||
&ast_util::method_fn_style(&**m),
|
||||
ast_util::method_fn_decl(&**m))
|
||||
}
|
||||
});
|
||||
|
||||
@ -330,7 +334,7 @@ fn convert_methods(ccx: &CrateCtxt,
|
||||
let tcx = ccx.tcx;
|
||||
let mut seen_methods = HashSet::new();
|
||||
for m in ms.iter() {
|
||||
if !seen_methods.insert(m.ident.repr(ccx.tcx)) {
|
||||
if !seen_methods.insert(ast_util::method_ident(&**m).repr(tcx)) {
|
||||
tcx.sess.span_err(m.span, "duplicate method in trait impl");
|
||||
}
|
||||
|
||||
@ -342,9 +346,9 @@ fn convert_methods(ccx: &CrateCtxt,
|
||||
rcvr_visibility));
|
||||
let fty = ty::mk_bare_fn(tcx, mty.fty.clone());
|
||||
debug!("method {} (id {}) has type {}",
|
||||
m.ident.repr(ccx.tcx),
|
||||
method_ident(&**m).repr(tcx),
|
||||
m.id,
|
||||
fty.repr(ccx.tcx));
|
||||
fty.repr(tcx));
|
||||
tcx.tcache.borrow_mut().insert(
|
||||
local_def(m.id),
|
||||
Polytype {
|
||||
@ -365,23 +369,24 @@ fn ty_of_method(ccx: &CrateCtxt,
|
||||
rcvr_visibility: ast::Visibility)
|
||||
-> ty::Method
|
||||
{
|
||||
let fty = astconv::ty_of_method(ccx, m.id, m.fn_style,
|
||||
let fty = astconv::ty_of_method(ccx, m.id, ast_util::method_fn_style(&*m),
|
||||
untransformed_rcvr_ty,
|
||||
m.explicit_self, &*m.decl);
|
||||
*ast_util::method_explicit_self(&*m),
|
||||
ast_util::method_fn_decl(&*m));
|
||||
|
||||
// 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 = m.vis.inherit_from(rcvr_visibility);
|
||||
let method_vis = ast_util::method_vis(&*m).inherit_from(rcvr_visibility);
|
||||
|
||||
let m_ty_generics =
|
||||
ty_generics_for_fn_or_method(ccx, &m.generics,
|
||||
ty_generics_for_fn_or_method(ccx, ast_util::method_generics(&*m),
|
||||
(*rcvr_ty_generics).clone());
|
||||
ty::Method::new(m.ident,
|
||||
ty::Method::new(ast_util::method_ident(&*m),
|
||||
m_ty_generics,
|
||||
fty,
|
||||
m.explicit_self.node,
|
||||
ast_util::method_explicit_self(&*m).node,
|
||||
method_vis,
|
||||
local_def(m.id),
|
||||
container,
|
||||
|
@ -693,15 +693,18 @@ fn give_suggestion(&self, same_regions: &[SameRegions]) {
|
||||
Some(ref node) => match *node {
|
||||
ast_map::NodeItem(ref item) => {
|
||||
match item.node {
|
||||
ast::ItemFn(ref fn_decl, ref pur, _, ref gen, _) => {
|
||||
ast::ItemFn(fn_decl, ref pur, _, ref gen, _) => {
|
||||
Some((fn_decl, gen, *pur, item.ident, None, item.span))
|
||||
},
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
ast_map::NodeMethod(ref m) => {
|
||||
Some((&m.decl, &m.generics, m.fn_style,
|
||||
m.ident, Some(m.explicit_self.node), m.span))
|
||||
Some((ast_util::method_fn_decl(&**m),
|
||||
ast_util::method_generics(&**m),
|
||||
ast_util::method_fn_style(&**m),
|
||||
ast_util::method_ident(&**m),
|
||||
Some(ast_util::method_explicit_self(&**m).node), m.span))
|
||||
},
|
||||
_ => None
|
||||
},
|
||||
@ -711,7 +714,7 @@ fn give_suggestion(&self, same_regions: &[SameRegions]) {
|
||||
= node_inner.expect("expect item fn");
|
||||
let taken = lifetimes_in_scope(self.tcx, scope_id);
|
||||
let life_giver = LifeGiver::with_taken(taken.as_slice());
|
||||
let rebuilder = Rebuilder::new(self.tcx, *fn_decl, expl_self,
|
||||
let rebuilder = Rebuilder::new(self.tcx, fn_decl, expl_self,
|
||||
generics, same_regions, &life_giver);
|
||||
let (fn_decl, expl_self, generics) = rebuilder.rebuild();
|
||||
self.give_expl_lifetime_param(&fn_decl, fn_style, ident,
|
||||
@ -1452,7 +1455,7 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
|
||||
_ => None
|
||||
},
|
||||
ast_map::NodeMethod(m) => {
|
||||
taken.push_all(m.generics.lifetimes.as_slice());
|
||||
taken.push_all(ast_util::method_generics(&*m).lifetimes.as_slice());
|
||||
Some(m.id)
|
||||
},
|
||||
_ => None
|
||||
|
@ -695,29 +695,30 @@ pub struct Method {
|
||||
|
||||
impl Clean<Item> for ast::Method {
|
||||
fn clean(&self) -> Item {
|
||||
let inputs = match self.explicit_self.node {
|
||||
ast::SelfStatic => self.decl.inputs.as_slice(),
|
||||
_ => self.decl.inputs.slice_from(1)
|
||||
let fn_decl = ast_util::method_fn_decl(self);
|
||||
let inputs = match ast_util::method_explicit_self(self).node {
|
||||
ast::SelfStatic => fn_decl.inputs.as_slice(),
|
||||
_ => fn_decl.inputs.slice_from(1)
|
||||
};
|
||||
let decl = FnDecl {
|
||||
inputs: Arguments {
|
||||
values: inputs.iter().map(|x| x.clean()).collect(),
|
||||
},
|
||||
output: (self.decl.output.clean()),
|
||||
cf: self.decl.cf.clean(),
|
||||
output: (fn_decl.output.clean()),
|
||||
cf: fn_decl.cf.clean(),
|
||||
attrs: Vec::new()
|
||||
};
|
||||
Item {
|
||||
name: Some(self.ident.clean()),
|
||||
name: Some(ast_util::method_ident(self).clean()),
|
||||
attrs: self.attrs.clean().move_iter().collect(),
|
||||
source: self.span.clean(),
|
||||
def_id: ast_util::local_def(self.id),
|
||||
visibility: self.vis.clean(),
|
||||
visibility: ast_util::method_vis(self).clean(),
|
||||
stability: get_stability(ast_util::local_def(self.id)),
|
||||
inner: MethodItem(Method {
|
||||
generics: self.generics.clean(),
|
||||
self_: self.explicit_self.node.clean(),
|
||||
fn_style: self.fn_style.clone(),
|
||||
generics: ast_util::method_generics(self).clean(),
|
||||
self_: ast_util::method_explicit_self(self).node.clean(),
|
||||
fn_style: ast_util::method_fn_style(self).clone(),
|
||||
decl: decl,
|
||||
}),
|
||||
}
|
||||
|
@ -633,6 +633,8 @@ pub enum Matcher_ {
|
||||
/// There's only one flavor, now, so this could presumably be simplified.
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub enum Mac_ {
|
||||
// NB: the additional ident for a macro_rules-style macro is actually
|
||||
// stored in the enclosing item. Oog.
|
||||
MacInvocTT(Path, Vec<TokenTree> , SyntaxContext), // new macro-invocation
|
||||
}
|
||||
|
||||
@ -950,19 +952,20 @@ pub enum ExplicitSelf_ {
|
||||
|
||||
pub type ExplicitSelf = Spanned<ExplicitSelf_>;
|
||||
|
||||
// Represents a method declaration
|
||||
#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub struct Method {
|
||||
pub ident: Ident,
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub generics: Generics,
|
||||
pub explicit_self: ExplicitSelf,
|
||||
pub fn_style: FnStyle,
|
||||
pub decl: P<FnDecl>,
|
||||
pub body: P<Block>,
|
||||
pub id: NodeId,
|
||||
pub span: Span,
|
||||
pub vis: Visibility,
|
||||
pub node: Method_
|
||||
}
|
||||
|
||||
#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
pub enum Method_ {
|
||||
/// Represents a method declaration
|
||||
MethDecl(Ident, Generics, ExplicitSelf, FnStyle, P<FnDecl>, P<Block>, Visibility),
|
||||
/// Represents a macro in method position
|
||||
MethMac(Mac),
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
|
||||
|
@ -304,8 +304,10 @@ pub fn expect_foreign_item(&self, id: NodeId) -> Gc<ForeignItem> {
|
||||
}
|
||||
}
|
||||
|
||||
/// returns the name associated with the given NodeId's AST
|
||||
pub fn get_path_elem(&self, id: NodeId) -> PathElem {
|
||||
match self.get(id) {
|
||||
let node = self.get(id);
|
||||
match node {
|
||||
NodeItem(item) => {
|
||||
match item.node {
|
||||
ItemMod(_) | ItemForeignMod(_) => {
|
||||
@ -315,13 +317,19 @@ pub fn get_path_elem(&self, id: NodeId) -> PathElem {
|
||||
}
|
||||
}
|
||||
NodeForeignItem(i) => PathName(i.ident.name),
|
||||
NodeMethod(m) => PathName(m.ident.name),
|
||||
NodeMethod(m) => match m.node {
|
||||
MethDecl(ident, _, _, _, _, _, _) => PathName(ident.name),
|
||||
MethMac(_) => fail!("no path elem for {:?}", node)
|
||||
},
|
||||
NodeTraitMethod(tm) => match *tm {
|
||||
Required(ref m) => PathName(m.ident.name),
|
||||
Provided(ref m) => PathName(m.ident.name)
|
||||
Provided(m) => match m.node {
|
||||
MethDecl(ident, _, _, _, _, _, _) => PathName(ident.name),
|
||||
MethMac(_) => fail!("no path elem for {:?}", node),
|
||||
}
|
||||
},
|
||||
NodeVariant(v) => PathName(v.node.name.name),
|
||||
node => fail!("no path elem for {:?}", node)
|
||||
_ => fail!("no path elem for {:?}", node)
|
||||
}
|
||||
}
|
||||
|
||||
@ -369,6 +377,8 @@ fn with_path_next<T>(&self, id: NodeId, next: LinkedPath, f: |PathElems| -> T) -
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a node ID and a closure, apply the closure to the array
|
||||
/// of attributes associated with the AST corresponding to the Node ID
|
||||
pub fn with_attrs<T>(&self, id: NodeId, f: |Option<&[Attribute]>| -> T) -> T {
|
||||
let node = self.get(id);
|
||||
let attrs = match node {
|
||||
@ -695,11 +705,15 @@ fn node_id_to_string(map: &Map, id: NodeId) -> String {
|
||||
let path_str = map.path_to_str_with_ident(id, item.ident);
|
||||
format!("foreign item {} (id={})", path_str, id)
|
||||
}
|
||||
Some(NodeMethod(m)) => {
|
||||
format!("method {} in {} (id={})",
|
||||
token::get_ident(m.ident),
|
||||
map.path_to_string(id), id)
|
||||
}
|
||||
Some(NodeMethod(m)) => match m.node {
|
||||
MethDecl(ident, _, _, _, _, _, _) =>
|
||||
format!("method {} in {} (id={})",
|
||||
token::get_ident(ident),
|
||||
map.path_to_string(id), id),
|
||||
MethMac(ref mac) =>
|
||||
format!("method macro {} (id={})",
|
||||
pprust::mac_to_string(mac), id)
|
||||
},
|
||||
Some(NodeTraitMethod(ref tm)) => {
|
||||
let m = ast_util::trait_method_to_ty_method(&**tm);
|
||||
format!("method {} in {} (id={})",
|
||||
|
@ -240,32 +240,31 @@ pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
|
||||
token::gensym_ident(pretty.as_slice())
|
||||
}
|
||||
|
||||
pub fn public_methods(ms: Vec<Gc<Method>> ) -> Vec<Gc<Method>> {
|
||||
ms.move_iter().filter(|m| {
|
||||
match m.vis {
|
||||
Public => true,
|
||||
_ => false
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
|
||||
/// extract a TypeMethod from a TraitMethod. if the TraitMethod is
|
||||
/// a default, pull out the useful fields to make a TypeMethod
|
||||
//
|
||||
// NB: to be used only after expansion is complete, and macros are gone.
|
||||
pub fn trait_method_to_ty_method(method: &TraitMethod) -> TypeMethod {
|
||||
match *method {
|
||||
Required(ref m) => (*m).clone(),
|
||||
Provided(ref m) => {
|
||||
TypeMethod {
|
||||
ident: m.ident,
|
||||
attrs: m.attrs.clone(),
|
||||
fn_style: m.fn_style,
|
||||
decl: m.decl,
|
||||
generics: m.generics.clone(),
|
||||
explicit_self: m.explicit_self,
|
||||
id: m.id,
|
||||
span: m.span,
|
||||
vis: m.vis,
|
||||
Provided(m) => {
|
||||
match m.node {
|
||||
MethDecl(ident, ref generics, explicit_self, fn_style, decl, _, vis) => {
|
||||
TypeMethod {
|
||||
ident: ident,
|
||||
attrs: m.attrs.clone(),
|
||||
fn_style: fn_style,
|
||||
decl: decl,
|
||||
generics: generics.clone(),
|
||||
explicit_self: explicit_self,
|
||||
id: m.id,
|
||||
span: m.span,
|
||||
vis: vis,
|
||||
}
|
||||
},
|
||||
MethMac(_) => fail!("expected non-macro method declaration")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -346,6 +345,9 @@ pub trait IdVisitingOperation {
|
||||
fn visit_id(&self, node_id: NodeId);
|
||||
}
|
||||
|
||||
/// A visitor that applies its operation to all of the node IDs
|
||||
/// in a visitable thing.
|
||||
|
||||
pub struct IdVisitor<'a, O> {
|
||||
pub operation: &'a O,
|
||||
pub pass_through_items: bool,
|
||||
@ -740,6 +742,38 @@ pub fn static_has_significant_address(mutbl: ast::Mutability,
|
||||
inline == InlineNever || inline == InlineNone
|
||||
}
|
||||
|
||||
|
||||
/// 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, though this check is guaranteed to succeed, assuming
|
||||
/// that the invocations are indeed gone.
|
||||
macro_rules! method_field_extractor {
|
||||
($fn_name:ident, $field_ty:ty, $field_pat:pat, $result:ident) => {
|
||||
/// Returns the ident of a Method. To be used after expansion is complete
|
||||
pub fn $fn_name<'a>(method: &'a ast::Method) -> $field_ty {
|
||||
match method.node {
|
||||
$field_pat => $result,
|
||||
MethMac(_) => {
|
||||
fail!("expected an AST without macro invocations");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note: this is unhygienic in the lifetime 'a. In order to fix this, we'd have to
|
||||
// add :lifetime as a macro argument type, so that the 'a could be supplied by the macro
|
||||
// invocation.
|
||||
pub method_field_extractor!(method_ident,ast::Ident,MethDecl(ident,_,_,_,_,_,_),ident)
|
||||
pub method_field_extractor!(method_generics,&'a ast::Generics,
|
||||
MethDecl(_,ref generics,_,_,_,_,_),generics)
|
||||
pub method_field_extractor!(method_explicit_self,&'a ast::ExplicitSelf,
|
||||
MethDecl(_,_,ref explicit_self,_,_,_,_),explicit_self)
|
||||
pub method_field_extractor!(method_fn_style,ast::FnStyle,MethDecl(_,_,_,fn_style,_,_,_),fn_style)
|
||||
pub method_field_extractor!(method_fn_decl,P<ast::FnDecl>,MethDecl(_,_,_,_,decl,_,_),decl)
|
||||
pub method_field_extractor!(method_body,P<ast::Block>,MethDecl(_,_,_,_,_,body,_),body)
|
||||
pub method_field_extractor!(method_vis,ast::Visibility,MethDecl(_,_,_,_,_,_,vis),vis)
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use ast::*;
|
||||
@ -765,3 +799,4 @@ fn ident_to_segment(id : &Ident) -> PathSegment {
|
||||
.iter().map(ident_to_segment).collect::<Vec<PathSegment>>().as_slice()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -648,16 +648,16 @@ fn create_method(&self,
|
||||
|
||||
// Create the method.
|
||||
box(GC) ast::Method {
|
||||
ident: method_ident,
|
||||
attrs: self.attributes.clone(),
|
||||
generics: fn_generics,
|
||||
explicit_self: explicit_self,
|
||||
fn_style: ast::NormalFn,
|
||||
decl: fn_decl,
|
||||
body: body_block,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: trait_.span,
|
||||
vis: ast::Inherited,
|
||||
node: ast::MethDecl(method_ident,
|
||||
fn_generics,
|
||||
explicit_self,
|
||||
ast::NormalFn,
|
||||
fn_decl,
|
||||
body_block,
|
||||
ast::Inherited)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -941,21 +941,25 @@ fn fold_mac(&mut self, macro: &ast::Mac) -> ast::Mac {
|
||||
// expand a method
|
||||
fn expand_method(m: &ast::Method, fld: &mut MacroExpander) -> Gc<ast::Method> {
|
||||
let id = fld.new_id(m.id);
|
||||
let (rewritten_fn_decl, rewritten_body)
|
||||
= expand_and_rename_fn_decl_and_block(m.decl,m.body,fld);
|
||||
|
||||
// all of the other standard stuff:
|
||||
box(GC) ast::Method {
|
||||
id: id,
|
||||
ident: fld.fold_ident(m.ident),
|
||||
attrs: m.attrs.iter().map(|a| fld.fold_attribute(*a)).collect(),
|
||||
generics: fold_generics(&m.generics, fld),
|
||||
explicit_self: fld.fold_explicit_self(&m.explicit_self),
|
||||
fn_style: m.fn_style,
|
||||
decl: rewritten_fn_decl,
|
||||
body: rewritten_body,
|
||||
id: id,
|
||||
span: fld.new_span(m.span),
|
||||
vis: m.vis
|
||||
node: match m.node {
|
||||
ast::MethDecl(ident, ref generics, ref explicit_self, fn_style, decl, body, vis) => {
|
||||
let (rewritten_fn_decl, rewritten_body)
|
||||
= expand_and_rename_fn_decl_and_block(decl,body,fld);
|
||||
|
||||
ast::MethDecl(fld.fold_ident(ident),
|
||||
fold_generics(generics, fld),
|
||||
fld.fold_explicit_self(explicit_self),
|
||||
fn_style,
|
||||
rewritten_fn_decl,
|
||||
rewritten_body,
|
||||
vis)
|
||||
},
|
||||
ast::MethMac(ref _mac) => fail!("expansion in method position not implemented yet!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -794,16 +794,21 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: &ForeignItem,
|
||||
pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> Gc<Method> {
|
||||
let id = folder.new_id(m.id); // Needs to be first, for ast_map.
|
||||
box(GC) Method {
|
||||
id: id,
|
||||
ident: folder.fold_ident(m.ident),
|
||||
attrs: m.attrs.iter().map(|a| folder.fold_attribute(*a)).collect(),
|
||||
generics: fold_generics(&m.generics, folder),
|
||||
explicit_self: folder.fold_explicit_self(&m.explicit_self),
|
||||
fn_style: m.fn_style,
|
||||
decl: folder.fold_fn_decl(&*m.decl),
|
||||
body: folder.fold_block(m.body),
|
||||
id: id,
|
||||
span: folder.new_span(m.span),
|
||||
vis: m.vis
|
||||
node: match m.node {
|
||||
MethDecl(ident, ref generics, ref explicit_self, fn_style, decl, body, vis) => {
|
||||
MethDecl(folder.fold_ident(ident),
|
||||
fold_generics(generics, folder),
|
||||
folder.fold_explicit_self(explicit_self),
|
||||
fn_style,
|
||||
folder.fold_fn_decl(&*decl),
|
||||
folder.fold_block(body),
|
||||
vis)
|
||||
},
|
||||
MethMac(ref mac) => MethMac(folder.fold_mac(mac)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1249,16 +1249,10 @@ pub fn parse_trait_methods(&mut self) -> Vec<TraitMethod> {
|
||||
p.parse_inner_attrs_and_block();
|
||||
let attrs = attrs.append(inner_attrs.as_slice());
|
||||
Provided(box(GC) ast::Method {
|
||||
ident: ident,
|
||||
attrs: attrs,
|
||||
generics: generics,
|
||||
explicit_self: explicit_self,
|
||||
fn_style: style,
|
||||
decl: d,
|
||||
body: body,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: mk_sp(lo, hi),
|
||||
vis: vis,
|
||||
node: ast::MethDecl(ident, generics, explicit_self, style, d, body, vis)
|
||||
})
|
||||
}
|
||||
|
||||
@ -4049,16 +4043,10 @@ fn parse_method(&mut self,
|
||||
let hi = body.span.hi;
|
||||
let attrs = attrs.append(inner_attrs.as_slice());
|
||||
box(GC) ast::Method {
|
||||
ident: ident,
|
||||
attrs: attrs,
|
||||
generics: generics,
|
||||
explicit_self: explicit_self,
|
||||
fn_style: fn_style,
|
||||
decl: decl,
|
||||
body: body,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: mk_sp(lo, hi),
|
||||
vis: visa,
|
||||
node: ast::MethDecl(ident, generics, explicit_self, fn_style, decl, body, visa),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,6 +245,10 @@ pub fn arg_to_string(arg: &ast::Arg) -> String {
|
||||
to_string(|s| s.print_arg(arg))
|
||||
}
|
||||
|
||||
pub fn mac_to_string(arg: &ast::Mac) -> String {
|
||||
to_string(|s| s.print_mac(arg))
|
||||
}
|
||||
|
||||
pub fn visibility_qualified(vis: ast::Visibility, s: &str) -> String {
|
||||
match vis {
|
||||
ast::Public => format!("pub {}", s),
|
||||
@ -342,6 +346,7 @@ pub fn is_end(&mut self) -> bool {
|
||||
match self.s.last_token() { pp::End => true, _ => false }
|
||||
}
|
||||
|
||||
// is this the beginning of a line?
|
||||
pub fn is_bol(&mut self) -> bool {
|
||||
self.s.last_token().is_eof() || self.s.last_token().is_hardbreak_tok()
|
||||
}
|
||||
@ -627,6 +632,7 @@ pub fn print_foreign_item(&mut self,
|
||||
}
|
||||
}
|
||||
|
||||
/// Pretty-print an item
|
||||
pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
|
||||
try!(self.hardbreak_if_not_bol());
|
||||
try!(self.maybe_print_comment(item.span.lo));
|
||||
@ -998,11 +1004,26 @@ pub fn print_method(&mut self, meth: &ast::Method) -> IoResult<()> {
|
||||
try!(self.hardbreak_if_not_bol());
|
||||
try!(self.maybe_print_comment(meth.span.lo));
|
||||
try!(self.print_outer_attributes(meth.attrs.as_slice()));
|
||||
try!(self.print_fn(&*meth.decl, Some(meth.fn_style), abi::Rust,
|
||||
meth.ident, &meth.generics, Some(meth.explicit_self.node),
|
||||
meth.vis));
|
||||
try!(word(&mut self.s, " "));
|
||||
self.print_block_with_attrs(&*meth.body, meth.attrs.as_slice())
|
||||
match meth.node {
|
||||
ast::MethDecl(ident, ref generics, ref explicit_self, fn_style, decl, body, vis) => {
|
||||
try!(self.print_fn(&*decl, Some(fn_style), abi::Rust,
|
||||
ident, generics, Some(explicit_self.node),
|
||||
vis));
|
||||
try!(word(&mut self.s, " "));
|
||||
self.print_block_with_attrs(&*body, meth.attrs.as_slice())
|
||||
},
|
||||
ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
|
||||
..}) => {
|
||||
// code copied from ItemMac:
|
||||
try!(self.print_path(pth, false));
|
||||
try!(word(&mut self.s, "! "));
|
||||
try!(self.cbox(indent_unit));
|
||||
try!(self.popen());
|
||||
try!(self.print_tts(tts.as_slice()));
|
||||
try!(self.pclose());
|
||||
self.end()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_outer_attributes(&mut self,
|
||||
|
@ -560,15 +560,21 @@ pub fn walk_fn_decl<E: Clone, V: Visitor<E>>(visitor: &mut V,
|
||||
pub fn walk_method_helper<E: Clone, V: Visitor<E>>(visitor: &mut V,
|
||||
method: &Method,
|
||||
env: E) {
|
||||
visitor.visit_ident(method.span, method.ident, env.clone());
|
||||
visitor.visit_fn(&FkMethod(method.ident, &method.generics, method),
|
||||
&*method.decl,
|
||||
&*method.body,
|
||||
method.span,
|
||||
method.id,
|
||||
env.clone());
|
||||
for attr in method.attrs.iter() {
|
||||
visitor.visit_attribute(attr, env.clone());
|
||||
match method.node {
|
||||
MethDecl(ident, ref generics, _, _, decl, body, _) => {
|
||||
visitor.visit_ident(method.span, ident, env.clone());
|
||||
visitor.visit_fn(&FkMethod(ident, generics, method),
|
||||
decl,
|
||||
body,
|
||||
method.span,
|
||||
method.id,
|
||||
env.clone());
|
||||
for attr in method.attrs.iter() {
|
||||
visitor.visit_attribute(attr, env.clone());
|
||||
}
|
||||
|
||||
},
|
||||
MethMac(ref mac) => visitor.visit_mac(mac, env.clone())
|
||||
}
|
||||
}
|
||||
|
||||
@ -586,8 +592,12 @@ pub fn walk_fn<E: Clone, V: Visitor<E>>(visitor: &mut V,
|
||||
}
|
||||
FkMethod(_, generics, method) => {
|
||||
visitor.visit_generics(generics, env.clone());
|
||||
|
||||
visitor.visit_explicit_self(&method.explicit_self, env.clone());
|
||||
match method.node {
|
||||
MethDecl(_, _, ref explicit_self, _, _, _, _) =>
|
||||
visitor.visit_explicit_self(explicit_self, env.clone()),
|
||||
MethMac(ref mac) =>
|
||||
visitor.visit_mac(mac, env.clone())
|
||||
}
|
||||
}
|
||||
FkFnBlock(..) => {}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user