Skip to content

Commit b94075c

Browse files
committed
rollup merge of #17314 : eddyb/span-no-gc
2 parents 129aff7 + f1a8f53 commit b94075c

File tree

21 files changed

+145
-134
lines changed

21 files changed

+145
-134
lines changed

src/grammar/verify.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ fn parse_antlr_token(s: &str, tokens: &HashMap<String, Token>) -> TokenAndSpan {
211211
let sp = syntax::codemap::Span {
212212
lo: syntax::codemap::BytePos(from_str::<u32>(start).unwrap() - offset),
213213
hi: syntax::codemap::BytePos(from_str::<u32>(end).unwrap() + 1),
214-
expn_info: None
214+
expn_id: syntax::codemap::NO_EXPANSION
215215
};
216216

217217
TokenAndSpan {

src/librustc/lint/builtin.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use syntax::abi;
4242
use syntax::ast_map;
4343
use syntax::attr::AttrMetaMethods;
4444
use syntax::attr;
45-
use syntax::codemap::Span;
45+
use syntax::codemap::{Span, NO_EXPANSION};
4646
use syntax::parse::token;
4747
use syntax::{ast, ast_util, visit};
4848
use syntax::ptr::P;
@@ -1491,7 +1491,7 @@ impl LintPass for Stability {
14911491

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

14961496
let id = match e.node {
14971497
ast::ExprPath(..) | ast::ExprStruct(..) => {

src/librustc/middle/astencode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2030,7 +2030,7 @@ impl fake_ext_ctxt for parse::ParseSess {
20302030
codemap::Span {
20312031
lo: codemap::BytePos(0),
20322032
hi: codemap::BytePos(0),
2033-
expn_info: None
2033+
expn_id: codemap::NO_EXPANSION
20342034
}
20352035
}
20362036
fn ident_of(&self, st: &str) -> ast::Ident {

src/librustc/middle/liveness.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,11 +1509,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
15091509
sp, "not all control paths return a value");
15101510
if ends_with_stmt {
15111511
let last_stmt = body.stmts.last().unwrap();
1512-
let original_span = original_sp(last_stmt.span, sp);
1512+
let original_span = original_sp(self.ir.tcx.sess.codemap(),
1513+
last_stmt.span, sp);
15131514
let span_semicolon = Span {
15141515
lo: original_span.hi - BytePos(1),
15151516
hi: original_span.hi,
1516-
expn_info: original_span.expn_info
1517+
expn_id: original_span.expn_id
15171518
};
15181519
self.ir.tcx.sess.span_note(
15191520
span_semicolon, "consider removing this semicolon:");

src/librustc/middle/save/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ fn escape(s: String) -> String {
7171

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

7777
struct DxrVisitor<'l, 'tcx: 'l> {

src/librustc/middle/save/span_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl<'a> SpanUtils<'a> {
5757
Some(Span {
5858
lo: base + self.sess.codemap().lookup_byte_offset(sub.lo).pos,
5959
hi: base + self.sess.codemap().lookup_byte_offset(sub.hi).pos,
60-
expn_info: None,
60+
expn_id: NO_EXPANSION,
6161
})
6262
}
6363
}

src/libsyntax/ast.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,7 +1370,7 @@ mod test {
13701370
inner: Span {
13711371
lo: BytePos(11),
13721372
hi: BytePos(19),
1373-
expn_info: None,
1373+
expn_id: NO_EXPANSION,
13741374
},
13751375
view_items: Vec::new(),
13761376
items: Vec::new(),
@@ -1380,7 +1380,7 @@ mod test {
13801380
span: Span {
13811381
lo: BytePos(10),
13821382
hi: BytePos(20),
1383-
expn_info: None,
1383+
expn_id: NO_EXPANSION,
13841384
},
13851385
exported_macros: Vec::new(),
13861386
};

src/libsyntax/codemap.rs

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ source code snippets, etc.
2525

2626
use serialize::{Encodable, Decodable, Encoder, Decoder};
2727
use std::cell::RefCell;
28-
use std::gc::Gc;
2928
use std::rc::Rc;
3029

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

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

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

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

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

@@ -222,6 +223,11 @@ pub struct ExpnInfo {
222223
pub callee: NameAndSpan
223224
}
224225

226+
#[deriving(PartialEq, Eq, Clone, Show, Hash)]
227+
pub struct ExpnId(u32);
228+
229+
pub static NO_EXPANSION: ExpnId = ExpnId(-1);
230+
225231
pub type FileName = String;
226232

227233
pub struct FileLines {
@@ -299,13 +305,15 @@ impl FileMap {
299305
}
300306

301307
pub struct CodeMap {
302-
pub files: RefCell<Vec<Rc<FileMap>>>
308+
pub files: RefCell<Vec<Rc<FileMap>>>,
309+
expansions: RefCell<Vec<ExpnInfo>>
303310
}
304311

305312
impl CodeMap {
306313
pub fn new() -> CodeMap {
307314
CodeMap {
308315
files: RefCell::new(Vec::new()),
316+
expansions: RefCell::new(Vec::new()),
309317
}
310318
}
311319

@@ -527,6 +535,19 @@ impl CodeMap {
527535
col: chpos - linechpos
528536
}
529537
}
538+
539+
pub fn record_expansion(&self, expn_info: ExpnInfo) -> ExpnId {
540+
let mut expansions = self.expansions.borrow_mut();
541+
expansions.push(expn_info);
542+
ExpnId(expansions.len().to_u32().expect("too many ExpnInfo's!") - 1)
543+
}
544+
545+
pub fn with_expn_info<T>(&self, id: ExpnId, f: |Option<&ExpnInfo>| -> T) -> T {
546+
match id {
547+
NO_EXPANSION => f(None),
548+
ExpnId(i) => f(Some(&(*self.expansions.borrow())[i as uint]))
549+
}
550+
}
530551
}
531552

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

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

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

693714
assert_eq!(sstr, "blork.rs:2:1: 2:12".to_string());

src/libsyntax/diagnostic.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
389389
// we want to tell compiletest/runtest to look at the last line of the
390390
// span (since `custom_highlight_lines` displays an arrow to the end of
391391
// the span)
392-
let span_end = Span { lo: sp.hi, hi: sp.hi, expn_info: sp.expn_info};
392+
let span_end = Span { lo: sp.hi, hi: sp.hi, expn_id: sp.expn_id};
393393
let ses = cm.span_to_string(span_end);
394394
try!(print_diagnostic(dst, ses.as_slice(), lvl, msg, code));
395395
if rsp.is_full_span() {
@@ -523,24 +523,24 @@ fn print_macro_backtrace(w: &mut EmitterWriter,
523523
cm: &codemap::CodeMap,
524524
sp: Span)
525525
-> io::IoResult<()> {
526-
for ei in sp.expn_info.iter() {
527-
let ss = ei.callee
528-
.span
529-
.as_ref()
530-
.map_or("".to_string(), |span| cm.span_to_string(*span));
531-
let (pre, post) = match ei.callee.format {
532-
codemap::MacroAttribute => ("#[", "]"),
533-
codemap::MacroBang => ("", "!")
534-
};
535-
try!(print_diagnostic(w, ss.as_slice(), Note,
536-
format!("in expansion of {}{}{}", pre,
537-
ei.callee.name,
538-
post).as_slice(), None));
539-
let ss = cm.span_to_string(ei.call_site);
540-
try!(print_diagnostic(w, ss.as_slice(), Note, "expansion site", None));
541-
try!(print_macro_backtrace(w, cm, ei.call_site));
542-
}
543-
Ok(())
526+
let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| match expn_info {
527+
Some(ei) => {
528+
let ss = ei.callee.span.map_or(String::new(), |span| cm.span_to_string(span));
529+
let (pre, post) = match ei.callee.format {
530+
codemap::MacroAttribute => ("#[", "]"),
531+
codemap::MacroBang => ("", "!")
532+
};
533+
try!(print_diagnostic(w, ss.as_slice(), Note,
534+
format!("in expansion of {}{}{}", pre,
535+
ei.callee.name,
536+
post).as_slice(), None));
537+
let ss = cm.span_to_string(ei.call_site);
538+
try!(print_diagnostic(w, ss.as_slice(), Note, "expansion site", None));
539+
Ok(Some(ei.call_site))
540+
}
541+
None => Ok(None)
542+
}));
543+
cs.map_or(Ok(()), |call_site| print_macro_backtrace(w, cm, call_site))
544544
}
545545

546546
pub fn expect<T>(diag: &SpanHandler, opt: Option<T>, msg: || -> String) -> T {

src/libsyntax/ext/base.rs

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use ast;
1212
use ast::Name;
1313
use codemap;
14-
use codemap::{CodeMap, Span, ExpnInfo};
14+
use codemap::{CodeMap, Span, ExpnId, ExpnInfo, NO_EXPANSION};
1515
use ext;
1616
use ext::expand;
1717
use parse;
@@ -24,7 +24,6 @@ use ext::mtwt;
2424
use fold::Folder;
2525

2626
use std::collections::HashMap;
27-
use std::gc::{Gc, GC};
2827
use std::rc::Rc;
2928

3029
// new-style macro! tt code:
@@ -452,7 +451,7 @@ fn initial_syntax_expander_table() -> SyntaxEnv {
452451
pub struct ExtCtxt<'a> {
453452
pub parse_sess: &'a parse::ParseSess,
454453
pub cfg: ast::CrateConfig,
455-
pub backtrace: Option<Gc<ExpnInfo>>,
454+
pub backtrace: ExpnId,
456455
pub ecfg: expand::ExpansionConfig,
457456

458457
pub mod_path: Vec<ast::Ident> ,
@@ -468,7 +467,7 @@ impl<'a> ExtCtxt<'a> {
468467
ExtCtxt {
469468
parse_sess: parse_sess,
470469
cfg: cfg,
471-
backtrace: None,
470+
backtrace: NO_EXPANSION,
472471
mod_path: Vec::new(),
473472
ecfg: ecfg,
474473
trace_mac: false,
@@ -496,13 +495,49 @@ impl<'a> ExtCtxt<'a> {
496495
pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess }
497496
pub fn cfg(&self) -> ast::CrateConfig { self.cfg.clone() }
498497
pub fn call_site(&self) -> Span {
499-
match self.backtrace {
498+
self.codemap().with_expn_info(self.backtrace, |ei| match ei {
500499
Some(expn_info) => expn_info.call_site,
501500
None => self.bug("missing top span")
502-
}
501+
})
503502
}
504503
pub fn print_backtrace(&self) { }
505-
pub fn backtrace(&self) -> Option<Gc<ExpnInfo>> { self.backtrace }
504+
pub fn backtrace(&self) -> ExpnId { self.backtrace }
505+
pub fn original_span(&self) -> Span {
506+
let mut expn_id = self.backtrace;
507+
let mut call_site = None;
508+
loop {
509+
match self.codemap().with_expn_info(expn_id, |ei| ei.map(|ei| ei.call_site)) {
510+
None => break,
511+
Some(cs) => {
512+
call_site = Some(cs);
513+
expn_id = cs.expn_id;
514+
}
515+
}
516+
}
517+
call_site.expect("missing expansion backtrace")
518+
}
519+
pub fn original_span_in_file(&self) -> Span {
520+
let mut expn_id = self.backtrace;
521+
let mut call_site = None;
522+
loop {
523+
let expn_info = self.codemap().with_expn_info(expn_id, |ei| {
524+
ei.map(|ei| (ei.call_site, ei.callee.name.as_slice() == "include"))
525+
});
526+
match expn_info {
527+
None => break,
528+
Some((cs, is_include)) => {
529+
if is_include {
530+
// Don't recurse into file using "include!".
531+
break;
532+
}
533+
call_site = Some(cs);
534+
expn_id = cs.expn_id;
535+
}
536+
}
537+
}
538+
call_site.expect("missing expansion backtrace")
539+
}
540+
506541
pub fn mod_push(&mut self, i: ast::Ident) { self.mod_path.push(i); }
507542
pub fn mod_pop(&mut self) { self.mod_path.pop().unwrap(); }
508543
pub fn mod_path(&self) -> Vec<ast::Ident> {
@@ -511,22 +546,22 @@ impl<'a> ExtCtxt<'a> {
511546
v.extend(self.mod_path.iter().map(|a| *a));
512547
return v;
513548
}
514-
pub fn bt_push(&mut self, ei: codemap::ExpnInfo) {
515-
match ei {
516-
ExpnInfo {call_site: cs, callee: ref callee} => {
517-
self.backtrace =
518-
Some(box(GC) ExpnInfo {
519-
call_site: Span {lo: cs.lo, hi: cs.hi,
520-
expn_info: self.backtrace.clone()},
521-
callee: (*callee).clone()
522-
});
523-
}
524-
}
549+
pub fn bt_push(&mut self, ei: ExpnInfo) {
550+
let mut call_site = ei.call_site;
551+
call_site.expn_id = self.backtrace;
552+
self.backtrace = self.codemap().record_expansion(ExpnInfo {
553+
call_site: call_site,
554+
callee: ei.callee
555+
});
525556
}
526557
pub fn bt_pop(&mut self) {
527558
match self.backtrace {
528-
Some(expn_info) => self.backtrace = expn_info.call_site.expn_info,
529-
_ => self.bug("tried to pop without a push")
559+
NO_EXPANSION => self.bug("tried to pop without a push"),
560+
expn_id => {
561+
self.backtrace = self.codemap().with_expn_info(expn_id, |expn_info| {
562+
expn_info.map_or(NO_EXPANSION, |ei| ei.call_site.expn_id)
563+
});
564+
}
530565
}
531566
}
532567
/// Emit `msg` attached to `sp`, and stop compilation immediately.

0 commit comments

Comments
 (0)