@@ -64,8 +64,8 @@ pub(super) trait GetCacheInternal<'tcx>: QueryDescription<'tcx> + Sized {
64
64
65
65
#[ derive( Clone ) ]
66
66
pub ( 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 > ) > ,
69
69
pub ( super ) cycle : Vec < QueryInfo < ' tcx > > ,
70
70
}
71
71
@@ -81,7 +81,7 @@ pub(super) enum TryGetLock<'a, 'tcx: 'a, T, D: QueryDescription<'tcx> + 'a> {
81
81
}
82
82
83
83
impl < ' 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 > )
85
85
-> DiagnosticBuilder < ' a >
86
86
{
87
87
assert ! ( !stack. is_empty( ) ) ;
@@ -95,23 +95,27 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
95
95
// (And cycle errors around impls tend to occur during the
96
96
// collect/coherence phases anyhow.)
97
97
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 ) ) ) ;
110
109
}
111
110
112
- err. note ( & format ! ( "...which then again requires {}, completing the cycle. " ,
111
+ err. note ( & format ! ( "...which again requires {}, completing the cycle" ,
113
112
stack[ 0 ] . query. describe( self ) ) ) ;
114
113
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
+
115
119
return err
116
120
} )
117
121
}
0 commit comments