@@ -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,15 +443,65 @@ 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) ;
457
+ span
458
+ }
459
+
460
+ /// Returns `true` if the debuginfo for `span` should be collapsed to the outermost expansion
461
+ /// site. Only applies when `Span` is the result of macro expansion.
462
+ ///
463
+ /// - If the `collapse_debuginfo` feature is enabled then debuginfo is not collapsed by default
464
+ /// and only when a macro definition is annotated with `#[collapse_debuginfo]`.
465
+ /// - If `collapse_debuginfo` is not enabled, then debuginfo is collapsed by default.
466
+ ///
467
+ /// When `-Zdebug-macros` is provided then debuginfo will never be collapsed.
468
+ fn should_collapse_debuginfo < F : Fn ( DefId ) -> bool > (
469
+ & self ,
470
+ span : Span ,
471
+ collapse_enabled : bool ,
472
+ attr_enabled : bool ,
473
+ in_std_macro : & F ,
474
+ ) -> bool {
475
+ collapse_enabled
476
+ && if attr_enabled {
477
+ span. in_macro_expansion_with_collapse_debuginfo ( & self , in_std_macro)
478
+ } else {
479
+ span. from_expansion ( )
480
+ }
481
+ }
482
+
483
+ fn walk_chain_collapsed < F : Fn ( DefId ) -> bool > (
484
+ & self ,
485
+ mut span : Span ,
486
+ to : SyntaxContext ,
487
+ collapse_enabled : bool ,
488
+ attr_enabled : bool ,
489
+ in_std_macro : F ,
490
+ ) -> Span {
491
+ let orig_span = span;
492
+
493
+ debug ! ( "walk_chain_collapsed({:?}, {:?})" , span, to) ;
494
+ debug ! ( "walk_chain_collapsed: span ctxt = {:?}" , span. ctxt( ) ) ;
495
+ while span. ctxt ( ) != to
496
+ && self . should_collapse_debuginfo ( span, collapse_enabled, attr_enabled, & in_std_macro)
497
+ {
498
+ let outer_expn = self . outer_expn ( span. ctxt ( ) ) ;
499
+ debug ! ( "walk_chain_collapsed({:?}): outer_expn={:?}" , span, outer_expn) ;
500
+ let expn_data = self . expn_data ( outer_expn) ;
501
+ debug ! ( "walk_chain_collapsed({:?}): expn_data={:?}" , span, expn_data) ;
502
+ span = expn_data. call_site ;
503
+ }
504
+ debug ! ( "walk_chain_collapsed: for span {:?} >>> return span = {:?}" , orig_span, span) ;
455
505
span
456
506
}
457
507
@@ -571,6 +621,22 @@ pub fn walk_chain(span: Span, to: SyntaxContext) -> Span {
571
621
HygieneData :: with ( |data| data. walk_chain ( span, to) )
572
622
}
573
623
624
+ pub fn walk_chain_collapsed < F : Fn ( DefId ) -> bool > (
625
+ span : Span ,
626
+ to : SyntaxContext ,
627
+ collapse_enabled : bool ,
628
+ attr_enabled : bool ,
629
+ in_std_macro : F ,
630
+ ) -> Span {
631
+ HygieneData :: with ( |hdata| {
632
+ if hdata. should_collapse_debuginfo ( span, collapse_enabled, attr_enabled, & in_std_macro) {
633
+ hdata. walk_chain_collapsed ( span, to, collapse_enabled, attr_enabled, in_std_macro)
634
+ } else {
635
+ span
636
+ }
637
+ } )
638
+ }
639
+
574
640
pub fn update_dollar_crate_names ( mut get_name : impl FnMut ( SyntaxContext ) -> Symbol ) {
575
641
// The new contexts that need updating are at the end of the list and have `$crate` as a name.
576
642
let ( len, to_update) = HygieneData :: with ( |data| {
0 commit comments