Skip to content

syntax: use an index in CodeMap instead of Gc for ExpnInfo. #17314

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 20, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/grammar/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ fn parse_antlr_token(s: &str, tokens: &HashMap<String, Token>) -> TokenAndSpan {
let sp = syntax::codemap::Span {
lo: syntax::codemap::BytePos(from_str::<u32>(start).unwrap() - offset),
hi: syntax::codemap::BytePos(from_str::<u32>(end).unwrap() + 1),
expn_info: None
expn_id: syntax::codemap::NO_EXPANSION
};

TokenAndSpan {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use syntax::abi;
use syntax::ast_map;
use syntax::attr::AttrMetaMethods;
use syntax::attr;
use syntax::codemap::Span;
use syntax::codemap::{Span, NO_EXPANSION};
use syntax::parse::token;
use syntax::{ast, ast_util, visit};
use syntax::ptr::P;
Expand Down Expand Up @@ -1492,7 +1492,7 @@ impl LintPass for Stability {

fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
// if the expression was produced by a macro expansion,
if e.span.expn_info.is_some() { return }
if e.span.expn_id != NO_EXPANSION { return }

let id = match e.node {
ast::ExprPath(..) | ast::ExprStruct(..) => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2035,7 +2035,7 @@ impl fake_ext_ctxt for parse::ParseSess {
codemap::Span {
lo: codemap::BytePos(0),
hi: codemap::BytePos(0),
expn_info: None
expn_id: codemap::NO_EXPANSION
}
}
fn ident_of(&self, st: &str) -> ast::Ident {
Expand Down
5 changes: 3 additions & 2 deletions src/librustc/middle/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1520,11 +1520,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
sp, "not all control paths return a value");
if ends_with_stmt {
let last_stmt = body.stmts.last().unwrap();
let original_span = original_sp(last_stmt.span, sp);
let original_span = original_sp(self.ir.tcx.sess.codemap(),
last_stmt.span, sp);
let span_semicolon = Span {
lo: original_span.hi - BytePos(1),
hi: original_span.hi,
expn_info: original_span.expn_info
expn_id: original_span.expn_id
};
self.ir.tcx.sess.span_note(
span_semicolon, "consider removing this semicolon:");
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/save/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ fn escape(s: String) -> String {

// If the expression is a macro expansion or other generated code, run screaming and don't index.
fn generated_code(span: Span) -> bool {
span.expn_info.is_some() || span == DUMMY_SP
span.expn_id != NO_EXPANSION || span == DUMMY_SP
}

struct DxrVisitor<'l, 'tcx: 'l> {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/save/span_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl<'a> SpanUtils<'a> {
Some(Span {
lo: base + self.sess.codemap().lookup_byte_offset(sub.lo).pos,
hi: base + self.sess.codemap().lookup_byte_offset(sub.hi).pos,
expn_info: None,
expn_id: NO_EXPANSION,
})
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1363,7 +1363,7 @@ mod test {
inner: Span {
lo: BytePos(11),
hi: BytePos(19),
expn_info: None,
expn_id: NO_EXPANSION,
},
view_items: Vec::new(),
items: Vec::new(),
Expand All @@ -1373,7 +1373,7 @@ mod test {
span: Span {
lo: BytePos(10),
hi: BytePos(20),
expn_info: None,
expn_id: NO_EXPANSION,
},
exported_macros: Vec::new(),
};
Expand Down
45 changes: 33 additions & 12 deletions src/libsyntax/codemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ source code snippets, etc.

use serialize::{Encodable, Decodable, Encoder, Decoder};
use std::cell::RefCell;
use std::gc::Gc;
use std::rc::Rc;

pub trait Pos {
Expand Down Expand Up @@ -93,10 +92,10 @@ pub struct Span {
pub hi: BytePos,
/// Information about where the macro came from, if this piece of
/// code was created by a macro expansion.
pub expn_info: Option<Gc<ExpnInfo>>
pub expn_id: ExpnId
}

pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_info: None };
pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_id: NO_EXPANSION };

#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub struct Spanned<T> {
Expand Down Expand Up @@ -140,17 +139,19 @@ pub fn dummy_spanned<T>(t: T) -> Spanned<T> {

/* assuming that we're not in macro expansion */
pub fn mk_sp(lo: BytePos, hi: BytePos) -> Span {
Span {lo: lo, hi: hi, expn_info: None}
Span {lo: lo, hi: hi, expn_id: NO_EXPANSION}
}

/// Return the span itself if it doesn't come from a macro expansion,
/// otherwise return the call site span up to the `enclosing_sp` by
/// following the `expn_info` chain.
pub fn original_sp(sp: Span, enclosing_sp: Span) -> Span {
match (sp.expn_info, enclosing_sp.expn_info) {
pub fn original_sp(cm: &CodeMap, sp: Span, enclosing_sp: Span) -> Span {
let call_site1 = cm.with_expn_info(sp.expn_id, |ei| ei.map(|ei| ei.call_site));
let call_site2 = cm.with_expn_info(enclosing_sp.expn_id, |ei| ei.map(|ei| ei.call_site));
match (call_site1, call_site2) {
(None, _) => sp,
(Some(expn1), Some(expn2)) if expn1.call_site == expn2.call_site => sp,
(Some(expn1), _) => original_sp(expn1.call_site, enclosing_sp),
(Some(call_site1), Some(call_site2)) if call_site1 == call_site2 => sp,
(Some(call_site1), _) => original_sp(cm, call_site1, enclosing_sp),
}
}

Expand Down Expand Up @@ -222,6 +223,11 @@ pub struct ExpnInfo {
pub callee: NameAndSpan
}

#[deriving(PartialEq, Eq, Clone, Show, Hash)]
pub struct ExpnId(u32);

pub static NO_EXPANSION: ExpnId = ExpnId(-1);

pub type FileName = String;

pub struct FileLines {
Expand Down Expand Up @@ -299,13 +305,15 @@ impl FileMap {
}

pub struct CodeMap {
pub files: RefCell<Vec<Rc<FileMap>>>
pub files: RefCell<Vec<Rc<FileMap>>>,
expansions: RefCell<Vec<ExpnInfo>>
}

impl CodeMap {
pub fn new() -> CodeMap {
CodeMap {
files: RefCell::new(Vec::new()),
expansions: RefCell::new(Vec::new()),
}
}

Expand Down Expand Up @@ -527,6 +535,19 @@ impl CodeMap {
col: chpos - linechpos
}
}

pub fn record_expansion(&self, expn_info: ExpnInfo) -> ExpnId {
let mut expansions = self.expansions.borrow_mut();
expansions.push(expn_info);
ExpnId(expansions.len().to_u32().expect("too many ExpnInfo's!") - 1)
}

pub fn with_expn_info<T>(&self, id: ExpnId, f: |Option<&ExpnInfo>| -> T) -> T {
match id {
NO_EXPANSION => f(None),
ExpnId(i) => f(Some(&(*self.expansions.borrow())[i as uint]))
}
}
}

#[cfg(test)]
Expand Down Expand Up @@ -665,7 +686,7 @@ mod test {
fn t7() {
// Test span_to_lines for a span ending at the end of filemap
let cm = init_code_map();
let span = Span {lo: BytePos(12), hi: BytePos(23), expn_info: None};
let span = Span {lo: BytePos(12), hi: BytePos(23), expn_id: NO_EXPANSION};
let file_lines = cm.span_to_lines(span);

assert_eq!(file_lines.file.name, "blork.rs".to_string());
Expand All @@ -677,7 +698,7 @@ mod test {
fn t8() {
// Test span_to_snippet for a span ending at the end of filemap
let cm = init_code_map();
let span = Span {lo: BytePos(12), hi: BytePos(23), expn_info: None};
let span = Span {lo: BytePos(12), hi: BytePos(23), expn_id: NO_EXPANSION};
let snippet = cm.span_to_snippet(span);

assert_eq!(snippet, Some("second line".to_string()));
Expand All @@ -687,7 +708,7 @@ mod test {
fn t9() {
// Test span_to_str for a span ending at the end of filemap
let cm = init_code_map();
let span = Span {lo: BytePos(12), hi: BytePos(23), expn_info: None};
let span = Span {lo: BytePos(12), hi: BytePos(23), expn_id: NO_EXPANSION};
let sstr = cm.span_to_string(span);

assert_eq!(sstr, "blork.rs:2:1: 2:12".to_string());
Expand Down
38 changes: 19 additions & 19 deletions src/libsyntax/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
// we want to tell compiletest/runtest to look at the last line of the
// span (since `custom_highlight_lines` displays an arrow to the end of
// the span)
let span_end = Span { lo: sp.hi, hi: sp.hi, expn_info: sp.expn_info};
let span_end = Span { lo: sp.hi, hi: sp.hi, expn_id: sp.expn_id};
let ses = cm.span_to_string(span_end);
try!(print_diagnostic(dst, ses.as_slice(), lvl, msg, code));
if rsp.is_full_span() {
Expand Down Expand Up @@ -523,24 +523,24 @@ fn print_macro_backtrace(w: &mut EmitterWriter,
cm: &codemap::CodeMap,
sp: Span)
-> io::IoResult<()> {
for ei in sp.expn_info.iter() {
let ss = ei.callee
.span
.as_ref()
.map_or("".to_string(), |span| cm.span_to_string(*span));
let (pre, post) = match ei.callee.format {
codemap::MacroAttribute => ("#[", "]"),
codemap::MacroBang => ("", "!")
};
try!(print_diagnostic(w, ss.as_slice(), Note,
format!("in expansion of {}{}{}", pre,
ei.callee.name,
post).as_slice(), None));
let ss = cm.span_to_string(ei.call_site);
try!(print_diagnostic(w, ss.as_slice(), Note, "expansion site", None));
try!(print_macro_backtrace(w, cm, ei.call_site));
}
Ok(())
let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| match expn_info {
Some(ei) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be Ok(expn_info.map(|ei| { ... })) rather than a match.

let ss = ei.callee.span.map_or(String::new(), |span| cm.span_to_string(span));
let (pre, post) = match ei.callee.format {
codemap::MacroAttribute => ("#[", "]"),
codemap::MacroBang => ("", "!")
};
try!(print_diagnostic(w, ss.as_slice(), Note,
format!("in expansion of {}{}{}", pre,
ei.callee.name,
post).as_slice(), None));
let ss = cm.span_to_string(ei.call_site);
try!(print_diagnostic(w, ss.as_slice(), Note, "expansion site", None));
Ok(Some(ei.call_site))
}
None => Ok(None)
}));
cs.map_or(Ok(()), |call_site| print_macro_backtrace(w, cm, call_site))
}

pub fn expect<T>(diag: &SpanHandler, opt: Option<T>, msg: || -> String) -> T {
Expand Down
75 changes: 55 additions & 20 deletions src/libsyntax/ext/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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:
Expand Down Expand Up @@ -457,7 +456,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> ,
Expand All @@ -473,7 +472,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,
Expand Down Expand Up @@ -501,13 +500,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> {
Expand All @@ -516,22 +551,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.
Expand Down
Loading