@@ -15,83 +15,112 @@ use triomphe::Arc;
1515
1616use crate :: {
1717 GenericDefId , TypeOrConstParamId , TypeParamId ,
18- expr_store:: lower:: ExprCollector ,
18+ expr_store:: { TypePtr , lower:: ExprCollector } ,
1919 hir:: generics:: {
2020 ConstParamData , GenericParams , LifetimeParamData , TypeOrConstParamData , TypeParamData ,
21- TypeParamProvenance , WherePredicate , WherePredicateTypeTarget ,
21+ TypeParamProvenance , WherePredicate ,
2222 } ,
2323 type_ref:: { LifetimeRef , TypeBound , TypeRef , TypeRefId } ,
2424} ;
2525
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 {
2833 type_or_consts : Arena < TypeOrConstParamData > ,
2934 lifetimes : Arena < LifetimeParamData > ,
3035 where_predicates : Vec < WherePredicate > ,
3136 parent : GenericDefId ,
3237}
3338
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 {
3641 Self {
37- expr_collector,
3842 type_or_consts : Default :: default ( ) ,
3943 lifetimes : Default :: default ( ) ,
4044 where_predicates : Default :: default ( ) ,
4145 parent,
4246 }
4347 }
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
6356 }
6457
6558 pub ( crate ) fn lower (
6659 & mut self ,
60+ ec : & mut ExprCollector < ' _ > ,
6761 generic_param_list : Option < ast:: GenericParamList > ,
6862 where_clause : Option < ast:: WhereClause > ,
6963 ) {
7064 if let Some ( params) = generic_param_list {
71- self . lower_param_list ( params)
65+ self . lower_param_list ( ec , params)
7266 }
7367 if let Some ( where_clause) = where_clause {
74- self . lower_where_predicates ( where_clause) ;
68+ self . lower_where_predicates ( ec , where_clause) ;
7569 }
7670 }
7771
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 ) {
79112 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) ;
85114 if !enabled {
86115 continue ;
87116 }
88117
89118 match generic_param {
90119 ast:: GenericParam :: TypeParam ( type_param) => {
91120 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+ } ) ;
95124 let param = TypeParamData {
96125 name : Some ( name. clone ( ) ) ,
97126 default,
@@ -103,30 +132,29 @@ impl<'db, 'c> GenericParamsCollector<'db, 'c> {
103132 parent : self . parent ,
104133 local_id : idx,
105134 } ) ) ;
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) ) ;
108137 }
109138 ast:: GenericParam :: ConstParam ( const_param) => {
110139 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+ ) ;
114144 let param = ConstParamData {
115145 name,
116146 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) ) ,
120148 } ;
121149 let _idx = self . type_or_consts . alloc ( param. into ( ) ) ;
122150 }
123151 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 ( ) ) ;
126153 if let LifetimeRef :: Named ( name) = & lifetime_ref {
127154 let param = LifetimeParamData { name : name. clone ( ) } ;
128155 let _idx = self . lifetimes . alloc ( param) ;
129156 self . lower_bounds (
157+ ec,
130158 lifetime_param. type_bound_list ( ) ,
131159 Either :: Right ( lifetime_ref) ,
132160 ) ;
@@ -136,12 +164,18 @@ impl<'db, 'c> GenericParamsCollector<'db, 'c> {
136164 }
137165 }
138166
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+ ) {
140172 for pred in where_clause. predicates ( ) {
141173 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+ )
143177 } 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) )
145179 } else {
146180 continue ;
147181 } ;
@@ -158,28 +192,30 @@ impl<'db, 'c> GenericParamsCollector<'db, 'c> {
158192 . collect ( )
159193 } ) ;
160194 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 ( ) ) ;
162196 }
163197 }
164198 }
165199
166200 fn lower_bounds (
167201 & mut self ,
202+ ec : & mut ExprCollector < ' _ > ,
168203 type_bounds : Option < ast:: TypeBoundList > ,
169204 target : Either < TypeRefId , LifetimeRef > ,
170205 ) {
171206 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 ( ) ) ;
173208 }
174209 }
175210
176211 fn lower_type_bound_as_predicate (
177212 & mut self ,
213+ ec : & mut ExprCollector < ' _ > ,
178214 bound : ast:: TypeBound ,
179215 hrtb_lifetimes : Option < & [ Name ] > ,
180216 target : Either < TypeRefId , LifetimeRef > ,
181217 ) {
182- let bound = self . expr_collector . lower_type_bound (
218+ let bound = ec . lower_type_bound (
183219 bound,
184220 & mut Self :: lower_argument_impl_trait (
185221 & mut self . type_or_consts ,
@@ -191,14 +227,11 @@ impl<'db, 'c> GenericParamsCollector<'db, 'c> {
191227 ( _, TypeBound :: Error | TypeBound :: Use ( _) ) => return ,
192228 ( Either :: Left ( type_ref) , bound) => match hrtb_lifetimes {
193229 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,
200232 bound,
201233 } ,
234+ None => WherePredicate :: TypeBound { target : type_ref, bound } ,
202235 } ,
203236 ( Either :: Right ( lifetime) , TypeBound :: Lifetime ( bound) ) => {
204237 WherePredicate :: Lifetime { target : lifetime, bound }
@@ -208,72 +241,49 @@ impl<'db, 'c> GenericParamsCollector<'db, 'c> {
208241 self . where_predicates . push ( predicate) ;
209242 }
210243
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-
225244 fn lower_argument_impl_trait (
226245 type_or_consts : & mut Arena < TypeOrConstParamData > ,
227246 where_predicates : & mut Vec < WherePredicate > ,
228247 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| {
231251 let param = TypeParamData {
232252 name : None ,
233253 default : None ,
234254 provenance : TypeParamProvenance :: ArgumentImplTrait ,
235255 } ;
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) ;
237261 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 ( ) } ) ;
242264 }
243- TypeRef :: TypeParam ( TypeParamId :: from_unchecked ( TypeOrConstParamId {
244- parent,
245- local_id : param_id,
246- } ) )
265+ type_ref
247266 }
248267 }
249268
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_ ) ) ;
268287 }
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- } )
278288 }
279289}
0 commit comments