@@ -16,11 +16,13 @@ use middle::privacy::AccessLevels;
16
16
use mir;
17
17
use session:: CompileResult ;
18
18
use ty:: { self , CrateInherentImpls , Ty , TyCtxt } ;
19
+ use ty:: item_path;
19
20
use ty:: subst:: Substs ;
20
21
use util:: nodemap:: NodeSet ;
21
22
22
23
use rustc_data_structures:: indexed_vec:: IndexVec ;
23
24
use std:: cell:: { RefCell , RefMut } ;
25
+ use std:: mem;
24
26
use std:: ops:: Deref ;
25
27
use std:: rc:: Rc ;
26
28
use syntax_pos:: { Span , DUMMY_SP } ;
@@ -138,24 +140,36 @@ pub struct CycleError<'a, 'tcx: 'a> {
138
140
139
141
impl < ' a , ' gcx , ' tcx > TyCtxt < ' a , ' gcx , ' tcx > {
140
142
pub fn report_cycle ( self , CycleError { span, cycle } : CycleError ) {
141
- assert ! ( !cycle. is_empty( ) ) ;
142
-
143
- let mut err = struct_span_err ! ( self . sess, span, E0391 ,
144
- "unsupported cyclic reference between types/traits detected" ) ;
145
- err. span_label ( span, & format ! ( "cyclic reference" ) ) ;
146
-
147
- err. span_note ( cycle[ 0 ] . 0 , & format ! ( "the cycle begins when {}..." ,
148
- cycle[ 0 ] . 1 . describe( self ) ) ) ;
149
-
150
- for & ( span, ref query) in & cycle[ 1 ..] {
151
- err. span_note ( span, & format ! ( "...which then requires {}..." ,
152
- query. describe( self ) ) ) ;
153
- }
143
+ // Subtle: release the refcell lock before invoking `describe()`
144
+ // below by dropping `cycle`.
145
+ let stack = cycle. to_vec ( ) ;
146
+ mem:: drop ( cycle) ;
147
+
148
+ assert ! ( !stack. is_empty( ) ) ;
149
+
150
+ // Disable naming impls with types in this path, since that
151
+ // sometimes cycles itself, leading to extra cycle errors.
152
+ // (And cycle errors around impls tend to occur during the
153
+ // collect/coherence phases anyhow.)
154
+ item_path:: with_forced_impl_filename_line ( || {
155
+ let mut err =
156
+ struct_span_err ! ( self . sess, span, E0391 ,
157
+ "unsupported cyclic reference between types/traits detected" ) ;
158
+ err. span_label ( span, & format ! ( "cyclic reference" ) ) ;
159
+
160
+ err. span_note ( stack[ 0 ] . 0 , & format ! ( "the cycle begins when {}..." ,
161
+ stack[ 0 ] . 1 . describe( self ) ) ) ;
162
+
163
+ for & ( span, ref query) in & stack[ 1 ..] {
164
+ err. span_note ( span, & format ! ( "...which then requires {}..." ,
165
+ query. describe( self ) ) ) ;
166
+ }
154
167
155
- err. note ( & format ! ( "...which then again requires {}, completing the cycle." ,
156
- cycle [ 0 ] . 1 . describe( self ) ) ) ;
168
+ err. note ( & format ! ( "...which then again requires {}, completing the cycle." ,
169
+ stack [ 0 ] . 1 . describe( self ) ) ) ;
157
170
158
- err. emit ( ) ;
171
+ err. emit ( ) ;
172
+ } ) ;
159
173
}
160
174
161
175
fn cycle_check < F , R > ( self , span : Span , query : Query < ' gcx > , compute : F )
@@ -328,6 +342,11 @@ macro_rules! define_maps {
328
342
-> Result <R , CycleError <' a, $tcx>>
329
343
where F : FnOnce ( & $V) -> R
330
344
{
345
+ debug!( "ty::queries::{}::try_get_with(key={:?}, span={:?})" ,
346
+ stringify!( $name) ,
347
+ key,
348
+ span) ;
349
+
331
350
if let Some ( result) = tcx. maps. $name. borrow( ) . get( & key) {
332
351
return Ok ( f( result) ) ;
333
352
}
@@ -434,7 +453,7 @@ macro_rules! define_maps {
434
453
// the driver creates (using several `rustc_*` crates).
435
454
define_maps ! { <' tcx>
436
455
/// Records the type of every item.
437
- [ pub ] type_of: ItemSignature ( DefId ) -> Ty <' tcx>,
456
+ [ ] type_of: ItemSignature ( DefId ) -> Ty <' tcx>,
438
457
439
458
/// Maps from the def-id of an item (trait/struct/enum/fn) to its
440
459
/// associated generics and predicates.
@@ -473,7 +492,7 @@ define_maps! { <'tcx>
473
492
/// Maps from a trait item to the trait item "descriptor"
474
493
[ ] associated_item: AssociatedItems ( DefId ) -> ty:: AssociatedItem ,
475
494
476
- [ pub ] impl_trait_ref: ItemSignature ( DefId ) -> Option <ty:: TraitRef <' tcx>>,
495
+ [ ] impl_trait_ref: ItemSignature ( DefId ) -> Option <ty:: TraitRef <' tcx>>,
477
496
[ ] impl_polarity: ItemSignature ( DefId ) -> hir:: ImplPolarity ,
478
497
479
498
/// Maps a DefId of a type to a list of its inherent impls.
0 commit comments