@@ -67,6 +67,9 @@ pub struct OpaqueTypeDecl<'tcx> {
67
67
/// the fn body). (Ultimately, writeback is responsible for this
68
68
/// check.)
69
69
pub has_required_region_bounds : bool ,
70
+
71
+ /// The origin of the existential type
72
+ pub origin : hir:: ExistTyOrigin ,
70
73
}
71
74
72
75
impl < ' a , ' gcx , ' tcx > InferCtxt < ' a , ' gcx , ' tcx > {
@@ -326,14 +329,39 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
326
329
// There are two regions (`lr` and
327
330
// `subst_arg`) which are not relatable. We can't
328
331
// 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
330
339
. 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
+ `async fn`.") ;
361
+ err. note ( "if you're using argument-position elided lifetimes, consider \
362
+ switching to a single named lifetime.") ;
363
+ }
364
+ err. emit ( ) ;
337
365
338
366
least_region = Some ( self . tcx . mk_region ( ty:: ReEmpty ) ) ;
339
367
break ;
@@ -692,39 +720,49 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
692
720
parent_def_id == tcx. hir ( )
693
721
. local_def_id_from_hir_id ( opaque_parent_hir_id)
694
722
} ;
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
+ {
696
726
Some ( Node :: Item ( item) ) => match item. node {
697
727
// impl trait
698
728
hir:: ItemKind :: Existential ( hir:: ExistTy {
699
729
impl_trait_fn : Some ( parent) ,
730
+ origin,
700
731
..
701
- } ) => parent == self . parent_def_id ,
732
+ } ) => ( parent == self . parent_def_id , origin ) ,
702
733
// named existential types
703
734
hir:: ItemKind :: Existential ( hir:: ExistTy {
704
735
impl_trait_fn : None ,
736
+ origin,
705
737
..
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,
710
745
) ,
711
- _ => def_scope_default ( ) ,
746
+ _ => ( def_scope_default ( ) , hir :: ExistTyOrigin :: ExistentialType ) ,
712
747
} ,
713
748
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 ,
718
756
) ,
719
- _ => def_scope_default ( ) ,
757
+ _ => ( def_scope_default ( ) , hir :: ExistTyOrigin :: ExistentialType ) ,
720
758
} ,
721
759
_ => bug ! (
722
760
"expected (impl) item, found {}" ,
723
761
tcx. hir( ) . hir_to_string( opaque_hir_id) ,
724
762
) ,
725
763
} ;
726
764
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 ) ;
728
766
}
729
767
730
768
debug ! (
@@ -746,6 +784,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
746
784
ty : Ty < ' tcx > ,
747
785
def_id : DefId ,
748
786
substs : SubstsRef < ' tcx > ,
787
+ origin : hir:: ExistTyOrigin ,
749
788
) -> Ty < ' tcx > {
750
789
let infcx = self . infcx ;
751
790
let tcx = infcx. tcx ;
@@ -795,6 +834,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
795
834
substs,
796
835
concrete_ty : ty_var,
797
836
has_required_region_bounds : !required_region_bounds. is_empty ( ) ,
837
+ origin,
798
838
} ,
799
839
) ;
800
840
debug ! ( "instantiate_opaque_types: ty_var={:?}" , ty_var) ;
0 commit comments