@@ -67,6 +67,9 @@ pub struct OpaqueTypeDecl<'tcx> {
6767/// the fn body). (Ultimately, writeback is responsible for this 
6868/// check.) 
6969pub  has_required_region_bounds :  bool , 
70+ 
71+     /// The origin of the existential type 
72+ pub  origin :  hir:: ExistTyOrigin , 
7073} 
7174
7275impl < ' a ,  ' gcx ,  ' tcx >  InferCtxt < ' a ,  ' gcx ,  ' tcx >  { 
@@ -326,14 +329,39 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
326329                        // There are two regions (`lr` and 
327330                        // `subst_arg`) which are not relatable. We can't 
328331                        // find a best choice. 
329-                         self . tcx 
332+                         let  context_name = match  opaque_defn. origin  { 
333+                             hir:: ExistTyOrigin :: ExistentialType  => "existential type" , 
334+                             hir:: ExistTyOrigin :: ReturnImplTrait  => "impl Trait" , 
335+                             hir:: ExistTyOrigin :: AsyncFn  => "async fn" , 
336+                         } ; 
337+                         let  msg = format ! ( "ambiguous lifetime bound in `{}`" ,  context_name) ; 
338+                         let  mut  err = self . tcx 
330339                            . sess 
331-                             . struct_span_err ( span,  "ambiguous lifetime bound in `impl Trait`" ) 
332-                             . span_label ( 
333-                                 span, 
334-                                 format ! ( "neither `{}` nor `{}` outlives the other" ,  lr,  subst_arg) , 
335-                             ) 
336-                             . emit ( ) ; 
340+                             . struct_span_err ( span,  & msg) ; 
341+ 
342+                         let  lr_name = lr. to_string ( ) ; 
343+                         let  subst_arg_name = subst_arg. to_string ( ) ; 
344+                         let  label_owned; 
345+                         let  label = match  ( & * lr_name,  & * subst_arg_name)  { 
346+                             ( "'_" ,  "'_" )  => "the elided lifetimes here do not outlive one another" , 
347+                             _ => { 
348+                                 label_owned = format ! ( 
349+                                     "neither `{}` nor `{}` outlives the other" , 
350+                                     lr_name, 
351+                                     subst_arg_name, 
352+                                 ) ; 
353+                                 & label_owned
354+                             } 
355+                         } ; 
356+                         err. span_label ( span,  label) ; 
357+ 
358+                         if  let  hir:: ExistTyOrigin :: AsyncFn  = opaque_defn. origin  { 
359+                             err. note ( "multiple unrelated lifetimes are not allowed in \  
360+ ) ; 
361+                             err. note ( "if you're using argument-position elided lifetimes, consider \  
362+ ) ; 
363+                         } 
364+                         err. emit ( ) ; 
337365
338366                        least_region = Some ( self . tcx . mk_region ( ty:: ReEmpty ) ) ; 
339367                        break ; 
@@ -692,39 +720,49 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
692720                            parent_def_id == tcx. hir ( ) 
693721                                                . local_def_id_from_hir_id ( opaque_parent_hir_id) 
694722                        } ; 
695-                         let  in_definition_scope = match  tcx. hir ( ) . find_by_hir_id ( opaque_hir_id)  { 
723+                         let  ( in_definition_scope,  origin)  =
724+                             match  tcx. hir ( ) . find_by_hir_id ( opaque_hir_id) 
725+                         { 
696726                            Some ( Node :: Item ( item) )  => match  item. node  { 
697727                                // impl trait 
698728                                hir:: ItemKind :: Existential ( hir:: ExistTy  { 
699729                                    impl_trait_fn :  Some ( parent) , 
730+                                     origin, 
700731                                    ..
701-                                 } )  => parent == self . parent_def_id , 
732+                                 } )  => ( parent == self . parent_def_id ,  origin ) , 
702733                                // named existential types 
703734                                hir:: ItemKind :: Existential ( hir:: ExistTy  { 
704735                                    impl_trait_fn :  None , 
736+                                     origin, 
705737                                    ..
706-                                 } )  => may_define_existential_type ( 
707-                                     tcx, 
708-                                     self . parent_def_id , 
709-                                     opaque_hir_id, 
738+                                 } )  => ( 
739+                                     may_define_existential_type ( 
740+                                         tcx, 
741+                                         self . parent_def_id , 
742+                                         opaque_hir_id, 
743+                                     ) , 
744+                                     origin, 
710745                                ) , 
711-                                 _ => def_scope_default ( ) , 
746+                                 _ => ( def_scope_default ( ) ,  hir :: ExistTyOrigin :: ExistentialType ) , 
712747                            } , 
713748                            Some ( Node :: ImplItem ( item) )  => match  item. node  { 
714-                                 hir:: ImplItemKind :: Existential ( _)  => may_define_existential_type ( 
715-                                     tcx, 
716-                                     self . parent_def_id , 
717-                                     opaque_hir_id, 
749+                                 hir:: ImplItemKind :: Existential ( _)  => ( 
750+                                     may_define_existential_type ( 
751+                                         tcx, 
752+                                         self . parent_def_id , 
753+                                         opaque_hir_id, 
754+                                     ) , 
755+                                     hir:: ExistTyOrigin :: ExistentialType , 
718756                                ) , 
719-                                 _ => def_scope_default ( ) , 
757+                                 _ => ( def_scope_default ( ) ,  hir :: ExistTyOrigin :: ExistentialType ) , 
720758                            } , 
721759                            _ => bug ! ( 
722760                                "expected (impl) item, found {}" , 
723761                                tcx. hir( ) . hir_to_string( opaque_hir_id) , 
724762                            ) , 
725763                        } ; 
726764                        if  in_definition_scope { 
727-                             return  self . fold_opaque_ty ( ty,  def_id,  substs) ; 
765+                             return  self . fold_opaque_ty ( ty,  def_id,  substs,  origin ) ; 
728766                        } 
729767
730768                        debug ! ( 
@@ -746,6 +784,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
746784        ty :  Ty < ' tcx > , 
747785        def_id :  DefId , 
748786        substs :  SubstsRef < ' tcx > , 
787+         origin :  hir:: ExistTyOrigin , 
749788    )  -> Ty < ' tcx >  { 
750789        let  infcx = self . infcx ; 
751790        let  tcx = infcx. tcx ; 
@@ -795,6 +834,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
795834                substs, 
796835                concrete_ty :  ty_var, 
797836                has_required_region_bounds :  !required_region_bounds. is_empty ( ) , 
837+                 origin, 
798838            } , 
799839        ) ; 
800840        debug ! ( "instantiate_opaque_types: ty_var={:?}" ,  ty_var) ; 
0 commit comments