Skip to content

Commit

Permalink
auto merge of #6611 : huonw/rust/syntax-ext-no-dup, r=jbclements
Browse files Browse the repository at this point in the history
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?
  • Loading branch information
bors committed May 21, 2013
2 parents 808aada + a59bec4 commit 64963d6
Show file tree
Hide file tree
Showing 36 changed files with 1,667 additions and 2,250 deletions.
6 changes: 3 additions & 3 deletions src/librustc/front/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use syntax::ast_util::*;
use syntax::attr;
use syntax::codemap::{dummy_sp, span, ExpandedFrom, CallInfo, NameAndSpan};
use syntax::codemap;
use syntax::ext::base::{mk_ctxt, ext_ctxt};
use syntax::ext::base::ExtCtxt;
use syntax::fold;
use syntax::print::pprust;
use syntax::{ast, ast_util};
Expand All @@ -36,7 +36,7 @@ struct TestCtxt {
sess: session::Session,
crate: @ast::crate,
path: ~[ast::ident],
ext_cx: @ext_ctxt,
ext_cx: @ExtCtxt,
testfns: ~[Test]
}

Expand Down Expand Up @@ -64,7 +64,7 @@ fn generate_test_harness(sess: session::Session,
let cx: @mut TestCtxt = @mut TestCtxt {
sess: sess,
crate: crate,
ext_cx: mk_ctxt(sess.parse_sess, copy sess.opts.cfg),
ext_cx: ExtCtxt::new(sess.parse_sess, copy sess.opts.cfg),
path: ~[],
testfns: ~[]
};
Expand Down
6 changes: 3 additions & 3 deletions src/librustpkg/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use std::semver;
use std::term;
use syntax::ast_util::*;
use syntax::codemap::{dummy_sp, spanned, dummy_spanned};
use syntax::ext::base::{mk_ctxt, ext_ctxt};
use syntax::ext::base::ExtCtxt;
use syntax::{ast, attr, codemap, diagnostic, fold};
use syntax::ast::{meta_name_value, meta_list};
use syntax::attr::{mk_attr};
Expand Down Expand Up @@ -178,7 +178,7 @@ struct ListenerFn {
struct ReadyCtx {
sess: session::Session,
crate: @ast::crate,
ext_cx: @ext_ctxt,
ext_cx: @ExtCtxt,
path: ~[ast::ident],
fns: ~[ListenerFn]
}
Expand Down Expand Up @@ -247,7 +247,7 @@ pub fn ready_crate(sess: session::Session,
let ctx = @mut ReadyCtx {
sess: sess,
crate: crate,
ext_cx: mk_ctxt(sess.parse_sess, copy sess.opts.cfg),
ext_cx: ExtCtxt::new(sess.parse_sess, copy sess.opts.cfg),
path: ~[],
fns: ~[]
};
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ext/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ fn next_state(s: State) -> Option<State> {
}
}

pub fn expand_asm(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
pub fn expand_asm(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
-> base::MacResult {
let p = parse::new_parser_from_tts(cx.parse_sess(),
cx.cfg(),
Expand Down
4 changes: 2 additions & 2 deletions src/libsyntax/ext/auto_encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use codemap::span;
use ext::base::*;

pub fn expand_auto_encode(
cx: @ext_ctxt,
cx: @ExtCtxt,
span: span,
_mitem: @ast::meta_item,
in_items: ~[@ast::item]
Expand All @@ -25,7 +25,7 @@ pub fn expand_auto_encode(
}

pub fn expand_auto_decode(
cx: @ext_ctxt,
cx: @ExtCtxt,
span: span,
_mitem: @ast::meta_item,
in_items: ~[@ast::item]
Expand Down
213 changes: 94 additions & 119 deletions src/libsyntax/ext/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub struct MacroDef {
ext: SyntaxExtension
}

pub type ItemDecorator = @fn(@ext_ctxt,
pub type ItemDecorator = @fn(@ExtCtxt,
span,
@ast::meta_item,
~[@ast::item])
Expand All @@ -44,7 +44,7 @@ pub struct SyntaxExpanderTT {
span: Option<span>
}

pub type SyntaxExpanderTTFun = @fn(@ext_ctxt,
pub type SyntaxExpanderTTFun = @fn(@ExtCtxt,
span,
&[ast::token_tree])
-> MacResult;
Expand All @@ -54,7 +54,7 @@ pub struct SyntaxExpanderTTItem {
span: Option<span>
}

pub type SyntaxExpanderTTItemFun = @fn(@ext_ctxt,
pub type SyntaxExpanderTTItemFun = @fn(@ExtCtxt,
span,
ast::ident,
~[ast::token_tree])
Expand Down Expand Up @@ -202,134 +202,109 @@ pub fn syntax_expander_table() -> SyntaxEnv {
// One of these is made during expansion and incrementally updated as we go;
// when a macro expansion occurs, the resulting nodes have the backtrace()
// -> expn_info of their expansion context stored into their span.
pub trait ext_ctxt {
fn codemap(&self) -> @CodeMap;
fn parse_sess(&self) -> @mut parse::ParseSess;
fn cfg(&self) -> ast::crate_cfg;
fn call_site(&self) -> span;
fn print_backtrace(&self);
fn backtrace(&self) -> Option<@ExpnInfo>;
fn mod_push(&self, mod_name: ast::ident);
fn mod_pop(&self);
fn mod_path(&self) -> ~[ast::ident];
fn bt_push(&self, ei: codemap::ExpnInfo);
fn bt_pop(&self);
fn span_fatal(&self, sp: span, msg: &str) -> !;
fn span_err(&self, sp: span, msg: &str);
fn span_warn(&self, sp: span, msg: &str);
fn span_unimpl(&self, sp: span, msg: &str) -> !;
fn span_bug(&self, sp: span, msg: &str) -> !;
fn bug(&self, msg: &str) -> !;
fn next_id(&self) -> ast::node_id;
fn trace_macros(&self) -> bool;
fn set_trace_macros(&self, x: bool);
/* for unhygienic identifier transformation */
fn str_of(&self, id: ast::ident) -> ~str;
fn ident_of(&self, st: &str) -> ast::ident;
pub struct ExtCtxt {
parse_sess: @mut parse::ParseSess,
cfg: ast::crate_cfg,
backtrace: @mut Option<@ExpnInfo>,

// These two @mut's should really not be here,
// but the self types for CtxtRepr are all wrong
// and there are bugs in the code for object
// types that make this hard to get right at the
// moment. - nmatsakis
mod_path: @mut ~[ast::ident],
trace_mac: @mut bool
}

pub fn mk_ctxt(parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg)
-> @ext_ctxt {
struct CtxtRepr {
parse_sess: @mut parse::ParseSess,
cfg: ast::crate_cfg,
backtrace: @mut Option<@ExpnInfo>,

// These two @mut's should really not be here,
// but the self types for CtxtRepr are all wrong
// and there are bugs in the code for object
// types that make this hard to get right at the
// moment. - nmatsakis
mod_path: @mut ~[ast::ident],
trace_mac: @mut bool
}
impl ext_ctxt for CtxtRepr {
fn codemap(&self) -> @CodeMap { self.parse_sess.cm }
fn parse_sess(&self) -> @mut parse::ParseSess { self.parse_sess }
fn cfg(&self) -> ast::crate_cfg { copy self.cfg }
fn call_site(&self) -> span {
match *self.backtrace {
Some(@ExpandedFrom(CallInfo {call_site: cs, _})) => cs,
None => self.bug("missing top span")
}
pub impl ExtCtxt {
fn new(parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg) -> @ExtCtxt {
@ExtCtxt {
parse_sess: parse_sess,
cfg: cfg,
backtrace: @mut None,
mod_path: @mut ~[],
trace_mac: @mut false
}
}

fn codemap(&self) -> @CodeMap { self.parse_sess.cm }
fn parse_sess(&self) -> @mut parse::ParseSess { self.parse_sess }
fn cfg(&self) -> ast::crate_cfg { copy self.cfg }
fn call_site(&self) -> span {
match *self.backtrace {
Some(@ExpandedFrom(CallInfo {call_site: cs, _})) => cs,
None => self.bug("missing top span")
}
fn print_backtrace(&self) { }
fn backtrace(&self) -> Option<@ExpnInfo> { *self.backtrace }
fn mod_push(&self, i: ast::ident) { self.mod_path.push(i); }
fn mod_pop(&self) { self.mod_path.pop(); }
fn mod_path(&self) -> ~[ast::ident] { copy *self.mod_path }
fn bt_push(&self, ei: codemap::ExpnInfo) {
match ei {
ExpandedFrom(CallInfo {call_site: cs, callee: ref callee}) => {
}
fn print_backtrace(&self) { }
fn backtrace(&self) -> Option<@ExpnInfo> { *self.backtrace }
fn mod_push(&self, i: ast::ident) { self.mod_path.push(i); }
fn mod_pop(&self) { self.mod_path.pop(); }
fn mod_path(&self) -> ~[ast::ident] { copy *self.mod_path }
fn bt_push(&self, ei: codemap::ExpnInfo) {
match ei {
ExpandedFrom(CallInfo {call_site: cs, callee: ref callee}) => {
*self.backtrace =
Some(@ExpandedFrom(CallInfo {
call_site: span {lo: cs.lo, hi: cs.hi,
expn_info: *self.backtrace},
callee: copy *callee}));
}
}
}
fn bt_pop(&self) {
match *self.backtrace {
Some(@ExpandedFrom(CallInfo {
call_site: span {expn_info: prev, _}, _
})) => {
}
fn bt_pop(&self) {
match *self.backtrace {
Some(@ExpandedFrom(
CallInfo {
call_site: span {expn_info: prev, _}, _
})) => {
*self.backtrace = prev
}
_ => self.bug("tried to pop without a push")
}
_ => self.bug("tried to pop without a push")
}
fn span_fatal(&self, sp: span, msg: &str) -> ! {
self.print_backtrace();
self.parse_sess.span_diagnostic.span_fatal(sp, msg);
}
fn span_err(&self, sp: span, msg: &str) {
self.print_backtrace();
self.parse_sess.span_diagnostic.span_err(sp, msg);
}
fn span_warn(&self, sp: span, msg: &str) {
self.print_backtrace();
self.parse_sess.span_diagnostic.span_warn(sp, msg);
}
fn span_unimpl(&self, sp: span, msg: &str) -> ! {
self.print_backtrace();
self.parse_sess.span_diagnostic.span_unimpl(sp, msg);
}
fn span_bug(&self, sp: span, msg: &str) -> ! {
self.print_backtrace();
self.parse_sess.span_diagnostic.span_bug(sp, msg);
}
fn bug(&self, msg: &str) -> ! {
self.print_backtrace();
self.parse_sess.span_diagnostic.handler().bug(msg);
}
fn next_id(&self) -> ast::node_id {
return parse::next_node_id(self.parse_sess);
}
fn trace_macros(&self) -> bool {
*self.trace_mac
}
fn set_trace_macros(&self, x: bool) {
*self.trace_mac = x
}
fn str_of(&self, id: ast::ident) -> ~str {
copy *self.parse_sess.interner.get(id)
}
fn ident_of(&self, st: &str) -> ast::ident {
self.parse_sess.interner.intern(st)
}
}
let imp: @CtxtRepr = @CtxtRepr {
parse_sess: parse_sess,
cfg: cfg,
backtrace: @mut None,
mod_path: @mut ~[],
trace_mac: @mut false
};
((imp) as @ext_ctxt)
fn span_fatal(&self, sp: span, msg: &str) -> ! {
self.print_backtrace();
self.parse_sess.span_diagnostic.span_fatal(sp, msg);
}
fn span_err(&self, sp: span, msg: &str) {
self.print_backtrace();
self.parse_sess.span_diagnostic.span_err(sp, msg);
}
fn span_warn(&self, sp: span, msg: &str) {
self.print_backtrace();
self.parse_sess.span_diagnostic.span_warn(sp, msg);
}
fn span_unimpl(&self, sp: span, msg: &str) -> ! {
self.print_backtrace();
self.parse_sess.span_diagnostic.span_unimpl(sp, msg);
}
fn span_bug(&self, sp: span, msg: &str) -> ! {
self.print_backtrace();
self.parse_sess.span_diagnostic.span_bug(sp, msg);
}
fn bug(&self, msg: &str) -> ! {
self.print_backtrace();
self.parse_sess.span_diagnostic.handler().bug(msg);
}
fn next_id(&self) -> ast::node_id {
parse::next_node_id(self.parse_sess)
}
fn trace_macros(&self) -> bool {
*self.trace_mac
}
fn set_trace_macros(&self, x: bool) {
*self.trace_mac = x
}
fn str_of(&self, id: ast::ident) -> ~str {
copy *self.parse_sess.interner.get(id)
}
fn ident_of(&self, st: &str) -> ast::ident {
self.parse_sess.interner.intern(st)
}
}

pub fn expr_to_str(cx: @ext_ctxt, expr: @ast::expr, err_msg: ~str) -> ~str {
pub fn expr_to_str(cx: @ExtCtxt, expr: @ast::expr, err_msg: ~str) -> ~str {
match expr.node {
ast::expr_lit(l) => match l.node {
ast::lit_str(s) => copy *s,
Expand All @@ -339,7 +314,7 @@ pub fn expr_to_str(cx: @ext_ctxt, expr: @ast::expr, err_msg: ~str) -> ~str {
}
}

pub fn expr_to_ident(cx: @ext_ctxt,
pub fn expr_to_ident(cx: @ExtCtxt,
expr: @ast::expr,
err_msg: &str) -> ast::ident {
match expr.node {
Expand All @@ -353,14 +328,14 @@ pub fn expr_to_ident(cx: @ext_ctxt,
}
}

pub fn check_zero_tts(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree],
pub fn check_zero_tts(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree],
name: &str) {
if tts.len() != 0 {
cx.span_fatal(sp, fmt!("%s takes no arguments", name));
}
}

pub fn get_single_str_from_tts(cx: @ext_ctxt,
pub fn get_single_str_from_tts(cx: @ExtCtxt,
sp: span,
tts: &[ast::token_tree],
name: &str) -> ~str {
Expand All @@ -375,7 +350,7 @@ pub fn get_single_str_from_tts(cx: @ext_ctxt,
}
}

pub fn get_exprs_from_tts(cx: @ext_ctxt, tts: &[ast::token_tree])
pub fn get_exprs_from_tts(cx: @ExtCtxt, tts: &[ast::token_tree])
-> ~[@ast::expr] {
let p = parse::new_parser_from_tts(cx.parse_sess(),
cx.cfg(),
Expand Down
Loading

0 comments on commit 64963d6

Please sign in to comment.