1111use ast;
1212use ast:: Name ;
1313use codemap;
14- use codemap:: { CodeMap , Span , ExpnInfo } ;
14+ use codemap:: { CodeMap , Span , ExpnId , ExpnInfo , NO_EXPANSION } ;
1515use ext;
1616use ext:: expand;
1717use parse;
@@ -24,7 +24,6 @@ use ext::mtwt;
2424use fold:: Folder ;
2525
2626use std:: collections:: HashMap ;
27- use std:: gc:: { Gc , GC } ;
2827use std:: rc:: Rc ;
2928
3029// new-style macro! tt code:
@@ -457,7 +456,7 @@ fn initial_syntax_expander_table() -> SyntaxEnv {
457456pub struct ExtCtxt <' a> {
458457 pub parse_sess: & ' a parse:: ParseSess ,
459458 pub cfg : ast:: CrateConfig ,
460- pub backtrace : Option < Gc < ExpnInfo > > ,
459+ pub backtrace : ExpnId ,
461460 pub ecfg : expand:: ExpansionConfig ,
462461
463462 pub mod_path : Vec < ast:: Ident > ,
@@ -473,7 +472,7 @@ impl<'a> ExtCtxt<'a> {
473472 ExtCtxt {
474473 parse_sess : parse_sess ,
475474 cfg : cfg ,
476- backtrace : None ,
475+ backtrace : NO_EXPANSION ,
477476 mod_path : Vec :: new ( ) ,
478477 ecfg : ecfg ,
479478 trace_mac : false,
@@ -501,13 +500,49 @@ impl<'a> ExtCtxt<'a> {
501500 pub fn parse_sess ( & self ) -> & ' a parse:: ParseSess { self . parse_sess }
502501 pub fn cfg ( & self ) -> ast:: CrateConfig { self . cfg. clone( ) }
503502 pub fn call_site ( & self ) -> Span {
504- match self . backtrace {
503+ self . codemap ( ) . with_expn_info ( self . backtrace, |ei| match ei {
505504 Some ( expn_info) => expn_info. call_site,
506505 None => self . bug( "missing top span" )
507- }
506+ } )
508507 }
509508 pub fn print_backtrace ( & self ) { }
510- pub fn backtrace ( & self ) -> Option < Gc < ExpnInfo > > { self . backtrace }
509+ pub fn backtrace ( & self ) -> ExpnId { self . backtrace }
510+ pub fn original_span ( & self ) -> Span {
511+ let mut expn_id = self . backtrace;
512+ let mut call_site = None ;
513+ loop {
514+ match self . codemap( ) . with_expn_info( expn_id, |ei| ei. map( |ei| ei. call_site) ) {
515+ None => break ,
516+ Some ( cs) => {
517+ call_site = Some ( cs) ;
518+ expn_id = cs. expn_id;
519+ }
520+ }
521+ }
522+ call_site. expect( "missing expansion backtrace" )
523+ }
524+ pub fn original_span_in_file( & self ) -> Span {
525+ let mut expn_id = self . backtrace;
526+ let mut call_site = None ;
527+ loop {
528+ let expn_info = self . codemap( ) . with_expn_info( expn_id, |ei| {
529+ ei. map( |ei| ( ei. call_site, ei. callee. name. as_slice( ) == "include" ) )
530+ } ) ;
531+ match expn_info {
532+ None => break ,
533+ Some( ( cs, is_include) ) => {
534+ if is_include {
535+ // Don't recurse into file using "include!".
536+ break;
537+ }
538+ call_site = Some ( cs) ;
539+ expn_id = cs. expn_id;
540+ }
541+ }
542+ }
543+ call_site. expect( "missing expansion backtrace" )
544+ }
545+
511546 pub fn mod_push( & mut self , i: ast:: Ident ) { self . mod_path. push( i) ; }
512547 pub fn mod_pop( & mut self ) { self . mod_path. pop( ) . unwrap( ) ; }
513548 pub fn mod_path( & self ) -> Vec < ast:: Ident > {
@@ -516,22 +551,22 @@ impl<'a> ExtCtxt<'a> {
516551 v. extend( self . mod_path. iter( ) . map( |a| * a) ) ;
517552 return v;
518553 }
519- pub fn bt_push ( & mut self , ei : codemap:: ExpnInfo ) {
520- match ei {
521- ExpnInfo { call_site : cs, callee : ref callee} => {
522- self . backtrace =
523- Some ( box( GC ) ExpnInfo {
524- call_site : Span { lo : cs. lo, hi : cs. hi,
525- expn_info : self . backtrace. clone( ) } ,
526- callee : ( * callee) . clone( )
527- } ) ;
528- }
529- }
554+ pub fn bt_push( & mut self , ei: ExpnInfo ) {
555+ let mut call_site = ei. call_site;
556+ call_site. expn_id = self . backtrace;
557+ self . backtrace = self . codemap( ) . record_expansion( ExpnInfo {
558+ call_site : call_site,
559+ callee : ei. callee
560+ } ) ;
530561 }
531562 pub fn bt_pop( & mut self ) {
532563 match self . backtrace {
533- Some ( expn_info) => self . backtrace = expn_info. call_site. expn_info,
534- _ => self . bug( "tried to pop without a push" )
564+ NO_EXPANSION => self . bug( "tried to pop without a push" ) ,
565+ expn_id => {
566+ self . backtrace = self . codemap( ) . with_expn_info( expn_id, |expn_info| {
567+ expn_info. map_or( NO_EXPANSION , |ei| ei. call_site. expn_id)
568+ } ) ;
569+ }
535570 }
536571 }
537572 /// Emit `msg` attached to `sp`, and stop compilation immediately.
0 commit comments