@@ -649,30 +649,74 @@ pub trait PrettyPrinter<'tcx>:
649
649
650
650
let mut first = true ;
651
651
let mut is_sized = false ;
652
+ let mut is_future = false ;
653
+ let mut future_output_ty = None ;
654
+
652
655
p ! ( "impl" ) ;
653
656
for ( predicate, _) in bounds {
654
657
let predicate = predicate. subst ( self . tcx ( ) , substs) ;
655
658
let bound_predicate = predicate. kind ( ) ;
656
- if let ty:: PredicateKind :: Trait ( pred) = bound_predicate. skip_binder ( ) {
657
- let trait_ref = bound_predicate. rebind ( pred. trait_ref ) ;
658
- // Don't print +Sized, but rather +?Sized if absent.
659
- if Some ( trait_ref. def_id ( ) ) == self . tcx ( ) . lang_items ( ) . sized_trait ( ) {
660
- is_sized = true ;
661
- continue ;
659
+
660
+ match bound_predicate. skip_binder ( ) {
661
+ ty:: PredicateKind :: Projection ( projection_predicate) => {
662
+ let Some ( future_trait) = self . tcx ( ) . lang_items ( ) . future_trait ( ) else { continue } ;
663
+ let future_output_def_id =
664
+ self . tcx ( ) . associated_item_def_ids ( future_trait) [ 0 ] ;
665
+
666
+ if projection_predicate. projection_ty . item_def_id
667
+ == future_output_def_id
668
+ {
669
+ // We don't account for multiple `Future::Output = Ty` contraints.
670
+ is_future = true ;
671
+ future_output_ty = Some ( projection_predicate. ty ) ;
672
+ }
662
673
}
674
+ ty:: PredicateKind :: Trait ( pred) => {
675
+ let trait_ref = bound_predicate. rebind ( pred. trait_ref ) ;
676
+ // Don't print +Sized, but rather +?Sized if absent.
677
+ if Some ( trait_ref. def_id ( ) ) == self . tcx ( ) . lang_items ( ) . sized_trait ( )
678
+ {
679
+ is_sized = true ;
680
+ continue ;
681
+ }
663
682
664
- p ! (
665
- write( "{}" , if first { " " } else { "+" } ) ,
666
- print( trait_ref. print_only_trait_path( ) )
667
- ) ;
668
- first = false ;
683
+ if Some ( trait_ref. def_id ( ) )
684
+ == self . tcx ( ) . lang_items ( ) . future_trait ( )
685
+ {
686
+ is_future = true ;
687
+ continue ;
688
+ }
689
+
690
+ p ! (
691
+ write( "{}" , if first { " " } else { "+" } ) ,
692
+ print( trait_ref. print_only_trait_path( ) )
693
+ ) ;
694
+
695
+ first = false ;
696
+ }
697
+ _ => { }
669
698
}
670
699
}
700
+
701
+ if is_future {
702
+ p ! ( write( "{}Future" , if first { " " } else { "+" } ) ) ;
703
+ first = false ;
704
+
705
+ if let Some ( future_output_ty) = future_output_ty {
706
+ // Don't print projection types, which we (unfortunately) see often
707
+ // in the error outputs involving async blocks.
708
+ if !matches ! ( future_output_ty. kind( ) , ty:: Projection ( _) ) {
709
+ p ! ( "<Output = " , print( future_output_ty) , ">" ) ;
710
+ }
711
+ }
712
+ }
713
+
671
714
if !is_sized {
672
715
p ! ( write( "{}?Sized" , if first { " " } else { "+" } ) ) ;
673
716
} else if first {
674
717
p ! ( " Sized" ) ;
675
718
}
719
+
676
720
Ok ( self )
677
721
} ) ;
678
722
}
0 commit comments