Skip to content

Commit 64963d6

Browse files
committed
auto merge of #6611 : huonw/rust/syntax-ext-no-dup, r=jbclements
Fixes #6578 by merging the 3 different ways to build an AST into a single `AstBuilder` trait, creating a more uniform and briefer interface. Also, converts the `ext_ctxt` trait-object to be a plain struct, as well as renaming it to `ExtCtxt`. Seems to make expansion slightly faster for the normal case (e.g. `libcore` and `libstd`), but slower for `librustc` (slightly) and `libsyntax` (0.3s -> 0.8s! I'm investigating this, but I'd prefer this patch to land relatively quickly.). `git blame` suggests maybe @graydon or @erickt are familiar with this area of the code. r?
2 parents 808aada + a59bec4 commit 64963d6

36 files changed

+1667
-2250
lines changed

src/librustc/front/test.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use syntax::ast_util::*;
1717
use syntax::attr;
1818
use syntax::codemap::{dummy_sp, span, ExpandedFrom, CallInfo, NameAndSpan};
1919
use syntax::codemap;
20-
use syntax::ext::base::{mk_ctxt, ext_ctxt};
20+
use syntax::ext::base::ExtCtxt;
2121
use syntax::fold;
2222
use syntax::print::pprust;
2323
use syntax::{ast, ast_util};
@@ -36,7 +36,7 @@ struct TestCtxt {
3636
sess: session::Session,
3737
crate: @ast::crate,
3838
path: ~[ast::ident],
39-
ext_cx: @ext_ctxt,
39+
ext_cx: @ExtCtxt,
4040
testfns: ~[Test]
4141
}
4242

@@ -64,7 +64,7 @@ fn generate_test_harness(sess: session::Session,
6464
let cx: @mut TestCtxt = @mut TestCtxt {
6565
sess: sess,
6666
crate: crate,
67-
ext_cx: mk_ctxt(sess.parse_sess, copy sess.opts.cfg),
67+
ext_cx: ExtCtxt::new(sess.parse_sess, copy sess.opts.cfg),
6868
path: ~[],
6969
testfns: ~[]
7070
};

src/librustpkg/util.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use std::semver;
1919
use std::term;
2020
use syntax::ast_util::*;
2121
use syntax::codemap::{dummy_sp, spanned, dummy_spanned};
22-
use syntax::ext::base::{mk_ctxt, ext_ctxt};
22+
use syntax::ext::base::ExtCtxt;
2323
use syntax::{ast, attr, codemap, diagnostic, fold};
2424
use syntax::ast::{meta_name_value, meta_list};
2525
use syntax::attr::{mk_attr};
@@ -178,7 +178,7 @@ struct ListenerFn {
178178
struct ReadyCtx {
179179
sess: session::Session,
180180
crate: @ast::crate,
181-
ext_cx: @ext_ctxt,
181+
ext_cx: @ExtCtxt,
182182
path: ~[ast::ident],
183183
fns: ~[ListenerFn]
184184
}
@@ -247,7 +247,7 @@ pub fn ready_crate(sess: session::Session,
247247
let ctx = @mut ReadyCtx {
248248
sess: sess,
249249
crate: crate,
250-
ext_cx: mk_ctxt(sess.parse_sess, copy sess.opts.cfg),
250+
ext_cx: ExtCtxt::new(sess.parse_sess, copy sess.opts.cfg),
251251
path: ~[],
252252
fns: ~[]
253253
};

src/libsyntax/ext/asm.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ fn next_state(s: State) -> Option<State> {
3737
}
3838
}
3939

40-
pub fn expand_asm(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
40+
pub fn expand_asm(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
4141
-> base::MacResult {
4242
let p = parse::new_parser_from_tts(cx.parse_sess(),
4343
cx.cfg(),

src/libsyntax/ext/auto_encode.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use codemap::span;
1515
use ext::base::*;
1616

1717
pub fn expand_auto_encode(
18-
cx: @ext_ctxt,
18+
cx: @ExtCtxt,
1919
span: span,
2020
_mitem: @ast::meta_item,
2121
in_items: ~[@ast::item]
@@ -25,7 +25,7 @@ pub fn expand_auto_encode(
2525
}
2626

2727
pub fn expand_auto_decode(
28-
cx: @ext_ctxt,
28+
cx: @ExtCtxt,
2929
span: span,
3030
_mitem: @ast::meta_item,
3131
in_items: ~[@ast::item]

src/libsyntax/ext/base.rs

+94-119
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub struct MacroDef {
3333
ext: SyntaxExtension
3434
}
3535

36-
pub type ItemDecorator = @fn(@ext_ctxt,
36+
pub type ItemDecorator = @fn(@ExtCtxt,
3737
span,
3838
@ast::meta_item,
3939
~[@ast::item])
@@ -44,7 +44,7 @@ pub struct SyntaxExpanderTT {
4444
span: Option<span>
4545
}
4646

47-
pub type SyntaxExpanderTTFun = @fn(@ext_ctxt,
47+
pub type SyntaxExpanderTTFun = @fn(@ExtCtxt,
4848
span,
4949
&[ast::token_tree])
5050
-> MacResult;
@@ -54,7 +54,7 @@ pub struct SyntaxExpanderTTItem {
5454
span: Option<span>
5555
}
5656

57-
pub type SyntaxExpanderTTItemFun = @fn(@ext_ctxt,
57+
pub type SyntaxExpanderTTItemFun = @fn(@ExtCtxt,
5858
span,
5959
ast::ident,
6060
~[ast::token_tree])
@@ -202,134 +202,109 @@ pub fn syntax_expander_table() -> SyntaxEnv {
202202
// One of these is made during expansion and incrementally updated as we go;
203203
// when a macro expansion occurs, the resulting nodes have the backtrace()
204204
// -> expn_info of their expansion context stored into their span.
205-
pub trait ext_ctxt {
206-
fn codemap(&self) -> @CodeMap;
207-
fn parse_sess(&self) -> @mut parse::ParseSess;
208-
fn cfg(&self) -> ast::crate_cfg;
209-
fn call_site(&self) -> span;
210-
fn print_backtrace(&self);
211-
fn backtrace(&self) -> Option<@ExpnInfo>;
212-
fn mod_push(&self, mod_name: ast::ident);
213-
fn mod_pop(&self);
214-
fn mod_path(&self) -> ~[ast::ident];
215-
fn bt_push(&self, ei: codemap::ExpnInfo);
216-
fn bt_pop(&self);
217-
fn span_fatal(&self, sp: span, msg: &str) -> !;
218-
fn span_err(&self, sp: span, msg: &str);
219-
fn span_warn(&self, sp: span, msg: &str);
220-
fn span_unimpl(&self, sp: span, msg: &str) -> !;
221-
fn span_bug(&self, sp: span, msg: &str) -> !;
222-
fn bug(&self, msg: &str) -> !;
223-
fn next_id(&self) -> ast::node_id;
224-
fn trace_macros(&self) -> bool;
225-
fn set_trace_macros(&self, x: bool);
226-
/* for unhygienic identifier transformation */
227-
fn str_of(&self, id: ast::ident) -> ~str;
228-
fn ident_of(&self, st: &str) -> ast::ident;
205+
pub struct ExtCtxt {
206+
parse_sess: @mut parse::ParseSess,
207+
cfg: ast::crate_cfg,
208+
backtrace: @mut Option<@ExpnInfo>,
209+
210+
// These two @mut's should really not be here,
211+
// but the self types for CtxtRepr are all wrong
212+
// and there are bugs in the code for object
213+
// types that make this hard to get right at the
214+
// moment. - nmatsakis
215+
mod_path: @mut ~[ast::ident],
216+
trace_mac: @mut bool
229217
}
230218

231-
pub fn mk_ctxt(parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg)
232-
-> @ext_ctxt {
233-
struct CtxtRepr {
234-
parse_sess: @mut parse::ParseSess,
235-
cfg: ast::crate_cfg,
236-
backtrace: @mut Option<@ExpnInfo>,
237-
238-
// These two @mut's should really not be here,
239-
// but the self types for CtxtRepr are all wrong
240-
// and there are bugs in the code for object
241-
// types that make this hard to get right at the
242-
// moment. - nmatsakis
243-
mod_path: @mut ~[ast::ident],
244-
trace_mac: @mut bool
245-
}
246-
impl ext_ctxt for CtxtRepr {
247-
fn codemap(&self) -> @CodeMap { self.parse_sess.cm }
248-
fn parse_sess(&self) -> @mut parse::ParseSess { self.parse_sess }
249-
fn cfg(&self) -> ast::crate_cfg { copy self.cfg }
250-
fn call_site(&self) -> span {
251-
match *self.backtrace {
252-
Some(@ExpandedFrom(CallInfo {call_site: cs, _})) => cs,
253-
None => self.bug("missing top span")
254-
}
219+
pub impl ExtCtxt {
220+
fn new(parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg) -> @ExtCtxt {
221+
@ExtCtxt {
222+
parse_sess: parse_sess,
223+
cfg: cfg,
224+
backtrace: @mut None,
225+
mod_path: @mut ~[],
226+
trace_mac: @mut false
227+
}
228+
}
229+
230+
fn codemap(&self) -> @CodeMap { self.parse_sess.cm }
231+
fn parse_sess(&self) -> @mut parse::ParseSess { self.parse_sess }
232+
fn cfg(&self) -> ast::crate_cfg { copy self.cfg }
233+
fn call_site(&self) -> span {
234+
match *self.backtrace {
235+
Some(@ExpandedFrom(CallInfo {call_site: cs, _})) => cs,
236+
None => self.bug("missing top span")
255237
}
256-
fn print_backtrace(&self) { }
257-
fn backtrace(&self) -> Option<@ExpnInfo> { *self.backtrace }
258-
fn mod_push(&self, i: ast::ident) { self.mod_path.push(i); }
259-
fn mod_pop(&self) { self.mod_path.pop(); }
260-
fn mod_path(&self) -> ~[ast::ident] { copy *self.mod_path }
261-
fn bt_push(&self, ei: codemap::ExpnInfo) {
262-
match ei {
263-
ExpandedFrom(CallInfo {call_site: cs, callee: ref callee}) => {
238+
}
239+
fn print_backtrace(&self) { }
240+
fn backtrace(&self) -> Option<@ExpnInfo> { *self.backtrace }
241+
fn mod_push(&self, i: ast::ident) { self.mod_path.push(i); }
242+
fn mod_pop(&self) { self.mod_path.pop(); }
243+
fn mod_path(&self) -> ~[ast::ident] { copy *self.mod_path }
244+
fn bt_push(&self, ei: codemap::ExpnInfo) {
245+
match ei {
246+
ExpandedFrom(CallInfo {call_site: cs, callee: ref callee}) => {
264247
*self.backtrace =
265248
Some(@ExpandedFrom(CallInfo {
266249
call_site: span {lo: cs.lo, hi: cs.hi,
267250
expn_info: *self.backtrace},
268251
callee: copy *callee}));
269-
}
270252
}
271253
}
272-
fn bt_pop(&self) {
273-
match *self.backtrace {
274-
Some(@ExpandedFrom(CallInfo {
275-
call_site: span {expn_info: prev, _}, _
276-
})) => {
254+
}
255+
fn bt_pop(&self) {
256+
match *self.backtrace {
257+
Some(@ExpandedFrom(
258+
CallInfo {
259+
call_site: span {expn_info: prev, _}, _
260+
})) => {
277261
*self.backtrace = prev
278-
}
279-
_ => self.bug("tried to pop without a push")
280262
}
263+
_ => self.bug("tried to pop without a push")
281264
}
282-
fn span_fatal(&self, sp: span, msg: &str) -> ! {
283-
self.print_backtrace();
284-
self.parse_sess.span_diagnostic.span_fatal(sp, msg);
285-
}
286-
fn span_err(&self, sp: span, msg: &str) {
287-
self.print_backtrace();
288-
self.parse_sess.span_diagnostic.span_err(sp, msg);
289-
}
290-
fn span_warn(&self, sp: span, msg: &str) {
291-
self.print_backtrace();
292-
self.parse_sess.span_diagnostic.span_warn(sp, msg);
293-
}
294-
fn span_unimpl(&self, sp: span, msg: &str) -> ! {
295-
self.print_backtrace();
296-
self.parse_sess.span_diagnostic.span_unimpl(sp, msg);
297-
}
298-
fn span_bug(&self, sp: span, msg: &str) -> ! {
299-
self.print_backtrace();
300-
self.parse_sess.span_diagnostic.span_bug(sp, msg);
301-
}
302-
fn bug(&self, msg: &str) -> ! {
303-
self.print_backtrace();
304-
self.parse_sess.span_diagnostic.handler().bug(msg);
305-
}
306-
fn next_id(&self) -> ast::node_id {
307-
return parse::next_node_id(self.parse_sess);
308-
}
309-
fn trace_macros(&self) -> bool {
310-
*self.trace_mac
311-
}
312-
fn set_trace_macros(&self, x: bool) {
313-
*self.trace_mac = x
314-
}
315-
fn str_of(&self, id: ast::ident) -> ~str {
316-
copy *self.parse_sess.interner.get(id)
317-
}
318-
fn ident_of(&self, st: &str) -> ast::ident {
319-
self.parse_sess.interner.intern(st)
320-
}
321265
}
322-
let imp: @CtxtRepr = @CtxtRepr {
323-
parse_sess: parse_sess,
324-
cfg: cfg,
325-
backtrace: @mut None,
326-
mod_path: @mut ~[],
327-
trace_mac: @mut false
328-
};
329-
((imp) as @ext_ctxt)
266+
fn span_fatal(&self, sp: span, msg: &str) -> ! {
267+
self.print_backtrace();
268+
self.parse_sess.span_diagnostic.span_fatal(sp, msg);
269+
}
270+
fn span_err(&self, sp: span, msg: &str) {
271+
self.print_backtrace();
272+
self.parse_sess.span_diagnostic.span_err(sp, msg);
273+
}
274+
fn span_warn(&self, sp: span, msg: &str) {
275+
self.print_backtrace();
276+
self.parse_sess.span_diagnostic.span_warn(sp, msg);
277+
}
278+
fn span_unimpl(&self, sp: span, msg: &str) -> ! {
279+
self.print_backtrace();
280+
self.parse_sess.span_diagnostic.span_unimpl(sp, msg);
281+
}
282+
fn span_bug(&self, sp: span, msg: &str) -> ! {
283+
self.print_backtrace();
284+
self.parse_sess.span_diagnostic.span_bug(sp, msg);
285+
}
286+
fn bug(&self, msg: &str) -> ! {
287+
self.print_backtrace();
288+
self.parse_sess.span_diagnostic.handler().bug(msg);
289+
}
290+
fn next_id(&self) -> ast::node_id {
291+
parse::next_node_id(self.parse_sess)
292+
}
293+
fn trace_macros(&self) -> bool {
294+
*self.trace_mac
295+
}
296+
fn set_trace_macros(&self, x: bool) {
297+
*self.trace_mac = x
298+
}
299+
fn str_of(&self, id: ast::ident) -> ~str {
300+
copy *self.parse_sess.interner.get(id)
301+
}
302+
fn ident_of(&self, st: &str) -> ast::ident {
303+
self.parse_sess.interner.intern(st)
304+
}
330305
}
331306

332-
pub fn expr_to_str(cx: @ext_ctxt, expr: @ast::expr, err_msg: ~str) -> ~str {
307+
pub fn expr_to_str(cx: @ExtCtxt, expr: @ast::expr, err_msg: ~str) -> ~str {
333308
match expr.node {
334309
ast::expr_lit(l) => match l.node {
335310
ast::lit_str(s) => copy *s,
@@ -339,7 +314,7 @@ pub fn expr_to_str(cx: @ext_ctxt, expr: @ast::expr, err_msg: ~str) -> ~str {
339314
}
340315
}
341316

342-
pub fn expr_to_ident(cx: @ext_ctxt,
317+
pub fn expr_to_ident(cx: @ExtCtxt,
343318
expr: @ast::expr,
344319
err_msg: &str) -> ast::ident {
345320
match expr.node {
@@ -353,14 +328,14 @@ pub fn expr_to_ident(cx: @ext_ctxt,
353328
}
354329
}
355330

356-
pub fn check_zero_tts(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree],
331+
pub fn check_zero_tts(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree],
357332
name: &str) {
358333
if tts.len() != 0 {
359334
cx.span_fatal(sp, fmt!("%s takes no arguments", name));
360335
}
361336
}
362337

363-
pub fn get_single_str_from_tts(cx: @ext_ctxt,
338+
pub fn get_single_str_from_tts(cx: @ExtCtxt,
364339
sp: span,
365340
tts: &[ast::token_tree],
366341
name: &str) -> ~str {
@@ -375,7 +350,7 @@ pub fn get_single_str_from_tts(cx: @ext_ctxt,
375350
}
376351
}
377352

378-
pub fn get_exprs_from_tts(cx: @ext_ctxt, tts: &[ast::token_tree])
353+
pub fn get_exprs_from_tts(cx: @ExtCtxt, tts: &[ast::token_tree])
379354
-> ~[@ast::expr] {
380355
let p = parse::new_parser_from_tts(cx.parse_sess(),
381356
cx.cfg(),

0 commit comments

Comments
 (0)