@@ -649,30 +649,74 @@ pub trait PrettyPrinter<'tcx>:
649649
650650 let mut first = true ;
651651 let mut is_sized = false ;
652+ let mut is_future = false ;
653+ let mut future_output_ty = None ;
654+
652655 p ! ( "impl" ) ;
653656 for ( predicate, _) in bounds {
654657 let predicate = predicate. subst ( self . tcx ( ) , substs) ;
655658 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+ }
662673 }
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+ }
663682
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+ _ => { }
669698 }
670699 }
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+
671714 if !is_sized {
672715 p ! ( write( "{}?Sized" , if first { " " } else { "+" } ) ) ;
673716 } else if first {
674717 p ! ( " Sized" ) ;
675718 }
719+
676720 Ok ( self )
677721 } ) ;
678722 }
0 commit comments