@@ -49,6 +49,24 @@ macro_rules! define_scoped_cx {
49
49
thread_local ! {
50
50
static FORCE_IMPL_FILENAME_LINE : Cell <bool > = Cell :: new( false ) ;
51
51
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
+ } )
52
70
}
53
71
54
72
/// Force us to name impls with just the filename/line number. We
@@ -556,52 +574,61 @@ pub trait PrettyPrinter<'tcx>:
556
574
}
557
575
ty:: Opaque ( def_id, substs) => {
558
576
// 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 ( ) ) {
560
583
p ! ( write( "Opaque({:?}, {:?})" , def_id, substs) ) ;
561
584
return Ok ( self ) ;
562
585
}
563
586
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( ">" ) ) ;
574
601
}
575
- p ! ( write ( ">" ) ) ;
602
+ return Ok ( self ) ;
576
603
}
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
+ }
593
618
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
+ }
598
624
}
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
+ } ) ?) ;
605
632
}
606
633
ty:: Str => p ! ( write( "str" ) ) ,
607
634
ty:: Generator ( did, substs, movability) => {
0 commit comments