@@ -2,8 +2,8 @@ use crate::interner::{ChalkFnAbi, ChalkIr};
2
2
use chalk_ir:: cast:: { Cast , Caster } ;
3
3
use chalk_ir:: interner:: { HasInterner , Interner } ;
4
4
use chalk_ir:: {
5
- self , AdtId , AssocTypeId , BoundVar , ClausePriority , DebruijnIndex , FnDefId , ImplId , OpaqueTyId ,
6
- QuantifiedWhereClauses , Substitution , ToGenericArg , TraitId , TyKind ,
5
+ self , AdtId , AssocTypeId , BoundVar , ClausePriority , ClosureId , DebruijnIndex , FnDefId , ImplId ,
6
+ OpaqueTyId , QuantifiedWhereClauses , Substitution , ToGenericArg , TraitId , TyKind ,
7
7
} ;
8
8
use chalk_parse:: ast:: * ;
9
9
use chalk_solve:: rust_ir:: {
@@ -20,11 +20,13 @@ use crate::{Identifier as Ident, RawId, TypeKind, TypeSort};
20
20
21
21
type AdtIds = BTreeMap < Ident , chalk_ir:: AdtId < ChalkIr > > ;
22
22
type FnDefIds = BTreeMap < Ident , chalk_ir:: FnDefId < ChalkIr > > ;
23
+ type ClosureIds = BTreeMap < Ident , chalk_ir:: ClosureId < ChalkIr > > ;
23
24
type TraitIds = BTreeMap < Ident , chalk_ir:: TraitId < ChalkIr > > ;
24
25
type OpaqueTyIds = BTreeMap < Ident , chalk_ir:: OpaqueTyId < ChalkIr > > ;
25
26
type AdtKinds = BTreeMap < chalk_ir:: AdtId < ChalkIr > , TypeKind > ;
26
27
type FnDefKinds = BTreeMap < chalk_ir:: FnDefId < ChalkIr > , TypeKind > ;
27
28
type FnDefAbis = BTreeMap < FnDefId < ChalkIr > , <ChalkIr as Interner >:: FnAbi > ;
29
+ type ClosureKinds = BTreeMap < chalk_ir:: ClosureId < ChalkIr > , TypeKind > ;
28
30
type TraitKinds = BTreeMap < chalk_ir:: TraitId < ChalkIr > , TypeKind > ;
29
31
type OpaqueTyKinds = BTreeMap < chalk_ir:: OpaqueTyId < ChalkIr > , TypeKind > ;
30
32
type AssociatedTyLookups = BTreeMap < ( chalk_ir:: TraitId < ChalkIr > , Ident ) , AssociatedTyLookup > ;
@@ -42,6 +44,8 @@ struct Env<'k> {
42
44
fn_def_ids : & ' k FnDefIds ,
43
45
fn_def_kinds : & ' k FnDefKinds ,
44
46
fn_def_abis : & ' k FnDefAbis ,
47
+ closure_ids : & ' k ClosureIds ,
48
+ closure_kinds : & ' k ClosureKinds ,
45
49
trait_ids : & ' k TraitIds ,
46
50
trait_kinds : & ' k TraitKinds ,
47
51
opaque_ty_ids : & ' k OpaqueTyIds ,
@@ -80,6 +84,7 @@ struct AssociatedTyLookup {
80
84
enum ApplyTypeLookup {
81
85
Adt ( AdtId < ChalkIr > ) ,
82
86
FnDef ( FnDefId < ChalkIr > ) ,
87
+ Closure ( ClosureId < ChalkIr > ) ,
83
88
Opaque ( OpaqueTyId < ChalkIr > ) ,
84
89
}
85
90
@@ -132,8 +137,27 @@ impl<'k> Env<'k> {
132
137
actual : 0 ,
133
138
} ) ;
134
139
} else {
135
- return Ok ( chalk_ir:: TyData :: Function ( chalk_ir:: Fn {
136
- num_binders : k. binders . len ( interner) ,
140
+ return Ok ( chalk_ir:: TyData :: Apply ( chalk_ir:: ApplicationTy {
141
+ name : chalk_ir:: TypeName :: FnDef ( id. clone ( ) ) ,
142
+ substitution : chalk_ir:: Substitution :: empty ( interner) ,
143
+ } )
144
+ . intern ( interner)
145
+ . cast ( interner) ) ;
146
+ }
147
+ }
148
+
149
+ if let Some ( id) = self . closure_ids . get ( & name. str ) {
150
+ let k = self . closure_kind ( * id) ;
151
+ if k. binders . len ( interner) > 0 {
152
+ return Err ( RustIrError :: IncorrectNumberOfTypeParameters {
153
+ identifier : name. clone ( ) ,
154
+ expected : k. binders . len ( interner) ,
155
+ actual : 0 ,
156
+ } ) ;
157
+ } else {
158
+ return Ok ( chalk_ir:: TyData :: Apply ( chalk_ir:: ApplicationTy {
159
+ name : chalk_ir:: TypeName :: Closure ( id. clone ( ) ) ,
160
+ // See note in `program`. Unlike rustc, we store upvars separately.
137
161
substitution : chalk_ir:: Substitution :: empty ( interner) ,
138
162
} )
139
163
. intern ( interner)
@@ -171,6 +195,10 @@ impl<'k> Env<'k> {
171
195
return Ok ( ApplyTypeLookup :: FnDef ( * id) ) ;
172
196
}
173
197
198
+ if let Some ( id) = self . closure_ids . get ( & name. str ) {
199
+ return Ok ( ApplyTypeLookup :: Closure ( * id) ) ;
200
+ }
201
+
174
202
if let Some ( id) = self . opaque_ty_ids . get ( & name. str ) {
175
203
return Ok ( ApplyTypeLookup :: Opaque ( * id) ) ;
176
204
}
@@ -206,6 +234,10 @@ impl<'k> Env<'k> {
206
234
& self . fn_def_kinds [ & id]
207
235
}
208
236
237
+ fn closure_kind ( & self , id : chalk_ir:: ClosureId < ChalkIr > ) -> & TypeKind {
238
+ & self . closure_kinds [ & id]
239
+ }
240
+
209
241
fn opaque_kind ( & self , id : chalk_ir:: OpaqueTyId < ChalkIr > ) -> & TypeKind {
210
242
& self . opaque_ty_kinds [ & id]
211
243
}
@@ -318,11 +350,13 @@ impl LowerProgram for Program {
318
350
319
351
let mut adt_ids = BTreeMap :: new ( ) ;
320
352
let mut fn_def_ids = BTreeMap :: new ( ) ;
353
+ let mut closure_ids = BTreeMap :: new ( ) ;
321
354
let mut trait_ids = BTreeMap :: new ( ) ;
322
355
let mut opaque_ty_ids = BTreeMap :: new ( ) ;
323
356
let mut adt_kinds = BTreeMap :: new ( ) ;
324
357
let mut fn_def_kinds = BTreeMap :: new ( ) ;
325
358
let mut fn_def_abis = BTreeMap :: new ( ) ;
359
+ let mut closure_kinds = BTreeMap :: new ( ) ;
326
360
let mut trait_kinds = BTreeMap :: new ( ) ;
327
361
let mut opaque_ty_kinds = BTreeMap :: new ( ) ;
328
362
let mut object_safe_traits = HashSet :: new ( ) ;
@@ -341,6 +375,12 @@ impl LowerProgram for Program {
341
375
fn_def_kinds. insert ( id, type_kind) ;
342
376
fn_def_abis. insert ( id, defn. abi . lower ( ) ?) ;
343
377
}
378
+ Item :: ClosureDefn ( defn) => {
379
+ let type_kind = defn. lower_type_kind ( ) ?;
380
+ let id = ClosureId ( raw_id) ;
381
+ closure_ids. insert ( defn. name . str . clone ( ) , id) ;
382
+ closure_kinds. insert ( id, type_kind) ;
383
+ }
344
384
Item :: TraitDefn ( defn) => {
345
385
let type_kind = defn. lower_type_kind ( ) ?;
346
386
let id = TraitId ( raw_id) ;
@@ -364,6 +404,9 @@ impl LowerProgram for Program {
364
404
365
405
let mut adt_data = BTreeMap :: new ( ) ;
366
406
let mut fn_def_data = BTreeMap :: new ( ) ;
407
+ let mut closure_inputs_and_output = BTreeMap :: new ( ) ;
408
+ let mut closure_closure_kind = BTreeMap :: new ( ) ;
409
+ let mut closure_upvars = BTreeMap :: new ( ) ;
367
410
let mut trait_data = BTreeMap :: new ( ) ;
368
411
let mut well_known_traits = BTreeMap :: new ( ) ;
369
412
let mut impl_data = BTreeMap :: new ( ) ;
@@ -379,6 +422,8 @@ impl LowerProgram for Program {
379
422
fn_def_ids : & fn_def_ids,
380
423
fn_def_kinds : & fn_def_kinds,
381
424
fn_def_abis : & fn_def_abis,
425
+ closure_ids : & closure_ids,
426
+ closure_kinds : & closure_kinds,
382
427
trait_ids : & trait_ids,
383
428
trait_kinds : & trait_kinds,
384
429
opaque_ty_ids : & opaque_ty_ids,
@@ -399,6 +444,26 @@ impl LowerProgram for Program {
399
444
Arc :: new ( defn. lower_fn_def ( fn_def_id, & empty_env) ?) ,
400
445
) ;
401
446
}
447
+ Item :: ClosureDefn ( ref defn) => {
448
+ let closure_def_id = ClosureId ( raw_id) ;
449
+ let ( kind, inputs_and_output) = defn. lower_closure ( & empty_env) ?;
450
+ closure_closure_kind. insert ( closure_def_id, kind) ;
451
+ closure_inputs_and_output. insert ( closure_def_id, inputs_and_output) ;
452
+ let upvars = empty_env. in_binders ( defn. all_parameters ( ) , |env| {
453
+ let upvar_tys: LowerResult < Vec < chalk_ir:: Ty < ChalkIr > > > =
454
+ defn. upvars . iter ( ) . map ( |ty| ty. lower ( & env) ) . collect ( ) ;
455
+ let substitution = chalk_ir:: Substitution :: from (
456
+ & ChalkIr ,
457
+ upvar_tys?. into_iter ( ) . map ( |ty| ty. cast ( & ChalkIr ) ) ,
458
+ ) ;
459
+ Ok ( chalk_ir:: TyData :: Apply ( chalk_ir:: ApplicationTy {
460
+ name : chalk_ir:: TypeName :: Tuple ( defn. upvars . len ( ) ) ,
461
+ substitution,
462
+ } )
463
+ . intern ( & ChalkIr ) )
464
+ } ) ?;
465
+ closure_upvars. insert ( closure_def_id, upvars) ;
466
+ }
402
467
Item :: TraitDefn ( ref trait_defn) => {
403
468
let trait_id = TraitId ( raw_id) ;
404
469
let trait_datum = trait_defn. lower_trait ( trait_id, & empty_env) ?;
@@ -556,12 +621,17 @@ impl LowerProgram for Program {
556
621
let program = LoweredProgram {
557
622
adt_ids,
558
623
fn_def_ids,
624
+ closure_ids,
625
+ closure_upvars,
626
+ closure_kinds,
559
627
trait_ids,
560
628
adt_kinds,
561
629
fn_def_kinds,
562
630
trait_kinds,
563
631
adt_data,
564
632
fn_def_data,
633
+ closure_inputs_and_output,
634
+ closure_closure_kind,
565
635
trait_data,
566
636
well_known_traits,
567
637
impl_data,
@@ -657,6 +727,16 @@ impl LowerParameterMap for FnDefn {
657
727
}
658
728
}
659
729
730
+ impl LowerParameterMap for ClosureDefn {
731
+ fn synthetic_parameters ( & self ) -> Option < chalk_ir:: WithKind < ChalkIr , Ident > > {
732
+ None
733
+ }
734
+
735
+ fn declared_parameters ( & self ) -> & [ VariableKind ] {
736
+ & self . variable_kinds
737
+ }
738
+ }
739
+
660
740
impl LowerParameterMap for Impl {
661
741
fn synthetic_parameters ( & self ) -> Option < chalk_ir:: WithKind < ChalkIr , Ident > > {
662
742
None
@@ -794,6 +874,20 @@ impl LowerWhereClauses for FnDefn {
794
874
}
795
875
}
796
876
877
+ impl LowerTypeKind for ClosureDefn {
878
+ fn lower_type_kind ( & self ) -> LowerResult < TypeKind > {
879
+ let interner = & ChalkIr ;
880
+ Ok ( TypeKind {
881
+ sort : TypeSort :: Closure ,
882
+ name : self . name . str . clone ( ) ,
883
+ binders : chalk_ir:: Binders :: new (
884
+ chalk_ir:: VariableKinds :: from ( interner, self . all_parameters ( ) . anonymize ( ) ) ,
885
+ crate :: Unit ,
886
+ ) ,
887
+ } )
888
+ }
889
+ }
890
+
797
891
impl LowerWhereClauses for StructDefn {
798
892
fn where_clauses ( & self ) -> & [ QuantifiedWhereClause ] {
799
893
& self . where_clauses
@@ -1032,11 +1126,12 @@ impl LowerFnDefn for FnDefn {
1032
1126
env : & Env ,
1033
1127
) -> LowerResult < rust_ir:: FnDefDatum < ChalkIr > > {
1034
1128
let binders = env. in_binders ( self . all_parameters ( ) , |env| {
1035
- let args: LowerResult < _ > = self . argument_types . iter ( ) . map ( |t| t. lower ( env) ) . collect ( ) ;
1036
1129
let where_clauses = self . lower_where_clauses ( env) ?;
1037
- let return_type = self . return_type . lower ( env) ?;
1038
1130
1039
- let inputs_and_output = env. in_binders ( vec ! [ ] , |_| {
1131
+ let inputs_and_output = env. in_binders ( vec ! [ ] , |env| {
1132
+ let args: LowerResult < _ > =
1133
+ self . argument_types . iter ( ) . map ( |t| t. lower ( env) ) . collect ( ) ;
1134
+ let return_type = self . return_type . lower ( env) ?;
1040
1135
Ok ( rust_ir:: FnDefInputsAndOutputDatum {
1041
1136
argument_types : args?,
1042
1137
return_type,
@@ -1070,6 +1165,51 @@ impl LowerFnAbi for FnAbi {
1070
1165
}
1071
1166
}
1072
1167
1168
+ trait LowerClosureDefn {
1169
+ fn lower_closure (
1170
+ & self ,
1171
+ env : & Env ,
1172
+ ) -> LowerResult < (
1173
+ rust_ir:: ClosureKind ,
1174
+ chalk_ir:: Binders < rust_ir:: FnDefInputsAndOutputDatum < ChalkIr > > ,
1175
+ ) > ;
1176
+ }
1177
+
1178
+ impl LowerClosureDefn for ClosureDefn {
1179
+ fn lower_closure (
1180
+ & self ,
1181
+ env : & Env ,
1182
+ ) -> LowerResult < (
1183
+ rust_ir:: ClosureKind ,
1184
+ chalk_ir:: Binders < rust_ir:: FnDefInputsAndOutputDatum < ChalkIr > > ,
1185
+ ) > {
1186
+ let inputs_and_output = env. in_binders ( self . all_parameters ( ) , |env| {
1187
+ let args: LowerResult < _ > = self . argument_types . iter ( ) . map ( |t| t. lower ( env) ) . collect ( ) ;
1188
+ let return_type = self . return_type . lower ( env) ?;
1189
+ Ok ( rust_ir:: FnDefInputsAndOutputDatum {
1190
+ argument_types : args?,
1191
+ return_type,
1192
+ } )
1193
+ } ) ?;
1194
+
1195
+ Ok ( ( self . kind . lower_closure_kind ( ) ?, inputs_and_output) )
1196
+ }
1197
+ }
1198
+
1199
+ trait LowerClosureKind {
1200
+ fn lower_closure_kind ( & self ) -> LowerResult < rust_ir:: ClosureKind > ;
1201
+ }
1202
+
1203
+ impl LowerClosureKind for ClosureKind {
1204
+ fn lower_closure_kind ( & self ) -> LowerResult < rust_ir:: ClosureKind > {
1205
+ Ok ( match self {
1206
+ ClosureKind :: Fn => rust_ir:: ClosureKind :: Fn ,
1207
+ ClosureKind :: FnMut => rust_ir:: ClosureKind :: FnMut ,
1208
+ ClosureKind :: FnOnce => rust_ir:: ClosureKind :: FnOnce ,
1209
+ } )
1210
+ }
1211
+ }
1212
+
1073
1213
trait LowerTraitRef {
1074
1214
fn lower ( & self , env : & Env ) -> LowerResult < chalk_ir:: TraitRef < ChalkIr > > ;
1075
1215
}
@@ -1369,6 +1509,9 @@ impl LowerTy for Ty {
1369
1509
ApplyTypeLookup :: FnDef ( id) => {
1370
1510
( chalk_ir:: TypeName :: FnDef ( id) , env. fn_def_kind ( id) )
1371
1511
}
1512
+ ApplyTypeLookup :: Closure ( id) => {
1513
+ ( chalk_ir:: TypeName :: Closure ( id) , env. closure_kind ( id) )
1514
+ }
1372
1515
ApplyTypeLookup :: Opaque ( id) => {
1373
1516
( chalk_ir:: TypeName :: OpaqueType ( id) , env. opaque_kind ( id) )
1374
1517
}
@@ -1761,11 +1904,13 @@ impl LowerGoal<LoweredProgram> for Goal {
1761
1904
let env = Env {
1762
1905
adt_ids : & program. adt_ids ,
1763
1906
fn_def_ids : & program. fn_def_ids ,
1907
+ closure_ids : & program. closure_ids ,
1764
1908
trait_ids : & program. trait_ids ,
1765
1909
opaque_ty_ids : & program. opaque_ty_ids ,
1766
1910
adt_kinds : & program. adt_kinds ,
1767
1911
fn_def_kinds : & program. fn_def_kinds ,
1768
1912
fn_def_abis : & fn_def_abis,
1913
+ closure_kinds : & program. closure_kinds ,
1769
1914
trait_kinds : & program. trait_kinds ,
1770
1915
opaque_ty_kinds : & program. opaque_ty_kinds ,
1771
1916
associated_ty_lookups : & associated_ty_lookups,
0 commit comments