@@ -990,8 +990,9 @@ impl<'a> LoweringContext<'a> {
990
990
struct ImplTraitLifetimeCollector < ' r , ' a : ' r > {
991
991
context : & ' r mut LoweringContext < ' a > ,
992
992
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 > ,
995
996
output_lifetimes : Vec < hir:: Lifetime > ,
996
997
output_lifetime_defs : Vec < hir:: LifetimeDef > ,
997
998
}
@@ -1002,6 +1003,30 @@ impl<'a> LoweringContext<'a> {
1002
1003
hir:: intravisit:: NestedVisitorMap :: None
1003
1004
}
1004
1005
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
+
1005
1030
fn visit_poly_trait_ref ( & mut self ,
1006
1031
polytr : & ' v hir:: PolyTraitRef ,
1007
1032
_: hir:: TraitBoundModifier ) {
@@ -1010,10 +1035,8 @@ impl<'a> LoweringContext<'a> {
1010
1035
// Record the introduction of 'a in `for<'a> ...`
1011
1036
for lt_def in & polytr. bound_lifetimes {
1012
1037
// 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 ) ;
1017
1040
1018
1041
// Visit the lifetime bounds
1019
1042
for lt_bound in & lt_def. bounds {
@@ -1027,47 +1050,58 @@ impl<'a> LoweringContext<'a> {
1027
1050
}
1028
1051
1029
1052
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
+ } ;
1043
1066
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
+ } ) ;
1064
1097
}
1065
1098
}
1066
1099
}
1067
1100
1068
1101
let mut lifetime_collector = ImplTraitLifetimeCollector {
1069
1102
context : self ,
1070
1103
parent : parent_index,
1104
+ collect_elided_lifetimes : true ,
1071
1105
currently_bound_lifetimes : Vec :: new ( ) ,
1072
1106
already_defined_lifetimes : HashSet :: new ( ) ,
1073
1107
output_lifetimes : Vec :: new ( ) ,
0 commit comments