@@ -17,11 +17,13 @@ use middle::privacy::AccessLevels;
17
17
use mir;
18
18
use session:: CompileResult ;
19
19
use ty:: { self , CrateInherentImpls , Ty , TyCtxt } ;
20
+ use ty:: item_path;
20
21
use ty:: subst:: Substs ;
21
22
use util:: nodemap:: NodeSet ;
22
23
23
24
use rustc_data_structures:: indexed_vec:: IndexVec ;
24
25
use std:: cell:: { RefCell , RefMut } ;
26
+ use std:: mem;
25
27
use std:: ops:: Deref ;
26
28
use std:: rc:: Rc ;
27
29
use syntax_pos:: { Span , DUMMY_SP } ;
@@ -139,24 +141,36 @@ pub struct CycleError<'a, 'tcx: 'a> {
139
141
140
142
impl < ' a , ' gcx , ' tcx > TyCtxt < ' a , ' gcx , ' tcx > {
141
143
pub fn report_cycle ( self , CycleError { span, cycle } : CycleError ) {
142
- assert ! ( !cycle. is_empty( ) ) ;
143
-
144
- let mut err = struct_span_err ! ( self . sess, span, E0391 ,
145
- "unsupported cyclic reference between types/traits detected" ) ;
146
- err. span_label ( span, & format ! ( "cyclic reference" ) ) ;
147
-
148
- err. span_note ( cycle[ 0 ] . 0 , & format ! ( "the cycle begins when {}..." ,
149
- cycle[ 0 ] . 1 . describe( self ) ) ) ;
150
-
151
- for & ( span, ref query) in & cycle[ 1 ..] {
152
- err. span_note ( span, & format ! ( "...which then requires {}..." ,
153
- query. describe( self ) ) ) ;
154
- }
144
+ // Subtle: release the refcell lock before invoking `describe()`
145
+ // below by dropping `cycle`.
146
+ let stack = cycle. to_vec ( ) ;
147
+ mem:: drop ( cycle) ;
148
+
149
+ assert ! ( !stack. is_empty( ) ) ;
150
+
151
+ // Disable naming impls with types in this path, since that
152
+ // sometimes cycles itself, leading to extra cycle errors.
153
+ // (And cycle errors around impls tend to occur during the
154
+ // collect/coherence phases anyhow.)
155
+ item_path:: with_forced_impl_filename_line ( || {
156
+ let mut err =
157
+ struct_span_err ! ( self . sess, span, E0391 ,
158
+ "unsupported cyclic reference between types/traits detected" ) ;
159
+ err. span_label ( span, & format ! ( "cyclic reference" ) ) ;
160
+
161
+ err. span_note ( stack[ 0 ] . 0 , & format ! ( "the cycle begins when {}..." ,
162
+ stack[ 0 ] . 1 . describe( self ) ) ) ;
163
+
164
+ for & ( span, ref query) in & stack[ 1 ..] {
165
+ err. span_note ( span, & format ! ( "...which then requires {}..." ,
166
+ query. describe( self ) ) ) ;
167
+ }
155
168
156
- err. note ( & format ! ( "...which then again requires {}, completing the cycle." ,
157
- cycle [ 0 ] . 1 . describe( self ) ) ) ;
169
+ err. note ( & format ! ( "...which then again requires {}, completing the cycle." ,
170
+ stack [ 0 ] . 1 . describe( self ) ) ) ;
158
171
159
- err. emit ( ) ;
172
+ err. emit ( ) ;
173
+ } ) ;
160
174
}
161
175
162
176
fn cycle_check < F , R > ( self , span : Span , query : Query < ' gcx > , compute : F )
@@ -335,6 +349,11 @@ macro_rules! define_maps {
335
349
-> Result <R , CycleError <' a, $tcx>>
336
350
where F : FnOnce ( & $V) -> R
337
351
{
352
+ debug!( "ty::queries::{}::try_get_with(key={:?}, span={:?})" ,
353
+ stringify!( $name) ,
354
+ key,
355
+ span) ;
356
+
338
357
if let Some ( result) = tcx. maps. $name. borrow( ) . get( & key) {
339
358
return Ok ( f( result) ) ;
340
359
}
@@ -441,7 +460,7 @@ macro_rules! define_maps {
441
460
// the driver creates (using several `rustc_*` crates).
442
461
define_maps ! { <' tcx>
443
462
/// Records the type of every item.
444
- [ pub ] type_of: ItemSignature ( DefId ) -> Ty <' tcx>,
463
+ [ ] type_of: ItemSignature ( DefId ) -> Ty <' tcx>,
445
464
446
465
/// Maps from the def-id of an item (trait/struct/enum/fn) to its
447
466
/// associated generics and predicates.
@@ -480,7 +499,7 @@ define_maps! { <'tcx>
480
499
/// Maps from a trait item to the trait item "descriptor"
481
500
[ ] associated_item: AssociatedItems ( DefId ) -> ty:: AssociatedItem ,
482
501
483
- [ pub ] impl_trait_ref: ItemSignature ( DefId ) -> Option <ty:: TraitRef <' tcx>>,
502
+ [ ] impl_trait_ref: ItemSignature ( DefId ) -> Option <ty:: TraitRef <' tcx>>,
484
503
[ ] impl_polarity: ItemSignature ( DefId ) -> hir:: ImplPolarity ,
485
504
486
505
/// Maps a DefId of a type to a list of its inherent impls.
0 commit comments