@@ -17,11 +17,13 @@ use middle::privacy::AccessLevels;
1717use mir;
1818use session:: CompileResult ;
1919use ty:: { self , CrateInherentImpls , Ty , TyCtxt } ;
20+ use ty:: item_path;
2021use ty:: subst:: Substs ;
2122use util:: nodemap:: NodeSet ;
2223
2324use rustc_data_structures:: indexed_vec:: IndexVec ;
2425use std:: cell:: { RefCell , RefMut } ;
26+ use std:: mem;
2527use std:: ops:: Deref ;
2628use std:: rc:: Rc ;
2729use syntax_pos:: { Span , DUMMY_SP } ;
@@ -139,24 +141,36 @@ pub struct CycleError<'a, 'tcx: 'a> {
139141
140142impl < ' a , ' gcx , ' tcx > TyCtxt < ' a , ' gcx , ' tcx > {
141143 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+ }
155168
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 ) ) ) ;
158171
159- err. emit ( ) ;
172+ err. emit ( ) ;
173+ } ) ;
160174 }
161175
162176 fn cycle_check < F , R > ( self , span : Span , query : Query < ' gcx > , compute : F )
@@ -335,6 +349,11 @@ macro_rules! define_maps {
335349 -> Result <R , CycleError <' a, $tcx>>
336350 where F : FnOnce ( & $V) -> R
337351 {
352+ debug!( "ty::queries::{}::try_get_with(key={:?}, span={:?})" ,
353+ stringify!( $name) ,
354+ key,
355+ span) ;
356+
338357 if let Some ( result) = tcx. maps. $name. borrow( ) . get( & key) {
339358 return Ok ( f( result) ) ;
340359 }
@@ -441,7 +460,7 @@ macro_rules! define_maps {
441460// the driver creates (using several `rustc_*` crates).
442461define_maps ! { <' tcx>
443462 /// Records the type of every item.
444- [ pub ] type_of: ItemSignature ( DefId ) -> Ty <' tcx>,
463+ [ ] type_of: ItemSignature ( DefId ) -> Ty <' tcx>,
445464
446465 /// Maps from the def-id of an item (trait/struct/enum/fn) to its
447466 /// associated generics and predicates.
@@ -480,7 +499,7 @@ define_maps! { <'tcx>
480499 /// Maps from a trait item to the trait item "descriptor"
481500 [ ] associated_item: AssociatedItems ( DefId ) -> ty:: AssociatedItem ,
482501
483- [ pub ] impl_trait_ref: ItemSignature ( DefId ) -> Option <ty:: TraitRef <' tcx>>,
502+ [ ] impl_trait_ref: ItemSignature ( DefId ) -> Option <ty:: TraitRef <' tcx>>,
484503 [ ] impl_polarity: ItemSignature ( DefId ) -> hir:: ImplPolarity ,
485504
486505 /// Maps a DefId of a type to a list of its inherent impls.
0 commit comments