@@ -64,8 +64,8 @@ pub(super) trait GetCacheInternal<'tcx>: QueryDescription<'tcx> + Sized {
6464
6565#[ derive( Clone ) ]
6666pub ( super ) struct CycleError < ' tcx > {
67- /// The span of the reason the first query in `cycle` ran the last query in ` cycle`
68- pub ( super ) span : Span ,
67+ /// The query and related span which uses the cycle
68+ pub ( super ) usage : Option < ( Span , Query < ' tcx > ) > ,
6969 pub ( super ) cycle : Vec < QueryInfo < ' tcx > > ,
7070}
7171
@@ -81,7 +81,7 @@ pub(super) enum TryGetLock<'a, 'tcx: 'a, T, D: QueryDescription<'tcx> + 'a> {
8181}
8282
8383impl < ' a , ' gcx , ' tcx > TyCtxt < ' a , ' gcx , ' tcx > {
84- pub ( super ) fn report_cycle ( self , CycleError { span , cycle : stack } : CycleError < ' gcx > )
84+ pub ( super ) fn report_cycle ( self , CycleError { usage , cycle : stack } : CycleError < ' gcx > )
8585 -> DiagnosticBuilder < ' a >
8686 {
8787 assert ! ( !stack. is_empty( ) ) ;
@@ -95,23 +95,27 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
9595 // (And cycle errors around impls tend to occur during the
9696 // collect/coherence phases anyhow.)
9797 item_path:: with_forced_impl_filename_line ( || {
98- let span = fix_span ( span, & stack. first ( ) . unwrap ( ) . query ) ;
99- let mut err =
100- struct_span_err ! ( self . sess, span, E0391 ,
101- "cyclic dependency detected" ) ;
102- err. span_label ( span, "cyclic reference" ) ;
103-
104- err. span_note ( fix_span ( stack[ 0 ] . span , & stack[ 0 ] . query ) ,
105- & format ! ( "the cycle begins when {}..." , stack[ 0 ] . query. describe( self ) ) ) ;
106-
107- for & QueryInfo { span, ref query, .. } in & stack[ 1 ..] {
108- err. span_note ( fix_span ( span, query) ,
109- & format ! ( "...which then requires {}..." , query. describe( self ) ) ) ;
98+ let span = fix_span ( stack[ 1 % stack. len ( ) ] . span , & stack[ 0 ] . query ) ;
99+ let mut err = struct_span_err ! ( self . sess,
100+ span,
101+ E0391 ,
102+ "cycle detected when {}" ,
103+ stack[ 0 ] . query. describe( self ) ) ;
104+
105+ for i in 1 ..stack. len ( ) {
106+ let query = & stack[ i] . query ;
107+ let span = fix_span ( stack[ ( i + 1 ) % stack. len ( ) ] . span , query) ;
108+ err. span_note ( span, & format ! ( "...which requires {}..." , query. describe( self ) ) ) ;
110109 }
111110
112- err. note ( & format ! ( "...which then again requires {}, completing the cycle. " ,
111+ err. note ( & format ! ( "...which again requires {}, completing the cycle" ,
113112 stack[ 0 ] . query. describe( self ) ) ) ;
114113
114+ if let Some ( ( span, query) ) = usage {
115+ err. span_note ( fix_span ( span, & query) ,
116+ & format ! ( "cycle used when {}" , query. describe( self ) ) ) ;
117+ }
118+
115119 return err
116120 } )
117121 }
0 commit comments