Skip to content

Commit 7a6208f

Browse files
committed
auto merge of #15646 : jbclements/rust/method-macros, r=cmr
This patch adds support for macros in method position. It follows roughly the template for Item macros, where an outer `Method` wrapper contains a `Method_` enum which can either be a macro invocation or a standard macro definition. One note; adding support for macros that expand into multiple methods is not included here, but should be a simple parser change, since this patch updates the type of fold_macro to return a smallvector of methods. For reviewers, please pay special attention to the parser changes; these are the ones I'm most concerned about. Because of the small change to the interface of fold_method, this is a ... [breaking change]
2 parents fbeee04 + aee5917 commit 7a6208f

File tree

28 files changed

+561
-359
lines changed

28 files changed

+561
-359
lines changed

src/librustc/metadata/encoder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@ fn encode_info_for_method(ecx: &EncodeContext,
799799
} else {
800800
encode_symbol(ecx, ebml_w, m.def_id.node);
801801
}
802-
encode_method_argument_names(ebml_w, &*ast_method.decl);
802+
encode_method_argument_names(ebml_w, method_fn_decl(&*ast_method));
803803
}
804804

805805
ebml_w.end_tag();
@@ -1241,7 +1241,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
12411241
encode_method_sort(ebml_w, 'p');
12421242
encode_inlined_item(ecx, ebml_w,
12431243
IIMethodRef(def_id, true, &*m));
1244-
encode_method_argument_names(ebml_w, &*m.decl);
1244+
encode_method_argument_names(ebml_w, method_fn_decl(m));
12451245
}
12461246
}
12471247

src/librustc/middle/astencode.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ pub fn decode_inlined_item(cdata: &cstore::crate_metadata,
136136
let ident = match ii {
137137
ast::IIItem(i) => i.ident,
138138
ast::IIForeign(i) => i.ident,
139-
ast::IIMethod(_, _, m) => m.ident,
139+
ast::IIMethod(_, _, m) => ast_util::method_ident(&*m),
140140
};
141141
debug!("Fn named: {}", token::get_ident(ident));
142142
debug!("< Decoded inlined fn: {}::{}",
@@ -345,7 +345,9 @@ fn simplify_ast(ii: e::InlinedItemRef) -> ast::InlinedItem {
345345
// HACK we're not dropping items.
346346
e::IIItemRef(i) => ast::IIItem(fold::noop_fold_item(i, &mut fld)
347347
.expect_one("expected one item")),
348-
e::IIMethodRef(d, p, m) => ast::IIMethod(d, p, fold::noop_fold_method(m, &mut fld)),
348+
e::IIMethodRef(d, p, m) => ast::IIMethod(d, p, fold::noop_fold_method(m, &mut fld)
349+
.expect_one(
350+
"noop_fold_method must produce exactly one method")),
349351
e::IIForeignRef(i) => ast::IIForeign(fold::noop_fold_foreign_item(i, &mut fld))
350352
}
351353
}
@@ -387,7 +389,8 @@ fn renumber_and_map_ast(xcx: &ExtendedDecodeContext,
387389
ast::IIItem(fld.fold_item(i).expect_one("expected one item"))
388390
}
389391
ast::IIMethod(d, is_provided, m) => {
390-
ast::IIMethod(xcx.tr_def_id(d), is_provided, fld.fold_method(m))
392+
ast::IIMethod(xcx.tr_def_id(d), is_provided, fld.fold_method(m)
393+
.expect_one("expected one method"))
391394
}
392395
ast::IIForeign(i) => ast::IIForeign(fld.fold_foreign_item(i))
393396
}

src/librustc/middle/dead.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use util::nodemap::NodeSet;
2222
use std::collections::HashSet;
2323
use syntax::ast;
2424
use syntax::ast_map;
25+
use syntax::ast_util;
2526
use syntax::ast_util::{local_def, is_local};
2627
use syntax::attr::AttrMetaMethods;
2728
use syntax::attr;
@@ -212,7 +213,7 @@ impl<'a> MarkSymbolVisitor<'a> {
212213
visit::walk_trait_method(self, &*trait_method, ctxt);
213214
}
214215
ast_map::NodeMethod(method) => {
215-
visit::walk_block(self, &*method.body, ctxt);
216+
visit::walk_block(self, ast_util::method_body(&*method), ctxt);
216217
}
217218
ast_map::NodeForeignItem(foreign_item) => {
218219
visit::walk_foreign_item(self, &*foreign_item, ctxt);
@@ -520,7 +521,8 @@ impl<'a> Visitor<()> for DeadVisitor<'a> {
520521
// Overwrite so that we don't warn the trait method itself.
521522
fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
522523
match *trait_method {
523-
ast::Provided(ref method) => visit::walk_block(self, &*method.body, ()),
524+
ast::Provided(ref method) => visit::walk_block(self,
525+
ast_util::method_body(&**method), ()),
524526
ast::Required(_) => ()
525527
}
526528
}

src/librustc/middle/effect.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use middle::typeck::MethodCall;
1717
use util::ppaux;
1818

1919
use syntax::ast;
20+
use syntax::ast_util;
2021
use syntax::codemap::Span;
2122
use syntax::visit;
2223
use syntax::visit::Visitor;
@@ -94,7 +95,7 @@ impl<'a> Visitor<()> for EffectCheckVisitor<'a> {
9495
visit::FkItemFn(_, _, fn_style, _) =>
9596
(true, fn_style == ast::UnsafeFn),
9697
visit::FkMethod(_, _, method) =>
97-
(true, method.fn_style == ast::UnsafeFn),
98+
(true, ast_util::method_fn_style(method) == ast::UnsafeFn),
9899
_ => (false, false),
99100
};
100101

src/librustc/middle/privacy.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use util::nodemap::{NodeMap, NodeSet};
2626

2727
use syntax::ast;
2828
use syntax::ast_map;
29+
use syntax::ast_util;
2930
use syntax::ast_util::{is_local, local_def};
3031
use syntax::attr;
3132
use syntax::codemap::Span;
@@ -263,10 +264,10 @@ impl<'a> Visitor<()> for EmbargoVisitor<'a> {
263264

264265
if public_ty || public_trait {
265266
for method in methods.iter() {
266-
let meth_public = match method.explicit_self.node {
267+
let meth_public = match ast_util::method_explicit_self(&**method).node {
267268
ast::SelfStatic => public_ty,
268269
_ => true,
269-
} && method.vis == ast::Public;
270+
} && ast_util::method_vis(&**method) == ast::Public;
270271
if meth_public || tr.is_some() {
271272
self.exported_items.insert(method.id);
272273
}
@@ -456,8 +457,8 @@ impl<'a> PrivacyVisitor<'a> {
456457
let imp = self.tcx.map.get_parent_did(closest_private_id);
457458
match ty::impl_trait_ref(self.tcx, imp) {
458459
Some(..) => return Allowable,
459-
_ if m.vis == ast::Public => return Allowable,
460-
_ => m.vis
460+
_ if ast_util::method_vis(&**m) == ast::Public => return Allowable,
461+
_ => ast_util::method_vis(&**m)
461462
}
462463
}
463464
Some(ast_map::NodeTraitMethod(_)) => {
@@ -1078,7 +1079,7 @@ impl<'a> SanePrivacyVisitor<'a> {
10781079
"visibility qualifiers have no effect on trait \
10791080
impls");
10801081
for m in methods.iter() {
1081-
check_inherited(m.span, m.vis, "");
1082+
check_inherited(m.span, ast_util::method_vis(&**m), "");
10821083
}
10831084
}
10841085

@@ -1110,7 +1111,7 @@ impl<'a> SanePrivacyVisitor<'a> {
11101111
for m in methods.iter() {
11111112
match *m {
11121113
ast::Provided(ref m) => {
1113-
check_inherited(m.span, m.vis,
1114+
check_inherited(m.span, ast_util::method_vis(&**m),
11141115
"unnecessary visibility");
11151116
}
11161117
ast::Required(ref m) => {
@@ -1148,7 +1149,7 @@ impl<'a> SanePrivacyVisitor<'a> {
11481149
match item.node {
11491150
ast::ItemImpl(_, _, _, ref methods) => {
11501151
for m in methods.iter() {
1151-
check_inherited(tcx, m.span, m.vis);
1152+
check_inherited(tcx, m.span, ast_util::method_vis(&**m));
11521153
}
11531154
}
11541155
ast::ItemForeignMod(ref fm) => {
@@ -1174,7 +1175,7 @@ impl<'a> SanePrivacyVisitor<'a> {
11741175
match *m {
11751176
ast::Required(..) => {}
11761177
ast::Provided(ref m) => check_inherited(tcx, m.span,
1177-
m.vis),
1178+
ast_util::method_vis(&**m)),
11781179
}
11791180
}
11801181
}
@@ -1344,7 +1345,7 @@ impl<'a> Visitor<()> for VisiblePrivateTypesVisitor<'a> {
13441345
// methods will be visible as `Public::foo`.
13451346
let mut found_pub_static = false;
13461347
for method in methods.iter() {
1347-
if method.explicit_self.node == ast::SelfStatic &&
1348+
if ast_util::method_explicit_self(&**method).node == ast::SelfStatic &&
13481349
self.exported_items.contains(&method.id) {
13491350
found_pub_static = true;
13501351
visit::walk_method_helper(self, &**method, ());

src/librustc/middle/reachable.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ fn item_might_be_inlined(item: &ast::Item) -> bool {
6868
fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method,
6969
impl_src: ast::DefId) -> bool {
7070
if attributes_specify_inlining(method.attrs.as_slice()) ||
71-
generics_require_inlining(&method.generics) {
71+
generics_require_inlining(ast_util::method_generics(&*method)) {
7272
return true
7373
}
7474
if is_local(impl_src) {
@@ -200,7 +200,7 @@ impl<'a> ReachableContext<'a> {
200200
}
201201
}
202202
Some(ast_map::NodeMethod(method)) => {
203-
if generics_require_inlining(&method.generics) ||
203+
if generics_require_inlining(ast_util::method_generics(&*method)) ||
204204
attributes_specify_inlining(method.attrs.as_slice()) {
205205
true
206206
} else {
@@ -316,14 +316,14 @@ impl<'a> ReachableContext<'a> {
316316
// Keep going, nothing to get exported
317317
}
318318
ast::Provided(ref method) => {
319-
visit::walk_block(self, &*method.body, ())
319+
visit::walk_block(self, ast_util::method_body(&**method), ())
320320
}
321321
}
322322
}
323323
ast_map::NodeMethod(method) => {
324324
let did = self.tcx.map.get_parent_did(search_item);
325325
if method_might_be_inlined(self.tcx, &*method, did) {
326-
visit::walk_block(self, &*method.body, ())
326+
visit::walk_block(self, ast_util::method_body(&*method), ())
327327
}
328328
}
329329
// Nothing to recurse on for these

src/librustc/middle/resolve.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use util::nodemap::{NodeMap, DefIdSet, FnvHashMap};
2222

2323
use syntax::ast::*;
2424
use syntax::ast;
25+
use syntax::ast_util;
2526
use syntax::ast_util::{local_def};
2627
use syntax::ast_util::{walk_pat, trait_method_to_ty_method};
2728
use syntax::ext::mtwt;
@@ -1298,20 +1299,20 @@ impl<'a> Resolver<'a> {
12981299
// For each method...
12991300
for method in methods.iter() {
13001301
// Add the method to the module.
1301-
let ident = method.ident;
1302+
let ident = ast_util::method_ident(&**method);
13021303
let method_name_bindings =
13031304
self.add_child(ident,
13041305
new_parent.clone(),
13051306
ForbidDuplicateValues,
13061307
method.span);
1307-
let def = match method.explicit_self.node {
1308+
let def = match ast_util::method_explicit_self(&**method).node {
13081309
SelfStatic => {
13091310
// Static methods become
13101311
// `def_static_method`s.
13111312
DefStaticMethod(local_def(method.id),
13121313
FromImpl(local_def(
13131314
item.id)),
1314-
method.fn_style)
1315+
ast_util::method_fn_style(&**method))
13151316
}
13161317
_ => {
13171318
// Non-static methods become
@@ -1320,7 +1321,7 @@ impl<'a> Resolver<'a> {
13201321
}
13211322
};
13221323

1323-
let is_public = method.vis == ast::Public;
1324+
let is_public = ast_util::method_vis(&**method) == ast::Public;
13241325
method_name_bindings.define_value(def,
13251326
method.span,
13261327
is_public);
@@ -4003,13 +4004,15 @@ impl<'a> Resolver<'a> {
40034004
fn resolve_method(&mut self,
40044005
rib_kind: RibKind,
40054006
method: &Method) {
4006-
let method_generics = &method.generics;
4007+
let method_generics = ast_util::method_generics(method);
40074008
let type_parameters = HasTypeParameters(method_generics,
40084009
FnSpace,
40094010
method.id,
40104011
rib_kind);
40114012

4012-
self.resolve_function(rib_kind, Some(method.decl), type_parameters, method.body);
4013+
self.resolve_function(rib_kind, Some(ast_util::method_fn_decl(method)),
4014+
type_parameters,
4015+
ast_util::method_body(method));
40134016
}
40144017

40154018
fn with_current_self_type<T>(&mut self, self_type: &Ty, f: |&mut Resolver| -> T) -> T {
@@ -4080,7 +4083,7 @@ impl<'a> Resolver<'a> {
40804083
fn check_trait_method(&self, method: &Method) {
40814084
// If there is a TraitRef in scope for an impl, then the method must be in the trait.
40824085
for &(did, ref trait_ref) in self.current_trait_ref.iter() {
4083-
let method_name = method.ident.name;
4086+
let method_name = ast_util::method_ident(method).name;
40844087

40854088
if self.method_map.borrow().find(&(method_name, did)).is_none() {
40864089
let path_str = self.path_idents_to_string(&trait_ref.path);

src/librustc/middle/save/mod.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ impl <'l> DxrVisitor<'l> {
333333
},
334334
};
335335

336-
qualname.push_str(get_ident(method.ident).get());
336+
qualname.push_str(get_ident(ast_util::method_ident(&*method)).get());
337337
let qualname = qualname.as_slice();
338338

339339
// record the decl for this def (if it has one)
@@ -349,17 +349,18 @@ impl <'l> DxrVisitor<'l> {
349349
decl_id,
350350
scope_id);
351351

352-
self.process_formals(&method.decl.inputs, qualname, e);
352+
let m_decl = ast_util::method_fn_decl(&*method);
353+
self.process_formals(&m_decl.inputs, qualname, e);
353354

354355
// walk arg and return types
355-
for arg in method.decl.inputs.iter() {
356+
for arg in m_decl.inputs.iter() {
356357
self.visit_ty(&*arg.ty, e);
357358
}
358-
self.visit_ty(&*method.decl.output, e);
359+
self.visit_ty(m_decl.output, e);
359360
// walk the fn body
360-
self.visit_block(&*method.body, DxrVisitorEnv::new_nested(method.id));
361+
self.visit_block(ast_util::method_body(&*method), DxrVisitorEnv::new_nested(method.id));
361362

362-
self.process_generic_params(&method.generics,
363+
self.process_generic_params(ast_util::method_generics(&*method),
363364
method.span,
364365
qualname,
365366
method.id,

src/librustc/middle/trans/debuginfo.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,10 +1138,10 @@ pub fn create_function_debug_context(cx: &CrateContext,
11381138
}
11391139
}
11401140
ast_map::NodeMethod(ref method) => {
1141-
(method.ident,
1142-
method.decl,
1143-
&method.generics,
1144-
method.body,
1141+
(ast_util::method_ident(&**method),
1142+
ast_util::method_fn_decl(&**method),
1143+
ast_util::method_generics(&**method),
1144+
ast_util::method_body(&**method),
11451145
method.span,
11461146
true)
11471147
}
@@ -1167,10 +1167,10 @@ pub fn create_function_debug_context(cx: &CrateContext,
11671167
ast_map::NodeTraitMethod(ref trait_method) => {
11681168
match **trait_method {
11691169
ast::Provided(ref method) => {
1170-
(method.ident,
1171-
method.decl,
1172-
&method.generics,
1173-
method.body,
1170+
(ast_util::method_ident(&**method),
1171+
ast_util::method_fn_decl(&**method),
1172+
ast_util::method_generics(&**method),
1173+
ast_util::method_body(&**method),
11741174
method.span,
11751175
true)
11761176
}

src/librustc/middle/trans/inline.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,12 @@ pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
128128
let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did);
129129
let unparameterized =
130130
impl_tpt.generics.types.is_empty() &&
131-
mth.generics.ty_params.is_empty();
131+
ast_util::method_generics(&*mth).ty_params.is_empty();
132132

133133
if unparameterized {
134134
let llfn = get_item_val(ccx, mth.id);
135-
trans_fn(ccx, &*mth.decl, &*mth.body, llfn,
135+
trans_fn(ccx, ast_util::method_fn_decl(&*mth),
136+
ast_util::method_body(&*mth), llfn,
136137
&param_substs::empty(), mth.id, []);
137138
}
138139
local_def(mth.id)

src/librustc/middle/trans/meth.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use std::c_str::ToCStr;
3838
use std::gc::Gc;
3939
use syntax::abi::Rust;
4040
use syntax::parse::token;
41-
use syntax::{ast, ast_map, visit};
41+
use syntax::{ast, ast_map, visit, ast_util};
4242

4343
/**
4444
The main "translation" pass for methods. Generates code
@@ -66,9 +66,10 @@ pub fn trans_impl(ccx: &CrateContext,
6666
return;
6767
}
6868
for method in methods.iter() {
69-
if method.generics.ty_params.len() == 0u {
69+
if ast_util::method_generics(&**method).ty_params.len() == 0u {
7070
let llfn = get_item_val(ccx, method.id);
71-
trans_fn(ccx, &*method.decl, &*method.body,
71+
trans_fn(ccx, ast_util::method_fn_decl(&**method),
72+
ast_util::method_body(&**method),
7273
llfn, &param_substs::empty(), method.id, []);
7374
} else {
7475
let mut v = TransItemVisitor{ ccx: ccx };
@@ -160,7 +161,7 @@ pub fn trans_static_method_callee(bcx: &Block,
160161
ast_map::NodeTraitMethod(method) => {
161162
let ident = match *method {
162163
ast::Required(ref m) => m.ident,
163-
ast::Provided(ref m) => m.ident
164+
ast::Provided(ref m) => ast_util::method_ident(&**m)
164165
};
165166
ident.name
166167
}

0 commit comments

Comments
 (0)