@@ -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 } ;
@@ -122,24 +124,36 @@ pub struct CycleError<'a, 'tcx: 'a> {
122
124
123
125
impl < ' a , ' gcx , ' tcx > TyCtxt < ' a , ' gcx , ' tcx > {
124
126
pub fn report_cycle ( self , CycleError { span, cycle } : CycleError ) {
125
- assert ! ( !cycle. is_empty( ) ) ;
126
-
127
- let mut err = struct_span_err ! ( self . sess, span, E0391 ,
128
- "unsupported cyclic reference between types/traits detected" ) ;
129
- err. span_label ( span, & format ! ( "cyclic reference" ) ) ;
130
-
131
- err. span_note ( cycle[ 0 ] . 0 , & format ! ( "the cycle begins when {}..." ,
132
- cycle[ 0 ] . 1 . describe( self ) ) ) ;
133
-
134
- for & ( span, ref query) in & cycle[ 1 ..] {
135
- err. span_note ( span, & format ! ( "...which then requires {}..." ,
136
- query. describe( self ) ) ) ;
137
- }
127
+ // Subtle: release the refcell lock before invoking `describe()`
128
+ // below by dropping `cycle`.
129
+ let stack = cycle. to_vec ( ) ;
130
+ mem:: drop ( cycle) ;
131
+
132
+ assert ! ( !stack. is_empty( ) ) ;
133
+
134
+ // Disable naming impls with types in this path, since that
135
+ // sometimes cycles itself, leading to extra cycle errors.
136
+ // (And cycle errors around impls tend to occur during the
137
+ // collect/coherence phases anyhow.)
138
+ item_path:: with_forced_impl_filename_line ( || {
139
+ let mut err =
140
+ struct_span_err ! ( self . sess, span, E0391 ,
141
+ "unsupported cyclic reference between types/traits detected" ) ;
142
+ err. span_label ( span, & format ! ( "cyclic reference" ) ) ;
143
+
144
+ err. span_note ( stack[ 0 ] . 0 , & format ! ( "the cycle begins when {}..." ,
145
+ stack[ 0 ] . 1 . describe( self ) ) ) ;
146
+
147
+ for & ( span, ref query) in & stack[ 1 ..] {
148
+ err. span_note ( span, & format ! ( "...which then requires {}..." ,
149
+ query. describe( self ) ) ) ;
150
+ }
138
151
139
- err. note ( & format ! ( "...which then again requires {}, completing the cycle." ,
140
- cycle [ 0 ] . 1 . describe( self ) ) ) ;
152
+ err. note ( & format ! ( "...which then again requires {}, completing the cycle." ,
153
+ stack [ 0 ] . 1 . describe( self ) ) ) ;
141
154
142
- err. emit ( ) ;
155
+ err. emit ( ) ;
156
+ } ) ;
143
157
}
144
158
145
159
fn cycle_check < F , R > ( self , span : Span , query : Query < ' gcx > , compute : F )
@@ -306,6 +320,11 @@ macro_rules! define_maps {
306
320
-> Result <R , CycleError <' a, $tcx>>
307
321
where F : FnOnce ( & $V) -> R
308
322
{
323
+ debug!( "ty::queries::{}::try_get_with(key={:?}, span={:?})" ,
324
+ stringify!( $name) ,
325
+ key,
326
+ span) ;
327
+
309
328
if let Some ( result) = tcx. maps. $name. borrow( ) . get( & key) {
310
329
return Ok ( f( result) ) ;
311
330
}
@@ -412,7 +431,7 @@ macro_rules! define_maps {
412
431
// the driver creates (using several `rustc_*` crates).
413
432
define_maps ! { <' tcx>
414
433
/// Records the type of every item.
415
- [ pub ] type_of: ItemSignature ( DefId ) -> Ty <' tcx>,
434
+ [ ] type_of: ItemSignature ( DefId ) -> Ty <' tcx>,
416
435
417
436
/// Maps from the def-id of an item (trait/struct/enum/fn) to its
418
437
/// associated generics and predicates.
@@ -451,7 +470,7 @@ define_maps! { <'tcx>
451
470
/// Maps from a trait item to the trait item "descriptor"
452
471
[ ] associated_item: AssociatedItems ( DefId ) -> ty:: AssociatedItem ,
453
472
454
- [ pub ] impl_trait_ref: ItemSignature ( DefId ) -> Option <ty:: TraitRef <' tcx>>,
473
+ [ ] impl_trait_ref: ItemSignature ( DefId ) -> Option <ty:: TraitRef <' tcx>>,
455
474
[ ] impl_polarity: ItemSignature ( DefId ) -> hir:: ImplPolarity ,
456
475
457
476
/// Maps a DefId of a type to a list of its inherent impls.
0 commit comments