Skip to content

Commit fca5255

Browse files
paulstansifergraydon
authored andcommitted
Make it possible to invoke item macros without passing identifier arguments.
1 parent cafea5e commit fca5255

File tree

4 files changed

+55
-33
lines changed

4 files changed

+55
-33
lines changed

src/libsyntax/ext/base.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use ast_util::dummy_sp;
1212
// new-style macro! tt code:
1313
//
1414
// syntax_expander_tt, syntax_expander_tt_item, mac_result,
15-
// expr_tt, item_tt
15+
// normal_tt, item_tt
1616
//
1717
// also note that ast::mac has way too many cases and can probably
1818
// be trimmed down substantially.
@@ -60,7 +60,10 @@ enum syntax_extension {
6060
item_decorator(item_decorator),
6161

6262
// Token-tree expanders
63-
expr_tt(syntax_expander_tt),
63+
normal_tt(syntax_expander_tt),
64+
65+
// perhaps macro_rules! will lose its odd special identifier argument,
66+
// and this can go away also
6467
item_tt(syntax_expander_tt_item),
6568
}
6669

@@ -69,8 +72,8 @@ enum syntax_extension {
6972
fn syntax_expander_table() -> HashMap<~str, syntax_extension> {
7073
fn builtin(f: syntax_expander_) -> syntax_extension
7174
{normal({expander: f, span: None})}
72-
fn builtin_expr_tt(f: syntax_expander_tt_) -> syntax_extension {
73-
expr_tt({expander: f, span: None})
75+
fn builtin_normal_tt(f: syntax_expander_tt_) -> syntax_extension {
76+
normal_tt({expander: f, span: None})
7477
}
7578
fn builtin_item_tt(f: syntax_expander_tt_item_) -> syntax_extension {
7679
item_tt({expander: f, span: None})
@@ -94,7 +97,7 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> {
9497
syntax_expanders.insert(~"ident_to_str",
9598
builtin(ext::ident_to_str::expand_syntax_ext));
9699
syntax_expanders.insert(~"log_syntax",
97-
builtin_expr_tt(
100+
builtin_normal_tt(
98101
ext::log_syntax::expand_syntax_ext));
99102
syntax_expanders.insert(~"ast",
100103
builtin(ext::qquote::expand_ast));
@@ -139,7 +142,7 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> {
139142
builtin_item_tt(ext::pipes::expand_proto));
140143
syntax_expanders.insert(
141144
~"trace_macros",
142-
builtin_expr_tt(ext::trace_macros::expand_trace_macros));
145+
builtin_normal_tt(ext::trace_macros::expand_trace_macros));
143146
return syntax_expanders;
144147
}
145148

src/libsyntax/ext/expand.rs

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ fn expand_expr(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt,
5454
exts.insert(named_extension.name, named_extension.ext);
5555
(ast::expr_rec(~[], None), s)
5656
}
57-
Some(expr_tt(_)) => {
57+
Some(normal_tt(_)) => {
5858
cx.span_fatal(pth.span,
5959
fmt!("this tt-style macro should be \
6060
invoked '%s!(...)'", *extname))
@@ -78,7 +78,7 @@ fn expand_expr(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt,
7878
cx.span_fatal(pth.span,
7979
fmt!("macro undefined: '%s'", *extname))
8080
}
81-
Some(expr_tt({expander: exp, span: exp_sp})) => {
81+
Some(normal_tt({expander: exp, span: exp_sp})) => {
8282
let expanded = match exp(cx, mac.span, tts) {
8383
mr_expr(e) => e,
8484
mr_expr_or_item(expr_maker,_) => expr_maker(),
@@ -153,7 +153,7 @@ fn expand_mod_items(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt,
153153
};
154154
match exts.find(mname) {
155155
None | Some(normal(_)) | Some(macro_defining(_))
156-
| Some(expr_tt(_)) | Some(item_tt(*)) => items,
156+
| Some(normal_tt(_)) | Some(item_tt(*)) => items,
157157
Some(item_decorator(dec_fn)) => {
158158
dec_fn(cx, attr.span, attr.node.value, items)
159159
}
@@ -200,34 +200,49 @@ fn expand_item_mac(exts: HashMap<~str, syntax_extension>,
200200
match it.node {
201201
item_mac({node: mac_invoc_tt(pth, tts), _}) => {
202202
let extname = cx.parse_sess().interner.get(pth.idents[0]);
203-
match exts.find(*extname) {
203+
let (expanded, ex_span) = match exts.find(*extname) {
204204
None => {
205205
cx.span_fatal(pth.span,
206-
fmt!("macro undefined: '%s'", *extname))
206+
fmt!("macro undefined: '%s!'", *extname))
207+
}
208+
Some(normal_tt(expand)) => {
209+
if it.ident != parse::token::special_idents::invalid {
210+
cx.span_fatal(pth.span,
211+
fmt!("macro %s! expects no ident argument, \
212+
given '%s'", *extname,
213+
*cx.parse_sess().interner.get(it.ident)));
214+
}
215+
(expand.expander(cx, it.span, tts), expand.span)
207216
}
208217
Some(item_tt(expand)) => {
209-
let expanded = expand.expander(cx, it.span, it.ident, tts);
210-
cx.bt_push(ExpandedFrom({call_site: it.span,
211-
callie: {name: *extname,
212-
span: expand.span}}));
213-
let maybe_it = match expanded {
214-
mr_item(it) => fld.fold_item(it),
215-
mr_expr(_) => cx.span_fatal(pth.span,
216-
~"expr macro in item position: " +
217-
*extname),
218-
mr_expr_or_item(_, item_maker) =>
219-
option::chain(item_maker(), |i| {fld.fold_item(i)}),
220-
mr_def(mdef) => {
221-
exts.insert(mdef.name, mdef.ext);
222-
None
223-
}
224-
};
225-
cx.bt_pop();
226-
return maybe_it
218+
if it.ident == parse::token::special_idents::invalid {
219+
cx.span_fatal(pth.span,
220+
fmt!("macro %s! expects an ident argument",
221+
*extname));
222+
}
223+
(expand.expander(cx, it.span, it.ident, tts), expand.span)
227224
}
228225
_ => cx.span_fatal(
229226
it.span, fmt!("%s! is not legal in item position", *extname))
230-
}
227+
};
228+
229+
cx.bt_push(ExpandedFrom({call_site: it.span,
230+
callie: {name: *extname,
231+
span: ex_span}}));
232+
let maybe_it = match expanded {
233+
mr_item(it) => fld.fold_item(it),
234+
mr_expr(_) => cx.span_fatal(pth.span,
235+
~"expr macro in item position: " +
236+
*extname),
237+
mr_expr_or_item(_, item_maker) =>
238+
option::chain(item_maker(), |i| {fld.fold_item(i)}),
239+
mr_def(mdef) => {
240+
exts.insert(mdef.name, mdef.ext);
241+
None
242+
}
243+
};
244+
cx.bt_pop();
245+
return maybe_it;
231246
}
232247
_ => cx.span_bug(it.span, ~"invalid item macro invocation")
233248
}

src/libsyntax/ext/tt/macro_rules.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use base::{ext_ctxt, mac_result, mr_expr_or_item, mr_def, expr_tt};
1+
use base::{ext_ctxt, mac_result, mr_expr_or_item, mr_def, normal_tt};
22
use codemap::span;
33
use ast::{ident, matcher_, matcher, match_tok,
44
match_nonterminal, match_seq, tt_delim};
@@ -113,6 +113,6 @@ fn add_new_extension(cx: ext_ctxt, sp: span, name: ident,
113113

114114
return mr_def({
115115
name: *cx.parse_sess().interner.get(name),
116-
ext: expr_tt({expander: exp, span: Some(sp)})
116+
ext: normal_tt({expander: exp, span: Some(sp)})
117117
});
118118
}

src/libsyntax/parse/parser.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3534,7 +3534,11 @@ impl Parser {
35343534
// item macro.
35353535
let pth = self.parse_path_without_tps();
35363536
self.expect(token::NOT);
3537-
let id = self.parse_ident();
3537+
let id = if self.token == token::LPAREN {
3538+
token::special_idents::invalid // no special identifier
3539+
} else {
3540+
self.parse_ident()
3541+
};
35383542
let tts = match self.token {
35393543
token::LPAREN | token::LBRACE => {
35403544
let ket = token::flip_delimiter(copy self.token);

0 commit comments

Comments
 (0)