@@ -15,83 +15,112 @@ use triomphe::Arc;
15
15
16
16
use crate :: {
17
17
GenericDefId , TypeOrConstParamId , TypeParamId ,
18
- expr_store:: lower:: ExprCollector ,
18
+ expr_store:: { TypePtr , lower:: ExprCollector } ,
19
19
hir:: generics:: {
20
20
ConstParamData , GenericParams , LifetimeParamData , TypeOrConstParamData , TypeParamData ,
21
- TypeParamProvenance , WherePredicate , WherePredicateTypeTarget ,
21
+ TypeParamProvenance , WherePredicate ,
22
22
} ,
23
23
type_ref:: { LifetimeRef , TypeBound , TypeRef , TypeRefId } ,
24
24
} ;
25
25
26
- pub ( crate ) struct GenericParamsCollector < ' db , ' c > {
27
- expr_collector : & ' c mut ExprCollector < ' db > ,
26
+ pub ( crate ) type ImplTraitLowerFn < ' l > = & ' l mut dyn for <' ec , ' db > FnMut (
27
+ & ' ec mut ExprCollector < ' db > ,
28
+ TypePtr ,
29
+ ThinVec < TypeBound > ,
30
+ ) -> TypeRefId ;
31
+
32
+ pub ( crate ) struct GenericParamsCollector {
28
33
type_or_consts : Arena < TypeOrConstParamData > ,
29
34
lifetimes : Arena < LifetimeParamData > ,
30
35
where_predicates : Vec < WherePredicate > ,
31
36
parent : GenericDefId ,
32
37
}
33
38
34
- impl < ' db , ' c > GenericParamsCollector < ' db , ' c > {
35
- pub ( crate ) fn new ( expr_collector : & ' c mut ExprCollector < ' db > , parent : GenericDefId ) -> Self {
39
+ impl GenericParamsCollector {
40
+ pub ( crate ) fn new ( parent : GenericDefId ) -> Self {
36
41
Self {
37
- expr_collector,
38
42
type_or_consts : Default :: default ( ) ,
39
43
lifetimes : Default :: default ( ) ,
40
44
where_predicates : Default :: default ( ) ,
41
45
parent,
42
46
}
43
47
}
44
-
45
- pub ( crate ) fn fill_self_param ( & mut self , bounds : Option < ast:: TypeBoundList > ) {
46
- let self_ = Name :: new_symbol_root ( sym:: Self_ ) ;
47
- let idx = self . type_or_consts . alloc (
48
- TypeParamData {
49
- name : Some ( self_. clone ( ) ) ,
50
- default : None ,
51
- provenance : TypeParamProvenance :: TraitSelf ,
52
- }
53
- . into ( ) ,
54
- ) ;
55
- let type_ref = TypeRef :: TypeParam ( TypeParamId :: from_unchecked ( TypeOrConstParamId {
56
- parent : self . parent ,
57
- local_id : idx,
58
- } ) ) ;
59
- let self_ = self . expr_collector . alloc_type_ref_desugared ( type_ref) ;
60
- if let Some ( bounds) = bounds {
61
- self . lower_bounds ( Some ( bounds) , Either :: Left ( self_) ) ;
62
- }
48
+ pub ( crate ) fn with_self_param (
49
+ ec : & mut ExprCollector < ' _ > ,
50
+ parent : GenericDefId ,
51
+ bounds : Option < ast:: TypeBoundList > ,
52
+ ) -> Self {
53
+ let mut this = Self :: new ( parent) ;
54
+ this. fill_self_param ( ec, bounds) ;
55
+ this
63
56
}
64
57
65
58
pub ( crate ) fn lower (
66
59
& mut self ,
60
+ ec : & mut ExprCollector < ' _ > ,
67
61
generic_param_list : Option < ast:: GenericParamList > ,
68
62
where_clause : Option < ast:: WhereClause > ,
69
63
) {
70
64
if let Some ( params) = generic_param_list {
71
- self . lower_param_list ( params)
65
+ self . lower_param_list ( ec , params)
72
66
}
73
67
if let Some ( where_clause) = where_clause {
74
- self . lower_where_predicates ( where_clause) ;
68
+ self . lower_where_predicates ( ec , where_clause) ;
75
69
}
76
70
}
77
71
78
- fn lower_param_list ( & mut self , params : ast:: GenericParamList ) {
72
+ pub ( crate ) fn collect_impl_trait < R > (
73
+ & mut self ,
74
+ ec : & mut ExprCollector < ' _ > ,
75
+ cb : impl FnOnce ( & mut ExprCollector < ' _ > , ImplTraitLowerFn < ' _ > ) -> R ,
76
+ ) -> R {
77
+ cb (
78
+ ec,
79
+ & mut Self :: lower_argument_impl_trait (
80
+ & mut self . type_or_consts ,
81
+ & mut self . where_predicates ,
82
+ self . parent ,
83
+ ) ,
84
+ )
85
+ }
86
+
87
+ pub ( crate ) fn finish ( self ) -> Arc < GenericParams > {
88
+ let Self { mut lifetimes, mut type_or_consts, mut where_predicates, parent : _ } = self ;
89
+
90
+ if lifetimes. is_empty ( ) && type_or_consts. is_empty ( ) && where_predicates. is_empty ( ) {
91
+ static EMPTY : LazyLock < Arc < GenericParams > > = LazyLock :: new ( || {
92
+ Arc :: new ( GenericParams {
93
+ lifetimes : Arena :: new ( ) ,
94
+ type_or_consts : Arena :: new ( ) ,
95
+ where_predicates : Box :: default ( ) ,
96
+ } )
97
+ } ) ;
98
+ return Arc :: clone ( & EMPTY ) ;
99
+ }
100
+
101
+ lifetimes. shrink_to_fit ( ) ;
102
+ type_or_consts. shrink_to_fit ( ) ;
103
+ where_predicates. shrink_to_fit ( ) ;
104
+ Arc :: new ( GenericParams {
105
+ type_or_consts,
106
+ lifetimes,
107
+ where_predicates : where_predicates. into_boxed_slice ( ) ,
108
+ } )
109
+ }
110
+
111
+ fn lower_param_list ( & mut self , ec : & mut ExprCollector < ' _ > , params : ast:: GenericParamList ) {
79
112
for generic_param in params. generic_params ( ) {
80
- let enabled = self . expr_collector . expander . is_cfg_enabled (
81
- self . expr_collector . db ,
82
- self . expr_collector . module . krate ( ) ,
83
- & generic_param,
84
- ) ;
113
+ let enabled = ec. expander . is_cfg_enabled ( ec. db , ec. module . krate ( ) , & generic_param) ;
85
114
if !enabled {
86
115
continue ;
87
116
}
88
117
89
118
match generic_param {
90
119
ast:: GenericParam :: TypeParam ( type_param) => {
91
120
let name = type_param. name ( ) . map_or_else ( Name :: missing, |it| it. as_name ( ) ) ;
92
- let default = type_param
93
- . default_type ( )
94
- . map ( |it| self . expr_collector . lower_type_ref ( it , & mut |_| TypeRef :: Error ) ) ;
121
+ let default = type_param. default_type ( ) . map ( |it| {
122
+ ec . lower_type_ref ( it , & mut ExprCollector :: impl_trait_error_allocator )
123
+ } ) ;
95
124
let param = TypeParamData {
96
125
name : Some ( name. clone ( ) ) ,
97
126
default,
@@ -103,30 +132,29 @@ impl<'db, 'c> GenericParamsCollector<'db, 'c> {
103
132
parent : self . parent ,
104
133
local_id : idx,
105
134
} ) ) ;
106
- let type_ref = self . expr_collector . alloc_type_ref_desugared ( type_ref) ;
107
- self . lower_bounds ( type_param. type_bound_list ( ) , Either :: Left ( type_ref) ) ;
135
+ let type_ref = ec . alloc_type_ref_desugared ( type_ref) ;
136
+ self . lower_bounds ( ec , type_param. type_bound_list ( ) , Either :: Left ( type_ref) ) ;
108
137
}
109
138
ast:: GenericParam :: ConstParam ( const_param) => {
110
139
let name = const_param. name ( ) . map_or_else ( Name :: missing, |it| it. as_name ( ) ) ;
111
- let ty = self
112
- . expr_collector
113
- . lower_type_ref_opt ( const_param. ty ( ) , & mut |_| TypeRef :: Error ) ;
140
+ let ty = ec. lower_type_ref_opt (
141
+ const_param. ty ( ) ,
142
+ & mut ExprCollector :: impl_trait_error_allocator,
143
+ ) ;
114
144
let param = ConstParamData {
115
145
name,
116
146
ty,
117
- default : const_param
118
- . default_val ( )
119
- . map ( |it| self . expr_collector . lower_const_arg ( it) ) ,
147
+ default : const_param. default_val ( ) . map ( |it| ec. lower_const_arg ( it) ) ,
120
148
} ;
121
149
let _idx = self . type_or_consts . alloc ( param. into ( ) ) ;
122
150
}
123
151
ast:: GenericParam :: LifetimeParam ( lifetime_param) => {
124
- let lifetime_ref =
125
- self . expr_collector . lower_lifetime_ref_opt ( lifetime_param. lifetime ( ) ) ;
152
+ let lifetime_ref = ec. lower_lifetime_ref_opt ( lifetime_param. lifetime ( ) ) ;
126
153
if let LifetimeRef :: Named ( name) = & lifetime_ref {
127
154
let param = LifetimeParamData { name : name. clone ( ) } ;
128
155
let _idx = self . lifetimes . alloc ( param) ;
129
156
self . lower_bounds (
157
+ ec,
130
158
lifetime_param. type_bound_list ( ) ,
131
159
Either :: Right ( lifetime_ref) ,
132
160
) ;
@@ -136,12 +164,18 @@ impl<'db, 'c> GenericParamsCollector<'db, 'c> {
136
164
}
137
165
}
138
166
139
- fn lower_where_predicates ( & mut self , where_clause : ast:: WhereClause ) {
167
+ fn lower_where_predicates (
168
+ & mut self ,
169
+ ec : & mut ExprCollector < ' _ > ,
170
+ where_clause : ast:: WhereClause ,
171
+ ) {
140
172
for pred in where_clause. predicates ( ) {
141
173
let target = if let Some ( type_ref) = pred. ty ( ) {
142
- Either :: Left ( self . expr_collector . lower_type_ref ( type_ref, & mut |_| TypeRef :: Error ) )
174
+ Either :: Left (
175
+ ec. lower_type_ref ( type_ref, & mut ExprCollector :: impl_trait_error_allocator) ,
176
+ )
143
177
} else if let Some ( lifetime) = pred. lifetime ( ) {
144
- Either :: Right ( self . expr_collector . lower_lifetime_ref ( lifetime) )
178
+ Either :: Right ( ec . lower_lifetime_ref ( lifetime) )
145
179
} else {
146
180
continue ;
147
181
} ;
@@ -158,28 +192,30 @@ impl<'db, 'c> GenericParamsCollector<'db, 'c> {
158
192
. collect ( )
159
193
} ) ;
160
194
for bound in pred. type_bound_list ( ) . iter ( ) . flat_map ( |l| l. bounds ( ) ) {
161
- self . lower_type_bound_as_predicate ( bound, lifetimes. as_deref ( ) , target. clone ( ) ) ;
195
+ self . lower_type_bound_as_predicate ( ec , bound, lifetimes. as_deref ( ) , target. clone ( ) ) ;
162
196
}
163
197
}
164
198
}
165
199
166
200
fn lower_bounds (
167
201
& mut self ,
202
+ ec : & mut ExprCollector < ' _ > ,
168
203
type_bounds : Option < ast:: TypeBoundList > ,
169
204
target : Either < TypeRefId , LifetimeRef > ,
170
205
) {
171
206
for bound in type_bounds. iter ( ) . flat_map ( |type_bound_list| type_bound_list. bounds ( ) ) {
172
- self . lower_type_bound_as_predicate ( bound, None , target. clone ( ) ) ;
207
+ self . lower_type_bound_as_predicate ( ec , bound, None , target. clone ( ) ) ;
173
208
}
174
209
}
175
210
176
211
fn lower_type_bound_as_predicate (
177
212
& mut self ,
213
+ ec : & mut ExprCollector < ' _ > ,
178
214
bound : ast:: TypeBound ,
179
215
hrtb_lifetimes : Option < & [ Name ] > ,
180
216
target : Either < TypeRefId , LifetimeRef > ,
181
217
) {
182
- let bound = self . expr_collector . lower_type_bound (
218
+ let bound = ec . lower_type_bound (
183
219
bound,
184
220
& mut Self :: lower_argument_impl_trait (
185
221
& mut self . type_or_consts ,
@@ -191,14 +227,11 @@ impl<'db, 'c> GenericParamsCollector<'db, 'c> {
191
227
( _, TypeBound :: Error | TypeBound :: Use ( _) ) => return ,
192
228
( Either :: Left ( type_ref) , bound) => match hrtb_lifetimes {
193
229
Some ( hrtb_lifetimes) => WherePredicate :: ForLifetime {
194
- lifetimes : hrtb_lifetimes. to_vec ( ) . into_boxed_slice ( ) ,
195
- target : WherePredicateTypeTarget :: TypeRef ( type_ref) ,
196
- bound,
197
- } ,
198
- None => WherePredicate :: TypeBound {
199
- target : WherePredicateTypeTarget :: TypeRef ( type_ref) ,
230
+ lifetimes : ThinVec :: from_iter ( hrtb_lifetimes. iter ( ) . cloned ( ) ) ,
231
+ target : type_ref,
200
232
bound,
201
233
} ,
234
+ None => WherePredicate :: TypeBound { target : type_ref, bound } ,
202
235
} ,
203
236
( Either :: Right ( lifetime) , TypeBound :: Lifetime ( bound) ) => {
204
237
WherePredicate :: Lifetime { target : lifetime, bound }
@@ -208,72 +241,49 @@ impl<'db, 'c> GenericParamsCollector<'db, 'c> {
208
241
self . where_predicates . push ( predicate) ;
209
242
}
210
243
211
- pub ( crate ) fn collect_impl_trait < R > (
212
- & mut self ,
213
- cb : impl FnOnce ( & mut ExprCollector < ' _ > , & mut dyn FnMut ( ThinVec < TypeBound > ) -> TypeRef ) -> R ,
214
- ) -> R {
215
- cb (
216
- self . expr_collector ,
217
- & mut Self :: lower_argument_impl_trait (
218
- & mut self . type_or_consts ,
219
- & mut self . where_predicates ,
220
- self . parent ,
221
- ) ,
222
- )
223
- }
224
-
225
244
fn lower_argument_impl_trait (
226
245
type_or_consts : & mut Arena < TypeOrConstParamData > ,
227
246
where_predicates : & mut Vec < WherePredicate > ,
228
247
parent : GenericDefId ,
229
- ) -> impl FnMut ( ThinVec < TypeBound > ) -> TypeRef {
230
- move |impl_trait_bounds| {
248
+ ) -> impl for <' ec , ' db > FnMut ( & ' ec mut ExprCollector < ' db > , TypePtr , ThinVec < TypeBound > ) -> TypeRefId
249
+ {
250
+ move |ec, ptr, impl_trait_bounds| {
231
251
let param = TypeParamData {
232
252
name : None ,
233
253
default : None ,
234
254
provenance : TypeParamProvenance :: ArgumentImplTrait ,
235
255
} ;
236
- let param_id = type_or_consts. alloc ( param. into ( ) ) ;
256
+ let param_id = TypeRef :: TypeParam ( TypeParamId :: from_unchecked ( TypeOrConstParamId {
257
+ parent,
258
+ local_id : type_or_consts. alloc ( param. into ( ) ) ,
259
+ } ) ) ;
260
+ let type_ref = ec. alloc_type_ref ( param_id, ptr) ;
237
261
for bound in impl_trait_bounds {
238
- where_predicates. push ( WherePredicate :: TypeBound {
239
- target : WherePredicateTypeTarget :: TypeOrConstParam ( param_id) ,
240
- bound : bound. clone ( ) ,
241
- } ) ;
262
+ where_predicates
263
+ . push ( WherePredicate :: TypeBound { target : type_ref, bound : bound. clone ( ) } ) ;
242
264
}
243
- TypeRef :: TypeParam ( TypeParamId :: from_unchecked ( TypeOrConstParamId {
244
- parent,
245
- local_id : param_id,
246
- } ) )
265
+ type_ref
247
266
}
248
267
}
249
268
250
- pub ( crate ) fn finish ( self ) -> Arc < GenericParams > {
251
- let Self {
252
- mut lifetimes ,
253
- mut type_or_consts ,
254
- mut where_predicates ,
255
- expr_collector : _ ,
256
- parent : _ ,
257
- } = self ;
258
-
259
- if lifetimes . is_empty ( ) && type_or_consts . is_empty ( ) && where_predicates . is_empty ( ) {
260
- static EMPTY : LazyLock < Arc < GenericParams > > = LazyLock :: new ( || {
261
- Arc :: new ( GenericParams {
262
- lifetimes : Arena :: new ( ) ,
263
- type_or_consts : Arena :: new ( ) ,
264
- where_predicates : Box :: default ( ) ,
265
- } )
266
- } ) ;
267
- return Arc :: clone ( & EMPTY ) ;
269
+ fn fill_self_param ( & mut self , ec : & mut ExprCollector < ' _ > , bounds : Option < ast :: TypeBoundList > ) {
270
+ let self_ = Name :: new_symbol_root ( sym :: Self_ ) ;
271
+ let idx = self . type_or_consts . alloc (
272
+ TypeParamData {
273
+ name : Some ( self_ . clone ( ) ) ,
274
+ default : None ,
275
+ provenance : TypeParamProvenance :: TraitSelf ,
276
+ }
277
+ . into ( ) ,
278
+ ) ;
279
+ debug_assert_eq ! ( idx , GenericParams :: SELF_PARAM_ID_IN_SELF ) ;
280
+ let type_ref = TypeRef :: TypeParam ( TypeParamId :: from_unchecked ( TypeOrConstParamId {
281
+ parent : self . parent ,
282
+ local_id : idx ,
283
+ } ) ) ;
284
+ let self_ = ec . alloc_type_ref_desugared ( type_ref ) ;
285
+ if let Some ( bounds ) = bounds {
286
+ self . lower_bounds ( ec , Some ( bounds ) , Either :: Left ( self_ ) ) ;
268
287
}
269
-
270
- lifetimes. shrink_to_fit ( ) ;
271
- type_or_consts. shrink_to_fit ( ) ;
272
- where_predicates. shrink_to_fit ( ) ;
273
- Arc :: new ( GenericParams {
274
- type_or_consts,
275
- lifetimes,
276
- where_predicates : where_predicates. into_boxed_slice ( ) ,
277
- } )
278
288
}
279
289
}
0 commit comments