@@ -17,6 +17,7 @@ use errors::DiagnosticBuilder;
1717use errors:: Level ;
1818use ty:: tls;
1919use ty:: { TyCtxt } ;
20+ use ty:: maps:: Query ;
2021use ty:: maps:: config:: QueryDescription ;
2122use ty:: maps:: job:: { QueryResult , QueryInfo } ;
2223use ty:: item_path;
@@ -63,6 +64,7 @@ pub(super) trait GetCacheInternal<'tcx>: QueryDescription<'tcx> + Sized {
6364
6465#[ derive( Clone ) ]
6566pub ( super ) struct CycleError < ' tcx > {
67+ /// The span of the reason the first query in `cycle` ran the last query in `cycle`
6668 pub ( super ) span : Span ,
6769 pub ( super ) cycle : Vec < QueryInfo < ' tcx > > ,
6870}
@@ -79,27 +81,31 @@ pub(super) enum TryGetLock<'a, 'tcx: 'a, T, D: QueryDescription<'tcx> + 'a> {
7981}
8082
8183impl < ' a , ' gcx , ' tcx > TyCtxt < ' a , ' gcx , ' tcx > {
82- pub ( super ) fn report_cycle ( self , CycleError { span, cycle : stack } : CycleError )
84+ pub ( super ) fn report_cycle ( self , CycleError { span, cycle : stack } : CycleError < ' gcx > )
8385 -> DiagnosticBuilder < ' a >
8486 {
8587 assert ! ( !stack. is_empty( ) ) ;
8688
89+ let fix_span = |span : Span , query : & Query < ' gcx > | {
90+ self . sess . codemap ( ) . def_span ( query. default_span ( self , span) )
91+ } ;
92+
8793 // Disable naming impls with types in this path, since that
8894 // sometimes cycles itself, leading to extra cycle errors.
8995 // (And cycle errors around impls tend to occur during the
9096 // collect/coherence phases anyhow.)
9197 item_path:: with_forced_impl_filename_line ( || {
92- let span = self . sess . codemap ( ) . def_span ( span ) ;
98+ let span = fix_span ( span , & stack . first ( ) . unwrap ( ) . query ) ;
9399 let mut err =
94100 struct_span_err ! ( self . sess, span, E0391 ,
95101 "cyclic dependency detected" ) ;
96102 err. span_label ( span, "cyclic reference" ) ;
97103
98- err. span_note ( self . sess . codemap ( ) . def_span ( stack[ 0 ] . span ) ,
104+ err. span_note ( fix_span ( stack[ 0 ] . span , & stack [ 0 ] . query ) ,
99105 & format ! ( "the cycle begins when {}..." , stack[ 0 ] . query. describe( self ) ) ) ;
100106
101107 for & QueryInfo { span, ref query, .. } in & stack[ 1 ..] {
102- err. span_note ( self . sess . codemap ( ) . def_span ( span) ,
108+ err. span_note ( fix_span ( span, query ) ,
103109 & format ! ( "...which then requires {}..." , query. describe( self ) ) ) ;
104110 }
105111
@@ -266,6 +272,22 @@ macro_rules! define_maps {
266272 r
267273 }
268274 }
275+
276+ // FIXME(eddyb) Get more valid Span's on queries.
277+ pub fn default_span( & self , tcx: TyCtxt <' _, $tcx, ' _>, span: Span ) -> Span {
278+ if span != DUMMY_SP {
279+ return span;
280+ }
281+ // The def_span query is used to calculate default_span,
282+ // so exit to avoid infinite recursion
283+ match * self {
284+ Query :: def_span( ..) => return span,
285+ _ => ( )
286+ }
287+ match * self {
288+ $( Query :: $name( key) => key. default_span( tcx) , ) *
289+ }
290+ }
269291 }
270292
271293 pub mod queries {
@@ -303,7 +325,7 @@ macro_rules! define_maps {
303325 /// If the query already executed and panicked, this will fatal error / silently panic
304326 fn try_get_lock(
305327 tcx: TyCtxt <' a, $tcx, ' lcx>,
306- mut span: Span ,
328+ span: Span ,
307329 key: & $K
308330 ) -> TryGetLock <' a, $tcx, $V, Self >
309331 {
@@ -329,21 +351,14 @@ macro_rules! define_maps {
329351 } ;
330352 mem:: drop( lock) ;
331353
332- // This just matches the behavior of `try_get_with` so the span when
333- // we await matches the span we would use when executing.
334- // See the FIXME there.
335- if span == DUMMY_SP && stringify!( $name) != "def_span" {
336- span = key. default_span( tcx) ;
337- }
338-
339354 if let Err ( cycle) = job. await ( tcx, span) {
340355 return TryGetLock :: JobCompleted ( Err ( cycle) ) ;
341356 }
342357 }
343358 }
344359
345360 fn try_get_with( tcx: TyCtxt <' a, $tcx, ' lcx>,
346- mut span: Span ,
361+ span: Span ,
347362 key: $K)
348363 -> Result <$V, CycleError <$tcx>>
349364 {
@@ -377,18 +392,6 @@ macro_rules! define_maps {
377392
378393 let mut lock = get_lock_or_return!( ) ;
379394
380- // FIXME(eddyb) Get more valid Span's on queries.
381- // def_span guard is necessary to prevent a recursive loop,
382- // default_span calls def_span query internally.
383- if span == DUMMY_SP && stringify!( $name) != "def_span" {
384- // This might deadlock if we hold the map lock since we might be
385- // waiting for the def_span query and switch to some other fiber
386- // So we drop the lock here and reacquire it
387- mem:: drop( lock) ;
388- span = key. default_span( tcx) ;
389- lock = get_lock_or_return!( ) ;
390- }
391-
392395 // Fast path for when incr. comp. is off. `to_dep_node` is
393396 // expensive for some DepKinds.
394397 if !tcx. dep_graph. is_fully_enabled( ) {
0 commit comments