@@ -49,6 +49,24 @@ macro_rules! define_scoped_cx {
4949thread_local ! {
5050 static FORCE_IMPL_FILENAME_LINE : Cell <bool > = Cell :: new( false ) ;
5151 static SHOULD_PREFIX_WITH_CRATE : Cell <bool > = Cell :: new( false ) ;
52+ static NO_QUERIES : Cell <bool > = Cell :: new( false ) ;
53+ }
54+
55+ /// Avoids running any queries during any prints that occur
56+ /// during the closure. This may alter the apperance of some
57+ /// types (e.g. forcing verbose printing for opaque types).
58+ /// This method is used during some queries (e.g. `predicates_of`
59+ /// for opaque types), to ensure that any debug printing that
60+ /// occurs during the query computation does not end up recursively
61+ /// calling the same query.
62+ pub fn with_no_queries < F : FnOnce ( ) -> R , R > ( f : F ) -> R {
63+ NO_QUERIES . with ( |no_queries| {
64+ let old = no_queries. get ( ) ;
65+ no_queries. set ( true ) ;
66+ let result = f ( ) ;
67+ no_queries. set ( old) ;
68+ result
69+ } )
5270}
5371
5472/// Force us to name impls with just the filename/line number. We
@@ -556,52 +574,61 @@ pub trait PrettyPrinter<'tcx>:
556574 }
557575 ty:: Opaque ( def_id, substs) => {
558576 // FIXME(eddyb) print this with `print_def_path`.
559- if self . tcx ( ) . sess . verbose ( ) {
577+ // We use verbose printing in 'NO_QUERIES' mode, to
578+ // avoid needing to call `predicates_of`. This should
579+ // only affect certain debug messages (e.g. messages printed
580+ // from `rustc::ty` during the computation of `tcx.predicates_of`),
581+ // and should have no effect on any compiler output.
582+ if self . tcx ( ) . sess . verbose ( ) || NO_QUERIES . with ( |q| q. get ( ) ) {
560583 p ! ( write( "Opaque({:?}, {:?})" , def_id, substs) ) ;
561584 return Ok ( self ) ;
562585 }
563586
564- let def_key = self . tcx ( ) . def_key ( def_id) ;
565- if let Some ( name) = def_key. disambiguated_data . data . get_opt_name ( ) {
566- p ! ( write( "{}" , name) ) ;
567- let mut substs = substs. iter ( ) ;
568- // FIXME(eddyb) print this with `print_def_path`.
569- if let Some ( first) = substs. next ( ) {
570- p ! ( write( "::<" ) ) ;
571- p ! ( print( first) ) ;
572- for subst in substs {
573- p ! ( write( ", " ) , print( subst) ) ;
587+ return Ok ( with_no_queries ( || {
588+
589+ let def_key = self . tcx ( ) . def_key ( def_id) ;
590+ if let Some ( name) = def_key. disambiguated_data . data . get_opt_name ( ) {
591+ p ! ( write( "{}" , name) ) ;
592+ let mut substs = substs. iter ( ) ;
593+ // FIXME(eddyb) print this with `print_def_path`.
594+ if let Some ( first) = substs. next ( ) {
595+ p ! ( write( "::<" ) ) ;
596+ p ! ( print( first) ) ;
597+ for subst in substs {
598+ p ! ( write( ", " ) , print( subst) ) ;
599+ }
600+ p ! ( write( ">" ) ) ;
574601 }
575- p ! ( write ( ">" ) ) ;
602+ return Ok ( self ) ;
576603 }
577- return Ok ( self ) ;
578- }
579- // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
580- // by looking up the projections associated with the def_id.
581- let bounds = self . tcx ( ) . predicates_of ( def_id) . instantiate ( self . tcx ( ) , substs) ;
582-
583- let mut first = true ;
584- let mut is_sized = false ;
585- p ! ( write( "impl" ) ) ;
586- for predicate in bounds. predicates {
587- if let Some ( trait_ref) = predicate. to_opt_poly_trait_ref ( ) {
588- // Don't print +Sized, but rather +?Sized if absent.
589- if Some ( trait_ref. def_id ( ) ) == self . tcx ( ) . lang_items ( ) . sized_trait ( ) {
590- is_sized = true ;
591- continue ;
592- }
604+ // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
605+ // by looking up the projections associated with the def_id.
606+ let bounds = self . tcx ( ) . predicates_of ( def_id) . instantiate ( self . tcx ( ) , substs) ;
607+
608+ let mut first = true ;
609+ let mut is_sized = false ;
610+ p ! ( write( "impl" ) ) ;
611+ for predicate in bounds. predicates {
612+ if let Some ( trait_ref) = predicate. to_opt_poly_trait_ref ( ) {
613+ // Don't print +Sized, but rather +?Sized if absent.
614+ if Some ( trait_ref. def_id ( ) ) == self . tcx ( ) . lang_items ( ) . sized_trait ( ) {
615+ is_sized = true ;
616+ continue ;
617+ }
593618
594- p ! (
595- write( "{}" , if first { " " } else { "+" } ) ,
596- print( trait_ref) ) ;
597- first = false ;
619+ p ! (
620+ write( "{}" , if first { " " } else { "+" } ) ,
621+ print( trait_ref) ) ;
622+ first = false ;
623+ }
598624 }
599- }
600- if !is_sized {
601- p ! ( write( "{}?Sized" , if first { " " } else { "+" } ) ) ;
602- } else if first {
603- p ! ( write( " Sized" ) ) ;
604- }
625+ if !is_sized {
626+ p ! ( write( "{}?Sized" , if first { " " } else { "+" } ) ) ;
627+ } else if first {
628+ p ! ( write( " Sized" ) ) ;
629+ }
630+ Ok ( self )
631+ } ) ?) ;
605632 }
606633 ty:: Str => p ! ( write( "str" ) ) ,
607634 ty:: Generator ( did, substs, movability) => {
0 commit comments