@@ -6,8 +6,8 @@ use rustc_hir::def::{DefKind, Res};
66use  rustc_middle:: ty:: print:: RegionHighlightMode ; 
77use  rustc_middle:: ty:: subst:: { GenericArgKind ,  SubstsRef } ; 
88use  rustc_middle:: ty:: { self ,  RegionVid ,  Ty } ; 
9- use  rustc_span:: symbol:: kw ; 
10- use  rustc_span:: { symbol :: Symbol ,   Span ,  DUMMY_SP } ; 
9+ use  rustc_span:: symbol:: { kw ,  sym ,   Ident ,   Symbol } ; 
10+ use  rustc_span:: { Span ,  DUMMY_SP } ; 
1111
1212use  crate :: borrow_check:: { nll:: ToRegionVid ,  universal_regions:: DefiningTy ,  MirBorrowckCtxt } ; 
1313
@@ -39,7 +39,7 @@ crate enum RegionNameSource {
3939    /// The region corresponding to a closure upvar. 
4040AnonRegionFromUpvar ( Span ,  String ) , 
4141    /// The region corresponding to the return type of a closure. 
42- AnonRegionFromOutput ( Span ,   String ,  String ) , 
42+ AnonRegionFromOutput ( RegionNameHighlight ,  String ) , 
4343    /// The region from a type yielded by a generator. 
4444AnonRegionFromYieldTy ( Span ,  String ) , 
4545    /// An anonymous region from an async fn. 
@@ -57,6 +57,10 @@ crate enum RegionNameHighlight {
5757    /// The anonymous region corresponds to a region where the type annotation is completely missing 
5858/// from the code, e.g. in a closure arguments `|x| { ... }`, where `x` is a reference. 
5959CannotMatchHirTy ( Span ,  String ) , 
60+     /// The anonymous region corresponds to a region where the type annotation is completely missing 
61+ /// from the code, and *even if* we print out the full name of the type, the region name won't 
62+ /// be included. This currently occurs for opaque types like `impl Future`. 
63+ Occluded ( Span ,  String ) , 
6064} 
6165
6266impl  RegionName  { 
@@ -81,13 +85,14 @@ impl RegionName {
8185            | RegionNameSource :: NamedFreeRegion ( span) 
8286            | RegionNameSource :: SynthesizedFreeEnvRegion ( span,  _) 
8387            | RegionNameSource :: AnonRegionFromUpvar ( span,  _) 
84-             | RegionNameSource :: AnonRegionFromOutput ( span,  _,  _) 
8588            | RegionNameSource :: AnonRegionFromYieldTy ( span,  _) 
8689            | RegionNameSource :: AnonRegionFromAsyncFn ( span)  => Some ( span) , 
87-             RegionNameSource :: AnonRegionFromArgument ( ref  highlight)  => match  * highlight { 
90+             RegionNameSource :: AnonRegionFromArgument ( ref  highlight) 
91+             | RegionNameSource :: AnonRegionFromOutput ( ref  highlight,  _)  => match  * highlight { 
8892                RegionNameHighlight :: MatchedHirTy ( span) 
8993                | RegionNameHighlight :: MatchedAdtAndSegment ( span) 
90-                 | RegionNameHighlight :: CannotMatchHirTy ( span,  _)  => Some ( span) , 
94+                 | RegionNameHighlight :: CannotMatchHirTy ( span,  _) 
95+                 | RegionNameHighlight :: Occluded ( span,  _)  => Some ( span) , 
9196            } , 
9297        } 
9398    } 
@@ -112,6 +117,7 @@ impl RegionName {
112117                diag. span_label ( * span,  format ! ( "has type `{}`" ,  type_name) ) ; 
113118            } 
114119            RegionNameSource :: AnonRegionFromArgument ( RegionNameHighlight :: MatchedHirTy ( span) ) 
120+             | RegionNameSource :: AnonRegionFromOutput ( RegionNameHighlight :: MatchedHirTy ( span) ,  _) 
115121            | RegionNameSource :: AnonRegionFromAsyncFn ( span)  => { 
116122                diag. span_label ( 
117123                    * span, 
@@ -120,16 +126,44 @@ impl RegionName {
120126            } 
121127            RegionNameSource :: AnonRegionFromArgument ( 
122128                RegionNameHighlight :: MatchedAdtAndSegment ( span) , 
129+             ) 
130+             | RegionNameSource :: AnonRegionFromOutput ( 
131+                 RegionNameHighlight :: MatchedAdtAndSegment ( span) , 
132+                 _, 
123133            )  => { 
124134                diag. span_label ( * span,  format ! ( "let's call this `{}`" ,  self ) ) ; 
125135            } 
136+             RegionNameSource :: AnonRegionFromArgument ( RegionNameHighlight :: Occluded ( 
137+                 span, 
138+                 type_name, 
139+             ) )  => { 
140+                 diag. span_label ( 
141+                     * span, 
142+                     format ! ( "lifetime `{}` appears in the type {}" ,  self ,  type_name) , 
143+                 ) ; 
144+             } 
145+             RegionNameSource :: AnonRegionFromOutput ( 
146+                 RegionNameHighlight :: Occluded ( span,  type_name) , 
147+                 mir_description, 
148+             )  => { 
149+                 diag. span_label ( 
150+                     * span, 
151+                     format ! ( 
152+                         "return type{} `{}` contains a lifetime `{}`" , 
153+                         mir_description,  type_name,  self 
154+                     ) , 
155+                 ) ; 
156+             } 
126157            RegionNameSource :: AnonRegionFromUpvar ( span,  upvar_name)  => { 
127158                diag. span_label ( 
128159                    * span, 
129160                    format ! ( "lifetime `{}` appears in the type of `{}`" ,  self ,  upvar_name) , 
130161                ) ; 
131162            } 
132-             RegionNameSource :: AnonRegionFromOutput ( span,  mir_description,  type_name)  => { 
163+             RegionNameSource :: AnonRegionFromOutput ( 
164+                 RegionNameHighlight :: CannotMatchHirTy ( span,  type_name) , 
165+                 mir_description, 
166+             )  => { 
133167                diag. span_label ( * span,  format ! ( "return type{} is {}" ,  mir_description,  type_name) ) ; 
134168            } 
135169            RegionNameSource :: AnonRegionFromYieldTy ( span,  type_name)  => { 
@@ -349,19 +383,21 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
349383            argument_index, 
350384        ) ; 
351385
352-         self . get_argument_hir_ty_for_highlighting ( argument_index) 
386+         let  highlight = self 
387+             . get_argument_hir_ty_for_highlighting ( argument_index) 
353388            . and_then ( |arg_hir_ty| self . highlight_if_we_can_match_hir_ty ( fr,  arg_ty,  arg_hir_ty) ) 
354-             . or_else ( || { 
389+             . unwrap_or_else ( || { 
355390                // `highlight_if_we_cannot_match_hir_ty` needs to know the number we will give to 
356391                // the anonymous region. If it succeeds, the `synthesize_region_name` call below 
357392                // will increment the counter, "reserving" the number we just used. 
358393                let  counter = * self . next_region_name . try_borrow ( ) . unwrap ( ) ; 
359394                self . highlight_if_we_cannot_match_hir_ty ( fr,  arg_ty,  span,  counter) 
360-             } ) 
361-             . map ( |highlight| RegionName  { 
362-                 name :  self . synthesize_region_name ( ) , 
363-                 source :  RegionNameSource :: AnonRegionFromArgument ( highlight) , 
364-             } ) 
395+             } ) ; 
396+ 
397+         Some ( RegionName  { 
398+             name :  self . synthesize_region_name ( ) , 
399+             source :  RegionNameSource :: AnonRegionFromArgument ( highlight) , 
400+         } ) 
365401    } 
366402
367403    fn  get_argument_hir_ty_for_highlighting ( 
@@ -399,7 +435,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
399435        ty :  Ty < ' tcx > , 
400436        span :  Span , 
401437        counter :  usize , 
402-     )  -> Option < RegionNameHighlight >  { 
438+     )  -> RegionNameHighlight  { 
403439        let  mut  highlight = RegionHighlightMode :: default ( ) ; 
404440        highlight. highlighting_region_vid ( needle_fr,  counter) ; 
405441        let  type_name =
@@ -411,9 +447,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
411447        ) ; 
412448        if  type_name. find ( & format ! ( "'{}" ,  counter) ) . is_some ( )  { 
413449            // Only add a label if we can confirm that a region was labelled. 
414-             Some ( RegionNameHighlight :: CannotMatchHirTy ( span,  type_name) ) 
450+             RegionNameHighlight :: CannotMatchHirTy ( span,  type_name) 
415451        }  else  { 
416-             None 
452+             RegionNameHighlight :: Occluded ( span ,  type_name ) 
417453        } 
418454    } 
419455
@@ -643,49 +679,131 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
643679/// or be early bound (named, not in argument). 
644680fn  give_name_if_anonymous_region_appears_in_output ( & self ,  fr :  RegionVid )  -> Option < RegionName >  { 
645681        let  tcx = self . infcx . tcx ; 
682+         let  hir = tcx. hir ( ) ; 
646683
647684        let  return_ty = self . regioncx . universal_regions ( ) . unnormalized_output_ty ; 
648685        debug ! ( "give_name_if_anonymous_region_appears_in_output: return_ty = {:?}" ,  return_ty) ; 
649686        if  !tcx. any_free_region_meets ( & return_ty,  |r| r. to_region_vid ( )  == fr)  { 
650687            return  None ; 
651688        } 
652689
653-         let  mut  highlight = RegionHighlightMode :: default ( ) ; 
654-         highlight. highlighting_region_vid ( fr,  * self . next_region_name . try_borrow ( ) . unwrap ( ) ) ; 
655-         let  type_name =
656-             self . infcx . extract_inference_diagnostics_data ( return_ty. into ( ) ,  Some ( highlight) ) . name ; 
690+         let  mir_hir_id = self . mir_hir_id ( ) ; 
657691
658-         let  ( return_span,  mir_description)  = match  tcx . hir ( ) . get ( self . mir_hir_id ( ) )  { 
692+         let  ( return_span,  mir_description,  hir_ty )  = match  hir. get ( mir_hir_id)  { 
659693            hir:: Node :: Expr ( hir:: Expr  { 
660-                 kind :  hir:: ExprKind :: Closure ( _,  return_ty,  _,  span,  gen_move) , 
661-                 ..
662-             } )  => ( 
663-                 match  return_ty. output  { 
664-                     hir:: FnRetTy :: DefaultReturn ( _)  => tcx. sess . source_map ( ) . end_point ( * span) , 
665-                     hir:: FnRetTy :: Return ( _)  => return_ty. output . span ( ) , 
666-                 } , 
667-                 if  gen_move. is_some ( )  {  " of generator"  }  else  {  " of closure"  } , 
668-             ) , 
669-             hir:: Node :: ImplItem ( hir:: ImplItem  { 
670-                 kind :  hir:: ImplItemKind :: Fn ( method_sig,  _) , 
694+                 kind :  hir:: ExprKind :: Closure ( _,  return_ty,  body_id,  span,  _) , 
671695                ..
672-             } )  => ( method_sig. decl . output . span ( ) ,  "" ) , 
673-             _ => ( self . body . span ,  "" ) , 
696+             } )  => { 
697+                 let  ( mut  span,  mut  hir_ty)  = match  return_ty. output  { 
698+                     hir:: FnRetTy :: DefaultReturn ( _)  => { 
699+                         ( tcx. sess . source_map ( ) . end_point ( * span) ,  None ) 
700+                     } 
701+                     hir:: FnRetTy :: Return ( hir_ty)  => ( return_ty. output . span ( ) ,  Some ( hir_ty) ) , 
702+                 } ; 
703+                 let  mir_description = match  hir. body ( * body_id) . generator_kind  { 
704+                     Some ( hir:: GeneratorKind :: Async ( gen) )  => match  gen { 
705+                         hir:: AsyncGeneratorKind :: Block  => " of async block" , 
706+                         hir:: AsyncGeneratorKind :: Closure  => " of async closure" , 
707+                         hir:: AsyncGeneratorKind :: Fn  => { 
708+                             let  parent_item = hir. get ( hir. get_parent_item ( mir_hir_id) ) ; 
709+                             let  output = & parent_item
710+                                 . fn_decl ( ) 
711+                                 . expect ( "generator lowered from async fn should be in fn" ) 
712+                                 . output ; 
713+                             span = output. span ( ) ; 
714+                             if  let  hir:: FnRetTy :: Return ( ret)  = output { 
715+                                 hir_ty = Some ( self . get_future_inner_return_ty ( * ret) ) ; 
716+                             } 
717+                             " of async function" 
718+                         } 
719+                     } , 
720+                     Some ( hir:: GeneratorKind :: Gen )  => " of generator" , 
721+                     None  => " of closure" , 
722+                 } ; 
723+                 ( span,  mir_description,  hir_ty) 
724+             } 
725+             node => match  node. fn_decl ( )  { 
726+                 Some ( fn_decl)  => { 
727+                     let  hir_ty = match  fn_decl. output  { 
728+                         hir:: FnRetTy :: DefaultReturn ( _)  => None , 
729+                         hir:: FnRetTy :: Return ( ty)  => Some ( ty) , 
730+                     } ; 
731+                     ( fn_decl. output . span ( ) ,  "" ,  hir_ty) 
732+                 } 
733+                 None  => ( self . body . span ,  "" ,  None ) , 
734+             } , 
674735        } ; 
675736
737+         let  highlight = hir_ty
738+             . and_then ( |hir_ty| self . highlight_if_we_can_match_hir_ty ( fr,  return_ty,  hir_ty) ) 
739+             . unwrap_or_else ( || { 
740+                 // `highlight_if_we_cannot_match_hir_ty` needs to know the number we will give to 
741+                 // the anonymous region. If it succeeds, the `synthesize_region_name` call below 
742+                 // will increment the counter, "reserving" the number we just used. 
743+                 let  counter = * self . next_region_name . try_borrow ( ) . unwrap ( ) ; 
744+                 self . highlight_if_we_cannot_match_hir_ty ( fr,  return_ty,  return_span,  counter) 
745+             } ) ; 
746+ 
676747        Some ( RegionName  { 
677-             // This counter value will already have been used, so this function will increment it 
678-             // so the next value will be used next and return the region name that would have been 
679-             // used. 
680748            name :  self . synthesize_region_name ( ) , 
681-             source :  RegionNameSource :: AnonRegionFromOutput ( 
682-                 return_span, 
683-                 mir_description. to_string ( ) , 
684-                 type_name, 
685-             ) , 
749+             source :  RegionNameSource :: AnonRegionFromOutput ( highlight,  mir_description. to_string ( ) ) , 
686750        } ) 
687751    } 
688752
753+     /// From the [`hir::Ty`] of an async function's lowered return type, 
754+ /// retrieve the `hir::Ty` representing the type the user originally wrote. 
755+ /// 
756+ /// e.g. given the function: 
757+ /// 
758+ /// ``` 
759+ /// async fn foo() -> i32 {} 
760+ /// ``` 
761+ /// 
762+ /// this function, given the lowered return type of `foo`, an [`OpaqueDef`] that implements `Future<Output=i32>`, 
763+ /// returns the `i32`. 
764+ /// 
765+ /// [`OpaqueDef`]: hir::TyKind::OpaqueDef 
766+ fn  get_future_inner_return_ty ( & self ,  hir_ty :  & ' tcx  hir:: Ty < ' tcx > )  -> & ' tcx  hir:: Ty < ' tcx >  { 
767+         let  hir = self . infcx . tcx . hir ( ) ; 
768+ 
769+         if  let  hir:: TyKind :: OpaqueDef ( id,  _)  = hir_ty. kind  { 
770+             let  opaque_ty = hir. item ( id. id ) ; 
771+             if  let  hir:: ItemKind :: OpaqueTy ( hir:: OpaqueTy  { 
772+                 bounds : 
773+                     [ hir:: GenericBound :: LangItemTrait ( 
774+                         hir:: LangItem :: Future , 
775+                         _, 
776+                         _, 
777+                         hir:: GenericArgs  { 
778+                             bindings : 
779+                                 [ hir:: TypeBinding  { 
780+                                     ident :  Ident  {  name :  sym:: Output ,  .. } , 
781+                                     kind :  hir:: TypeBindingKind :: Equality  {  ty } , 
782+                                     ..
783+                                 } ] , 
784+                             ..
785+                         } , 
786+                     ) ] , 
787+                 ..
788+             } )  = opaque_ty. kind 
789+             { 
790+                 ty
791+             }  else  { 
792+                 span_bug ! ( 
793+                     hir_ty. span, 
794+                     "bounds from lowered return type of async fn did not match expected format: {:?}" , 
795+                     opaque_ty
796+                 ) ; 
797+             } 
798+         }  else  { 
799+             span_bug ! ( 
800+                 hir_ty. span, 
801+                 "lowered return type of async fn is not OpaqueDef: {:?}" , 
802+                 hir_ty
803+             ) ; 
804+         } 
805+     } 
806+ 
689807    fn  give_name_if_anonymous_region_appears_in_yield_ty ( 
690808        & self , 
691809        fr :  RegionVid , 
0 commit comments