@@ -16,11 +16,13 @@ use middle::privacy::AccessLevels;
1616use mir;
1717use session:: CompileResult ;
1818use ty:: { self , CrateInherentImpls , Ty , TyCtxt } ;
19+ use ty:: item_path;
1920use ty:: subst:: Substs ;
2021use util:: nodemap:: NodeSet ;
2122
2223use rustc_data_structures:: indexed_vec:: IndexVec ;
2324use std:: cell:: { RefCell , RefMut } ;
25+ use std:: mem;
2426use std:: ops:: Deref ;
2527use std:: rc:: Rc ;
2628use syntax_pos:: { Span , DUMMY_SP } ;
@@ -122,24 +124,36 @@ pub struct CycleError<'a, 'tcx: 'a> {
122124
123125impl < ' a , ' gcx , ' tcx > TyCtxt < ' a , ' gcx , ' tcx > {
124126 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+ }
138151
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 ) ) ) ;
141154
142- err. emit ( ) ;
155+ err. emit ( ) ;
156+ } ) ;
143157 }
144158
145159 fn cycle_check < F , R > ( self , span : Span , query : Query < ' gcx > , compute : F )
@@ -306,6 +320,11 @@ macro_rules! define_maps {
306320 -> Result <R , CycleError <' a, $tcx>>
307321 where F : FnOnce ( & $V) -> R
308322 {
323+ debug!( "ty::queries::{}::try_get_with(key={:?}, span={:?})" ,
324+ stringify!( $name) ,
325+ key,
326+ span) ;
327+
309328 if let Some ( result) = tcx. maps. $name. borrow( ) . get( & key) {
310329 return Ok ( f( result) ) ;
311330 }
@@ -412,7 +431,7 @@ macro_rules! define_maps {
412431// the driver creates (using several `rustc_*` crates).
413432define_maps ! { <' tcx>
414433 /// Records the type of every item.
415- [ pub ] type_of: ItemSignature ( DefId ) -> Ty <' tcx>,
434+ [ ] type_of: ItemSignature ( DefId ) -> Ty <' tcx>,
416435
417436 /// Maps from the def-id of an item (trait/struct/enum/fn) to its
418437 /// associated generics and predicates.
@@ -451,7 +470,7 @@ define_maps! { <'tcx>
451470 /// Maps from a trait item to the trait item "descriptor"
452471 [ ] associated_item: AssociatedItems ( DefId ) -> ty:: AssociatedItem ,
453472
454- [ pub ] impl_trait_ref: ItemSignature ( DefId ) -> Option <ty:: TraitRef <' tcx>>,
473+ [ ] impl_trait_ref: ItemSignature ( DefId ) -> Option <ty:: TraitRef <' tcx>>,
455474 [ ] impl_polarity: ItemSignature ( DefId ) -> hir:: ImplPolarity ,
456475
457476 /// Maps a DefId of a type to a list of its inherent impls.
0 commit comments