@@ -389,16 +389,17 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
389389 for ( & def_id, anon_defn) in self . fcx . anon_types . borrow ( ) . iter ( ) {
390390 let node_id = self . tcx ( ) . hir . as_local_node_id ( def_id) . unwrap ( ) ;
391391 let instantiated_ty = self . resolve ( & anon_defn. concrete_ty , & node_id) ;
392- let mut definition_ty = self . fcx . infer_anon_definition_from_instantiation (
393- def_id,
394- anon_defn,
395- instantiated_ty,
396- ) ;
397392
398393 let generics = self . tcx ( ) . generics_of ( def_id) ;
399394
400- // named existential type, not an impl trait
401- if generics. parent . is_none ( ) {
395+ let definition_ty = if generics. parent . is_some ( ) {
396+ // impl trait
397+ self . fcx . infer_anon_definition_from_instantiation (
398+ def_id,
399+ anon_defn,
400+ instantiated_ty,
401+ )
402+ } else {
402403 // prevent
403404 // * `fn foo<T>() -> Foo<T>`
404405 // * `fn foo<T: Bound + Other>() -> Foo<T>`
@@ -411,9 +412,10 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
411412 // fn foo<U>() -> Foo<U> { .. }
412413 // ```
413414 // figures out the concrete type with `U`, but the stored type is with `T`
414- definition_ty = definition_ty . fold_with ( & mut BottomUpFolder {
415+ instantiated_ty . fold_with ( & mut BottomUpFolder {
415416 tcx : self . tcx ( ) . global_tcx ( ) ,
416417 fldop : |ty| {
418+ trace ! ( "checking type {:?}: {:#?}" , ty, ty. sty) ;
417419 // find a type parameter
418420 if let ty:: TyParam ( ..) = ty. sty {
419421 // look it up in the substitution list
@@ -445,8 +447,50 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
445447 }
446448 ty
447449 } ,
448- } ) ;
449- }
450+ reg_op : |region| {
451+ match region {
452+ // ignore static regions
453+ ty:: ReStatic => region,
454+ _ => {
455+ trace ! ( "checking {:?}" , region) ;
456+ for ( subst, p) in anon_defn. substs . iter ( ) . zip ( & generics. params ) {
457+ if let UnpackedKind :: Lifetime ( subst) = subst. unpack ( ) {
458+ if subst == region {
459+ // found it in the substitution list, replace with the
460+ // parameter from the existential type
461+ let reg = ty:: EarlyBoundRegion {
462+ def_id : p. def_id ,
463+ index : p. index ,
464+ name : p. name ,
465+ } ;
466+ trace ! ( "replace {:?} with {:?}" , region, reg) ;
467+ return self . tcx ( ) . global_tcx ( )
468+ . mk_region ( ty:: ReEarlyBound ( reg) ) ;
469+ }
470+ }
471+ }
472+ trace ! ( "anon_defn: {:#?}" , anon_defn) ;
473+ trace ! ( "generics: {:#?}" , generics) ;
474+ self . tcx ( ) . sess
475+ . struct_span_err (
476+ span,
477+ "non-defining existential type use in defining scope" ,
478+ )
479+ . span_label (
480+ span,
481+ format ! (
482+ "lifetime `{}` is part of concrete type but not used \
483+ in parameter list of existential type",
484+ region,
485+ ) ,
486+ )
487+ . emit ( ) ;
488+ self . tcx ( ) . global_tcx ( ) . mk_region ( ty:: ReStatic )
489+ }
490+ }
491+ }
492+ } )
493+ } ;
450494
451495 let old = self . tables . concrete_existential_types . insert ( def_id, definition_ty) ;
452496 if let Some ( old) = old {
0 commit comments