@@ -990,8 +990,9 @@ impl<'a> LoweringContext<'a> {
990990 struct ImplTraitLifetimeCollector < ' r , ' a : ' r > {
991991 context : & ' r mut LoweringContext < ' a > ,
992992 parent : DefIndex ,
993- currently_bound_lifetimes : Vec < Name > ,
994- already_defined_lifetimes : HashSet < Name > ,
993+ collect_elided_lifetimes : bool ,
994+ currently_bound_lifetimes : Vec < hir:: LifetimeName > ,
995+ already_defined_lifetimes : HashSet < hir:: LifetimeName > ,
995996 output_lifetimes : Vec < hir:: Lifetime > ,
996997 output_lifetime_defs : Vec < hir:: LifetimeDef > ,
997998 }
@@ -1002,6 +1003,30 @@ impl<'a> LoweringContext<'a> {
10021003 hir:: intravisit:: NestedVisitorMap :: None
10031004 }
10041005
1006+ fn visit_path_parameters ( & mut self , span : Span , parameters : & ' v hir:: PathParameters ) {
1007+ // Don't collect elided lifetimes used inside of `Fn()` syntax.
1008+ if parameters. parenthesized {
1009+ let old_collect_elided_lifetimes = self . collect_elided_lifetimes ;
1010+ self . collect_elided_lifetimes = false ;
1011+ hir:: intravisit:: walk_path_parameters ( self , span, parameters) ;
1012+ self . collect_elided_lifetimes = old_collect_elided_lifetimes;
1013+ } else {
1014+ hir:: intravisit:: walk_path_parameters ( self , span, parameters) ;
1015+ }
1016+ }
1017+
1018+ fn visit_ty ( & mut self , t : & ' v hir:: Ty ) {
1019+ // Don't collect elided lifetimes used inside of `fn()` syntax
1020+ if let & hir:: Ty_ :: TyBareFn ( _) = & t. node {
1021+ let old_collect_elided_lifetimes = self . collect_elided_lifetimes ;
1022+ self . collect_elided_lifetimes = false ;
1023+ hir:: intravisit:: walk_ty ( self , t) ;
1024+ self . collect_elided_lifetimes = old_collect_elided_lifetimes;
1025+ } else {
1026+ hir:: intravisit:: walk_ty ( self , t) ;
1027+ }
1028+ }
1029+
10051030 fn visit_poly_trait_ref ( & mut self ,
10061031 polytr : & ' v hir:: PolyTraitRef ,
10071032 _: hir:: TraitBoundModifier ) {
@@ -1010,10 +1035,8 @@ impl<'a> LoweringContext<'a> {
10101035 // Record the introduction of 'a in `for<'a> ...`
10111036 for lt_def in & polytr. bound_lifetimes {
10121037 // Introduce lifetimes one at a time so that we can handle
1013- // cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd> ...`
1014- if let hir:: LifetimeName :: Name ( name) = lt_def. lifetime . name {
1015- self . currently_bound_lifetimes . push ( name) ;
1016- }
1038+ // cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>`
1039+ self . currently_bound_lifetimes . push ( lt_def. lifetime . name ) ;
10171040
10181041 // Visit the lifetime bounds
10191042 for lt_bound in & lt_def. bounds {
@@ -1027,47 +1050,58 @@ impl<'a> LoweringContext<'a> {
10271050 }
10281051
10291052 fn visit_lifetime ( & mut self , lifetime : & ' v hir:: Lifetime ) {
1030- // Exclude '_, 'static, and elided lifetimes (there should be no elided lifetimes)
1031- if let hir:: LifetimeName :: Name ( lifetime_name ) = lifetime . name {
1032- if ! self . currently_bound_lifetimes . contains ( & lifetime_name ) &&
1033- ! self . already_defined_lifetimes . contains ( & lifetime_name )
1034- {
1035- self . already_defined_lifetimes . insert ( lifetime_name ) ;
1036- let name = hir:: LifetimeName :: Name ( lifetime_name ) ;
1037-
1038- self . output_lifetimes . push ( hir :: Lifetime {
1039- id : self . context . next_id ( ) . node_id ,
1040- span : lifetime . span ,
1041- name ,
1042- } ) ;
1053+ let name = match lifetime . name {
1054+ hir:: LifetimeName :: Implicit |
1055+ hir :: LifetimeName :: Underscore =>
1056+ if self . collect_elided_lifetimes {
1057+ // Use `'_` for both implicit and underscore lifetimes in
1058+ // `abstract type Foo<'_>: SomeTrait<'_>;`
1059+ hir:: LifetimeName :: Underscore
1060+ } else {
1061+ return
1062+ }
1063+ name @ hir :: LifetimeName :: Name ( _ ) => name ,
1064+ hir :: LifetimeName :: Static => return ,
1065+ } ;
10431066
1044- let def_node_id = self . context . next_id ( ) . node_id ;
1045- self . context . resolver . definitions ( ) . create_def_with_parent (
1046- self . parent ,
1047- def_node_id,
1048- DefPathData :: LifetimeDef ( lifetime_name. as_str ( ) ) ,
1049- DefIndexAddressSpace :: High ,
1050- Mark :: root ( )
1051- ) ;
1052- let def_lifetime = hir:: Lifetime {
1053- id : def_node_id,
1054- span : lifetime. span ,
1055- name,
1056- } ;
1057- self . output_lifetime_defs . push ( hir:: LifetimeDef {
1058- lifetime : def_lifetime,
1059- bounds : Vec :: new ( ) . into ( ) ,
1060- pure_wrt_drop : false ,
1061- in_band : false ,
1062- } ) ;
1063- }
1067+ if !self . currently_bound_lifetimes . contains ( & name) &&
1068+ !self . already_defined_lifetimes . contains ( & name)
1069+ {
1070+ self . already_defined_lifetimes . insert ( name) ;
1071+
1072+ self . output_lifetimes . push ( hir:: Lifetime {
1073+ id : self . context . next_id ( ) . node_id ,
1074+ span : lifetime. span ,
1075+ name,
1076+ } ) ;
1077+
1078+ let def_node_id = self . context . next_id ( ) . node_id ;
1079+ self . context . resolver . definitions ( ) . create_def_with_parent (
1080+ self . parent ,
1081+ def_node_id,
1082+ DefPathData :: LifetimeDef ( name. name ( ) . as_str ( ) ) ,
1083+ DefIndexAddressSpace :: High ,
1084+ Mark :: root ( )
1085+ ) ;
1086+ let def_lifetime = hir:: Lifetime {
1087+ id : def_node_id,
1088+ span : lifetime. span ,
1089+ name : name,
1090+ } ;
1091+ self . output_lifetime_defs . push ( hir:: LifetimeDef {
1092+ lifetime : def_lifetime,
1093+ bounds : Vec :: new ( ) . into ( ) ,
1094+ pure_wrt_drop : false ,
1095+ in_band : false ,
1096+ } ) ;
10641097 }
10651098 }
10661099 }
10671100
10681101 let mut lifetime_collector = ImplTraitLifetimeCollector {
10691102 context : self ,
10701103 parent : parent_index,
1104+ collect_elided_lifetimes : true ,
10711105 currently_bound_lifetimes : Vec :: new ( ) ,
10721106 already_defined_lifetimes : HashSet :: new ( ) ,
10731107 output_lifetimes : Vec :: new ( ) ,
0 commit comments