diff options
| author | bors <bors@rust-lang.org> | 2014-09-20 03:11:12 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-09-20 03:11:12 +0000 |
| commit | aef6c4b1382dcf2f943bd5872656625f935c0b7c (patch) | |
| tree | 95920a7c62cbc07301ec8fe4b189b33e208327cd /src/libsyntax/ext | |
| parent | 3b6e880fffb8e09b15bc6fc41d5b23f21bf5056d (diff) | |
| parent | f082416bece7cbb16ec46f870fb7f91ca15f2231 (diff) | |
auto merge of #17399 : alexcrichton/rust/rollup, r=alexcrichton
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 108 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic/mod.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 33 | ||||
| -rw-r--r-- | src/libsyntax/ext/format.rs | 33 | ||||
| -rw-r--r-- | src/libsyntax/ext/source_util.rs | 46 |
6 files changed, 106 insertions, 121 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 773daa4a4c5..b35a9456757 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -11,7 +11,7 @@ use ast; use ast::Name; use codemap; -use codemap::{CodeMap, Span, ExpnInfo}; +use codemap::{CodeMap, Span, ExpnId, ExpnInfo, NO_EXPANSION}; use ext; use ext::expand; use parse; @@ -24,7 +24,6 @@ use ext::mtwt; use fold::Folder; use std::collections::HashMap; -use std::gc::{Gc, GC}; use std::rc::Rc; // new-style macro! tt code: @@ -203,25 +202,20 @@ impl MacResult for MacPat { Some(self.p) } } -/// A convenience type for macros that return a single item. -pub struct MacItem { - i: P<ast::Item> +/// A type for macros that return multiple items. +pub struct MacItems { + items: SmallVector<P<ast::Item>> } -impl MacItem { - pub fn new(i: P<ast::Item>) -> Box<MacResult+'static> { - box MacItem { i: i } as Box<MacResult+'static> + +impl MacItems { + pub fn new<I: Iterator<P<ast::Item>>>(mut it: I) -> Box<MacResult+'static> { + box MacItems { items: it.collect() } as Box<MacResult+'static> } } -impl MacResult for MacItem { - fn make_items(self: Box<MacItem>) -> Option<SmallVector<P<ast::Item>>> { - Some(SmallVector::one(self.i)) - } - fn make_stmt(self: Box<MacItem>) -> Option<P<ast::Stmt>> { - Some(P(codemap::respan( - self.i.span, - ast::StmtDecl( - P(codemap::respan(self.i.span, ast::DeclItem(self.i))), - ast::DUMMY_NODE_ID)))) + +impl MacResult for MacItems { + fn make_items(self: Box<MacItems>) -> Option<SmallVector<P<ast::Item>>> { + Some(self.items) } } @@ -305,11 +299,11 @@ pub enum SyntaxExtension { /// based upon it. /// /// `#[deriving(...)]` is an `ItemDecorator`. - ItemDecorator(Box<ItemDecorator + 'static>), + Decorator(Box<ItemDecorator + 'static>), /// A syntax extension that is attached to an item and modifies it /// in-place. - ItemModifier(Box<ItemModifier + 'static>), + Modifier(Box<ItemModifier + 'static>), /// A normal, function-like syntax extension. /// @@ -387,7 +381,7 @@ fn initial_syntax_expander_table() -> SyntaxEnv { builtin_normal_expander( ext::log_syntax::expand_syntax_ext)); syntax_expanders.insert(intern("deriving"), - ItemDecorator(box ext::deriving::expand_meta_deriving)); + Decorator(box ext::deriving::expand_meta_deriving)); // Quasi-quoting expanders syntax_expanders.insert(intern("quote_tokens"), @@ -457,7 +451,7 @@ fn initial_syntax_expander_table() -> SyntaxEnv { pub struct ExtCtxt<'a> { pub parse_sess: &'a parse::ParseSess, pub cfg: ast::CrateConfig, - pub backtrace: Option<Gc<ExpnInfo>>, + pub backtrace: ExpnId, pub ecfg: expand::ExpansionConfig, pub mod_path: Vec<ast::Ident> , @@ -473,7 +467,7 @@ impl<'a> ExtCtxt<'a> { ExtCtxt { parse_sess: parse_sess, cfg: cfg, - backtrace: None, + backtrace: NO_EXPANSION, mod_path: Vec::new(), ecfg: ecfg, trace_mac: false, @@ -501,13 +495,49 @@ impl<'a> ExtCtxt<'a> { pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess } pub fn cfg(&self) -> ast::CrateConfig { self.cfg.clone() } pub fn call_site(&self) -> Span { - match self.backtrace { + self.codemap().with_expn_info(self.backtrace, |ei| match ei { Some(expn_info) => expn_info.call_site, None => self.bug("missing top span") - } + }) } pub fn print_backtrace(&self) { } - pub fn backtrace(&self) -> Option<Gc<ExpnInfo>> { self.backtrace } + pub fn backtrace(&self) -> ExpnId { self.backtrace } + pub fn original_span(&self) -> Span { + let mut expn_id = self.backtrace; + let mut call_site = None; + loop { + match self.codemap().with_expn_info(expn_id, |ei| ei.map(|ei| ei.call_site)) { + None => break, + Some(cs) => { + call_site = Some(cs); + expn_id = cs.expn_id; + } + } + } + call_site.expect("missing expansion backtrace") + } + pub fn original_span_in_file(&self) -> Span { + let mut expn_id = self.backtrace; + let mut call_site = None; + loop { + let expn_info = self.codemap().with_expn_info(expn_id, |ei| { + ei.map(|ei| (ei.call_site, ei.callee.name.as_slice() == "include")) + }); + match expn_info { + None => break, + Some((cs, is_include)) => { + if is_include { + // Don't recurse into file using "include!". + break; + } + call_site = Some(cs); + expn_id = cs.expn_id; + } + } + } + call_site.expect("missing expansion backtrace") + } + pub fn mod_push(&mut self, i: ast::Ident) { self.mod_path.push(i); } pub fn mod_pop(&mut self) { self.mod_path.pop().unwrap(); } pub fn mod_path(&self) -> Vec<ast::Ident> { @@ -516,22 +546,22 @@ impl<'a> ExtCtxt<'a> { v.extend(self.mod_path.iter().map(|a| *a)); return v; } - pub fn bt_push(&mut self, ei: codemap::ExpnInfo) { - match ei { - ExpnInfo {call_site: cs, callee: ref callee} => { - self.backtrace = - Some(box(GC) ExpnInfo { - call_site: Span {lo: cs.lo, hi: cs.hi, - expn_info: self.backtrace.clone()}, - callee: (*callee).clone() - }); - } - } + pub fn bt_push(&mut self, ei: ExpnInfo) { + let mut call_site = ei.call_site; + call_site.expn_id = self.backtrace; + self.backtrace = self.codemap().record_expansion(ExpnInfo { + call_site: call_site, + callee: ei.callee + }); } pub fn bt_pop(&mut self) { match self.backtrace { - Some(expn_info) => self.backtrace = expn_info.call_site.expn_info, - _ => self.bug("tried to pop without a push") + NO_EXPANSION => self.bug("tried to pop without a push"), + expn_id => { + self.backtrace = self.codemap().with_expn_info(expn_id, |expn_info| { + expn_info.map_or(NO_EXPANSION, |ei| ei.call_site.expn_id) + }); + } } } /// Emit `msg` attached to `sp`, and stop compilation immediately. diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 7b2613d4e8b..16ecd83180e 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -573,7 +573,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { let field_span = Span { lo: sp.lo - Pos::from_uint(field_name.get().len()), hi: sp.hi, - expn_info: sp.expn_info, + expn_id: sp.expn_id, }; let id = Spanned { node: ident, span: field_span }; @@ -583,7 +583,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { let field_span = Span { lo: sp.lo - Pos::from_uint(idx.to_string().len()), hi: sp.hi, - expn_info: sp.expn_info, + expn_id: sp.expn_id, }; let id = Spanned { node: idx, span: field_span }; diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index ff249495bd7..142adc9b721 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -181,7 +181,6 @@ //! ~~~ use std::cell::RefCell; -use std::gc::GC; use std::vec; use abi::Abi; @@ -1169,7 +1168,7 @@ impl<'a> TraitDef<'a> { None => cx.span_bug(self.span, "trait with empty path in generic `deriving`"), Some(name) => *name }; - to_set.expn_info = Some(box(GC) codemap::ExpnInfo { + to_set.expn_id = cx.codemap().record_expansion(codemap::ExpnInfo { call_site: to_set, callee: codemap::NameAndSpan { name: format!("deriving({})", trait_name), diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 4ff9912645a..e173b93e468 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -30,8 +30,6 @@ use util::small_vector::SmallVector; use visit; use visit::Visitor; -use std::gc::Gc; - enum Either<L,R> { Left(L), Right(R) @@ -161,11 +159,11 @@ fn expand_mac_invoc<T>(mac: ast::Mac, span: codemap::Span, // be the root of the call stack. That's the most // relevant span and it's the actual invocation of // the macro. - let mac_span = original_span(fld.cx); + let mac_span = fld.cx.original_span(); let opt_parsed = { let expanded = expandfun.expand(fld.cx, - mac_span.call_site, + mac_span, marked_before.as_slice()); parse_thunk(expanded) }; @@ -254,7 +252,7 @@ pub fn expand_item(it: P<ast::Item>, fld: &mut MacroExpander) match fld.cx.syntax_env.find(&intern(mname.get())) { Some(rc) => match *rc { - ItemDecorator(ref dec) => { + Decorator(ref dec) => { attr::mark_used(attr); fld.cx.bt_push(ExpnInfo { @@ -311,7 +309,7 @@ fn expand_item_modifiers(mut it: P<ast::Item>, fld: &mut MacroExpander) // partition the attributes into ItemModifiers and others let (modifiers, other_attrs) = it.attrs.partitioned(|attr| { match fld.cx.syntax_env.find(&intern(attr.name().get())) { - Some(rc) => match *rc { ItemModifier(_) => true, _ => false }, + Some(rc) => match *rc { Modifier(_) => true, _ => false }, _ => false } }); @@ -330,7 +328,7 @@ fn expand_item_modifiers(mut it: P<ast::Item>, fld: &mut MacroExpander) match fld.cx.syntax_env.find(&intern(mname.get())) { Some(rc) => match *rc { - ItemModifier(ref mac) => { + Modifier(ref mac) => { attr::mark_used(attr); fld.cx.bt_push(ExpnInfo { call_site: attr.span, @@ -759,9 +757,9 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> { let fm = fresh_mark(); let marked_before = mark_tts(tts.as_slice(), fm); - let mac_span = original_span(fld.cx); + let mac_span = fld.cx.original_span(); let expanded = match expander.expand(fld.cx, - mac_span.call_site, + mac_span, marked_before.as_slice()).make_pat() { Some(e) => e, None => { @@ -969,7 +967,7 @@ fn new_span(cx: &ExtCtxt, sp: Span) -> Span { Span { lo: sp.lo, hi: sp.hi, - expn_info: cx.backtrace(), + expn_id: cx.backtrace(), } } @@ -1083,21 +1081,6 @@ fn mark_method(expr: P<ast::Method>, m: Mrk) -> P<ast::Method> { .expect_one("marking an item didn't return exactly one method") } -fn original_span(cx: &ExtCtxt) -> Gc<codemap::ExpnInfo> { - let mut relevant_info = cx.backtrace(); - let mut einfo = relevant_info.unwrap(); - loop { - match relevant_info { - None => { break } - Some(e) => { - einfo = e; - relevant_info = einfo.call_site.expn_info; - } - } - } - return einfo; -} - /// Check that there are no macro invocations left in the AST: pub fn check_for_macros(sess: &parse::ParseSess, krate: &ast::Crate) { visit::walk_crate(&mut MacroExterminator{sess:sess}, krate); diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 26586684309..b760c893a10 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -19,17 +19,18 @@ use parse::token; use ptr::P; use std::collections::HashMap; +use std::string; #[deriving(PartialEq)] enum ArgumentType { - Known(String), + Known(string::String), Unsigned, String, } enum Position { Exact(uint), - Named(String), + Named(string::String), } struct Context<'a, 'b:'a> { @@ -44,12 +45,12 @@ struct Context<'a, 'b:'a> { /// Note that we keep a side-array of the ordering of the named arguments /// found to be sure that we can translate them in the same order that they /// were declared in. - names: HashMap<String, P<ast::Expr>>, - name_types: HashMap<String, ArgumentType>, - name_ordering: Vec<String>, + names: HashMap<string::String, P<ast::Expr>>, + name_types: HashMap<string::String, ArgumentType>, + name_ordering: Vec<string::String>, /// The latest consecutive literal strings, or empty if there weren't any. - literal: String, + literal: string::String, /// Collection of the compiled `rt::Argument` structures pieces: Vec<P<ast::Expr>>, @@ -58,7 +59,7 @@ struct Context<'a, 'b:'a> { /// Stays `true` if all formatting parameters are default (as in "{}{}"). all_pieces_simple: bool, - name_positions: HashMap<String, uint>, + name_positions: HashMap<string::String, uint>, method_statics: Vec<P<ast::Item>>, /// Updated as arguments are consumed or methods are entered @@ -81,10 +82,10 @@ pub enum Invocation { /// named arguments)) fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool, tts: &[ast::TokenTree]) - -> (Invocation, Option<(P<ast::Expr>, Vec<P<ast::Expr>>, Vec<String>, - HashMap<String, P<ast::Expr>>)>) { + -> (Invocation, Option<(P<ast::Expr>, Vec<P<ast::Expr>>, Vec<string::String>, + HashMap<string::String, P<ast::Expr>>)>) { let mut args = Vec::new(); - let mut names = HashMap::<String, P<ast::Expr>>::new(); + let mut names = HashMap::<string::String, P<ast::Expr>>::new(); let mut order = Vec::new(); let mut p = ecx.new_parser_from_tts(tts); @@ -167,7 +168,7 @@ impl<'a, 'b> Context<'a, 'b> { fn verify_piece(&mut self, p: &parse::Piece) { match *p { parse::String(..) => {} - parse::Argument(ref arg) => { + parse::NextArgument(ref arg) => { // width/precision first, if they have implicit positional // parameters it makes more sense to consume them first. self.verify_count(arg.format.width); @@ -222,7 +223,7 @@ impl<'a, 'b> Context<'a, 'b> { } } - fn describe_num_args(&self) -> String { + fn describe_num_args(&self) -> string::String { match self.args.len() { 0 => "no arguments given".to_string(), 1 => "there is 1 argument".to_string(), @@ -391,7 +392,7 @@ impl<'a, 'b> Context<'a, 'b> { self.literal.push_str(s); None } - parse::Argument(ref arg) => { + parse::NextArgument(ref arg) => { // Translate the position let pos = match arg.position { // These two have a direct mapping @@ -747,8 +748,8 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, invocation: Invocation, efmt: P<ast::Expr>, args: Vec<P<ast::Expr>>, - name_ordering: Vec<String>, - names: HashMap<String, P<ast::Expr>>) + name_ordering: Vec<string::String>, + names: HashMap<string::String, P<ast::Expr>>) -> P<ast::Expr> { let arg_types = Vec::from_fn(args.len(), |_| None); let mut cx = Context { @@ -761,7 +762,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, name_ordering: name_ordering, nest_level: 0, next_arg: 0, - literal: String::new(), + literal: string::String::new(), pieces: Vec::new(), str_pieces: Vec::new(), all_pieces_simple: true, diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 5cc0ec4a122..41967b0680c 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -11,7 +11,6 @@ use ast; use codemap; use codemap::{Pos, Span}; -use codemap::{ExpnInfo, NameAndSpan}; use ext::base::*; use ext::base; use ext::build::AstBuilder; @@ -19,7 +18,6 @@ use parse; use parse::token; use print::pprust; -use std::gc::Gc; use std::io::File; use std::rc::Rc; @@ -32,10 +30,10 @@ pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> Box<base::MacResult+'static> { base::check_zero_tts(cx, sp, tts, "line!"); - let topmost = topmost_expn_info(cx.backtrace().unwrap()); - let loc = cx.codemap().lookup_char_pos(topmost.call_site.lo); + let topmost = cx.original_span_in_file(); + let loc = cx.codemap().lookup_char_pos(topmost.lo); - base::MacExpr::new(cx.expr_uint(topmost.call_site, loc.line)) + base::MacExpr::new(cx.expr_uint(topmost, loc.line)) } /* col!(): expands to the current column number */ @@ -43,9 +41,9 @@ pub fn expand_col(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> Box<base::MacResult+'static> { base::check_zero_tts(cx, sp, tts, "col!"); - let topmost = topmost_expn_info(cx.backtrace().unwrap()); - let loc = cx.codemap().lookup_char_pos(topmost.call_site.lo); - base::MacExpr::new(cx.expr_uint(topmost.call_site, loc.col.to_uint())) + let topmost = cx.original_span_in_file(); + let loc = cx.codemap().lookup_char_pos(topmost.lo); + base::MacExpr::new(cx.expr_uint(topmost, loc.col.to_uint())) } /// file!(): expands to the current filename */ @@ -55,10 +53,10 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> Box<base::MacResult+'static> { base::check_zero_tts(cx, sp, tts, "file!"); - let topmost = topmost_expn_info(cx.backtrace().unwrap()); - let loc = cx.codemap().lookup_char_pos(topmost.call_site.lo); + let topmost = cx.original_span_in_file(); + let loc = cx.codemap().lookup_char_pos(topmost.lo); let filename = token::intern_and_get_ident(loc.file.name.as_slice()); - base::MacExpr::new(cx.expr_str(topmost.call_site, filename)) + base::MacExpr::new(cx.expr_str(topmost, filename)) } pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) @@ -162,32 +160,6 @@ pub fn expand_include_bin(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) } } -// recur along an ExpnInfo chain to find the original expression -fn topmost_expn_info(expn_info: Gc<codemap::ExpnInfo>) -> Gc<codemap::ExpnInfo> { - match *expn_info { - ExpnInfo { call_site: ref call_site, .. } => { - match call_site.expn_info { - Some(next_expn_info) => { - match *next_expn_info { - ExpnInfo { - callee: NameAndSpan { name: ref name, .. }, - .. - } => { - // Don't recurse into file using "include!" - if "include" == name.as_slice() { - expn_info - } else { - topmost_expn_info(next_expn_info) - } - } - } - }, - None => expn_info - } - } - } -} - // resolve a file-system path to an absolute file-system path (if it // isn't already) fn res_rel_file(cx: &mut ExtCtxt, sp: codemap::Span, arg: &Path) -> Path { |
