@@ -377,7 +377,7 @@ impl HygieneData {
377
377
self . local_expn_data [ expn_id] . as_ref ( ) . expect ( "no expansion data for an expansion ID" )
378
378
}
379
379
380
- fn expn_data ( & self , expn_id : ExpnId ) -> & ExpnData {
380
+ pub fn expn_data ( & self , expn_id : ExpnId ) -> & ExpnData {
381
381
if let Some ( expn_id) = expn_id. as_local ( ) {
382
382
self . local_expn_data [ expn_id] . as_ref ( ) . expect ( "no expansion data for an expansion ID" )
383
383
} else {
@@ -412,7 +412,7 @@ impl HygieneData {
412
412
self . syntax_context_data [ ctxt. 0 as usize ] . opaque_and_semitransparent
413
413
}
414
414
415
- fn outer_expn ( & self , ctxt : SyntaxContext ) -> ExpnId {
415
+ pub fn outer_expn ( & self , ctxt : SyntaxContext ) -> ExpnId {
416
416
self . syntax_context_data [ ctxt. 0 as usize ] . outer_expn
417
417
}
418
418
@@ -443,18 +443,52 @@ impl HygieneData {
443
443
}
444
444
445
445
fn walk_chain ( & self , mut span : Span , to : SyntaxContext ) -> Span {
446
+ let orig_span = span;
446
447
debug ! ( "walk_chain({:?}, {:?})" , span, to) ;
447
448
debug ! ( "walk_chain: span ctxt = {:?}" , span. ctxt( ) ) ;
448
- while span. from_expansion ( ) && span. ctxt ( ) != to {
449
+ while span. ctxt ( ) != to && span. from_expansion ( ) {
449
450
let outer_expn = self . outer_expn ( span. ctxt ( ) ) ;
450
451
debug ! ( "walk_chain({:?}): outer_expn={:?}" , span, outer_expn) ;
451
452
let expn_data = self . expn_data ( outer_expn) ;
452
453
debug ! ( "walk_chain({:?}): expn_data={:?}" , span, expn_data) ;
453
454
span = expn_data. call_site ;
454
455
}
456
+ debug ! ( "walk_chain: for span {:?} >>> return span = {:?}" , orig_span, span) ;
455
457
span
456
458
}
457
459
460
+ // We need to walk up and update return span if we meet macro instantiation to be collapsed
461
+ fn walk_chain_collapsed (
462
+ & self ,
463
+ mut span : Span ,
464
+ to : SyntaxContext ,
465
+ collapse_enabled : bool ,
466
+ attr_enabled : bool ,
467
+ ) -> Span {
468
+ if !collapse_enabled {
469
+ return span;
470
+ }
471
+ let orig_span = span;
472
+ let mut rv_span = span;
473
+
474
+ debug ! ( "walk_chain_collapsed({:?}, {:?})" , span, to) ;
475
+ debug ! ( "walk_chain_collapsed: span ctxt = {:?}" , span. ctxt( ) ) ;
476
+ while span. ctxt ( ) != to && span. from_expansion ( ) {
477
+ let outer_expn = self . outer_expn ( span. ctxt ( ) ) ;
478
+ debug ! ( "walk_chain_collapsed({:?}): outer_expn={:?}" , span, outer_expn) ;
479
+ let expn_data = self . expn_data ( outer_expn) ;
480
+ debug ! ( "walk_chain_collapsed({:?}): expn_data={:?}" , span, expn_data) ;
481
+ span = expn_data. call_site ;
482
+ if !attr_enabled ||
483
+ matches ! ( expn_data. kind, ExpnKind :: Macro ( ..) ) && expn_data. collapse_debuginfo
484
+ {
485
+ rv_span = span;
486
+ }
487
+ }
488
+ debug ! ( "walk_chain_collapsed: for span {:?} >>> return span = {:?}" , orig_span, rv_span) ;
489
+ rv_span
490
+ }
491
+
458
492
fn adjust ( & self , ctxt : & mut SyntaxContext , expn_id : ExpnId ) -> Option < ExpnId > {
459
493
let mut scope = None ;
460
494
while !self . is_descendant_of ( expn_id, self . outer_expn ( * ctxt) ) {
@@ -571,6 +605,21 @@ pub fn walk_chain(span: Span, to: SyntaxContext) -> Span {
571
605
HygieneData :: with ( |data| data. walk_chain ( span, to) )
572
606
}
573
607
608
+ pub fn walk_chain_collapsed (
609
+ span : Span ,
610
+ to : SyntaxContext ,
611
+ collapse_enabled : bool ,
612
+ attr_enabled : bool ,
613
+ ) -> Span {
614
+ HygieneData :: with ( |hdata| {
615
+ if collapse_enabled && span. from_expansion ( ) {
616
+ hdata. walk_chain_collapsed ( span, to, collapse_enabled, attr_enabled)
617
+ } else {
618
+ span
619
+ }
620
+ } )
621
+ }
622
+
574
623
pub fn update_dollar_crate_names ( mut get_name : impl FnMut ( SyntaxContext ) -> Symbol ) {
575
624
// The new contexts that need updating are at the end of the list and have `$crate` as a name.
576
625
let ( len, to_update) = HygieneData :: with ( |data| {
0 commit comments