@@ -2,7 +2,7 @@ use crate::interner::ChalkIr;
22use chalk_ir:: cast:: { Cast , Caster } ;
33use chalk_ir:: interner:: HasInterner ;
44use chalk_ir:: {
5- self , AdtId , AssocTypeId , BoundVar , ClausePriority , DebruijnIndex , ImplId , OpaqueTyId ,
5+ self , AdtId , AssocTypeId , BoundVar , ClausePriority , DebruijnIndex , FnDefId , ImplId , OpaqueTyId ,
66 QuantifiedWhereClauses , Substitution , ToGenericArg , TraitId ,
77} ;
88use chalk_parse:: ast:: * ;
@@ -19,9 +19,11 @@ use crate::program::Program as LoweredProgram;
1919use crate :: { Identifier as Ident , RawId , TypeKind , TypeSort } ;
2020
2121type AdtIds = BTreeMap < Ident , chalk_ir:: AdtId < ChalkIr > > ;
22+ type FnDefIds = BTreeMap < Ident , chalk_ir:: FnDefId < ChalkIr > > ;
2223type TraitIds = BTreeMap < Ident , chalk_ir:: TraitId < ChalkIr > > ;
2324type OpaqueTyIds = BTreeMap < Ident , chalk_ir:: OpaqueTyId < ChalkIr > > ;
2425type AdtKinds = BTreeMap < chalk_ir:: AdtId < ChalkIr > , TypeKind > ;
26+ type FnDefKinds = BTreeMap < chalk_ir:: FnDefId < ChalkIr > , TypeKind > ;
2527type TraitKinds = BTreeMap < chalk_ir:: TraitId < ChalkIr > , TypeKind > ;
2628type AssociatedTyLookups = BTreeMap < ( chalk_ir:: TraitId < ChalkIr > , Ident ) , AssociatedTyLookup > ;
2729type AssociatedTyValueIds =
@@ -36,6 +38,8 @@ pub type LowerResult<T> = Result<T, RustIrError>;
3638struct Env < ' k > {
3739 adt_ids : & ' k AdtIds ,
3840 adt_kinds : & ' k AdtKinds ,
41+ fn_def_ids : & ' k FnDefIds ,
42+ fn_def_kinds : & ' k FnDefKinds ,
3943 trait_ids : & ' k TraitIds ,
4044 trait_kinds : & ' k TraitKinds ,
4145 opaque_ty_ids : & ' k OpaqueTyIds ,
@@ -73,6 +77,7 @@ struct AssociatedTyLookup {
7377enum TypeLookup {
7478 Adt ( chalk_ir:: AdtId < ChalkIr > ) ,
7579 GenericArg ( BoundVar ) ,
80+ FnDef ( chalk_ir:: FnDefId < ChalkIr > ) ,
7681 Opaque ( chalk_ir:: OpaqueTyId < ChalkIr > ) ,
7782}
7883
@@ -96,6 +101,10 @@ impl<'k> Env<'k> {
96101 return Ok ( TypeLookup :: Adt ( * id) ) ;
97102 }
98103
104+ if let Some ( id) = self . fn_def_ids . get ( & name. str ) {
105+ return Ok ( TypeLookup :: FnDef ( * id) ) ;
106+ }
107+
99108 if let Some ( id) = self . opaque_ty_ids . get ( & name. str ) {
100109 return Ok ( TypeLookup :: Opaque ( * id) ) ;
101110 }
@@ -140,6 +149,10 @@ impl<'k> Env<'k> {
140149 & self . adt_kinds [ & id]
141150 }
142151
152+ fn fn_def_kind ( & self , id : chalk_ir:: FnDefId < ChalkIr > ) -> & TypeKind {
153+ & self . fn_def_kinds [ & id]
154+ }
155+
143156 fn trait_kind ( & self , id : chalk_ir:: TraitId < ChalkIr > ) -> & TypeKind {
144157 & self . trait_kinds [ & id]
145158 }
@@ -240,9 +253,11 @@ impl LowerProgram for Program {
240253 }
241254
242255 let mut adt_ids = BTreeMap :: new ( ) ;
256+ let mut fn_def_ids = BTreeMap :: new ( ) ;
243257 let mut trait_ids = BTreeMap :: new ( ) ;
244258 let mut opaque_ty_ids = BTreeMap :: new ( ) ;
245259 let mut adt_kinds = BTreeMap :: new ( ) ;
260+ let mut fn_def_kinds = BTreeMap :: new ( ) ;
246261 let mut trait_kinds = BTreeMap :: new ( ) ;
247262 let mut opaque_ty_kinds = BTreeMap :: new ( ) ;
248263 let mut object_safe_traits = HashSet :: new ( ) ;
@@ -254,6 +269,12 @@ impl LowerProgram for Program {
254269 adt_ids. insert ( type_kind. name . clone ( ) , id) ;
255270 adt_kinds. insert ( id, type_kind) ;
256271 }
272+ Item :: FnDefn ( defn) => {
273+ let type_kind = defn. lower_type_kind ( ) ?;
274+ let id = FnDefId ( raw_id) ;
275+ fn_def_ids. insert ( type_kind. name . clone ( ) , id) ;
276+ fn_def_kinds. insert ( id, type_kind) ;
277+ }
257278 Item :: TraitDefn ( defn) => {
258279 let type_kind = defn. lower_type_kind ( ) ?;
259280 let id = TraitId ( raw_id) ;
@@ -276,6 +297,7 @@ impl LowerProgram for Program {
276297 }
277298
278299 let mut adt_data = BTreeMap :: new ( ) ;
300+ let mut fn_def_data = BTreeMap :: new ( ) ;
279301 let mut trait_data = BTreeMap :: new ( ) ;
280302 let mut well_known_traits = BTreeMap :: new ( ) ;
281303 let mut impl_data = BTreeMap :: new ( ) ;
@@ -287,6 +309,8 @@ impl LowerProgram for Program {
287309 let empty_env = Env {
288310 adt_ids : & adt_ids,
289311 adt_kinds : & adt_kinds,
312+ fn_def_ids : & fn_def_ids,
313+ fn_def_kinds : & fn_def_kinds,
290314 trait_ids : & trait_ids,
291315 trait_kinds : & trait_kinds,
292316 opaque_ty_ids : & opaque_ty_ids,
@@ -299,6 +323,13 @@ impl LowerProgram for Program {
299323 let adt_id = AdtId ( raw_id) ;
300324 adt_data. insert ( adt_id, Arc :: new ( d. lower_adt ( adt_id, & empty_env) ?) ) ;
301325 }
326+ Item :: FnDefn ( ref defn) => {
327+ let fn_def_id = FnDefId ( raw_id) ;
328+ fn_def_data. insert (
329+ fn_def_id,
330+ Arc :: new ( defn. lower_fn_def ( fn_def_id, & empty_env) ?) ,
331+ ) ;
332+ }
302333 Item :: TraitDefn ( ref trait_defn) => {
303334 let trait_id = TraitId ( raw_id) ;
304335 let trait_datum = trait_defn. lower_trait ( trait_id, & empty_env) ?;
@@ -454,10 +485,13 @@ impl LowerProgram for Program {
454485
455486 let program = LoweredProgram {
456487 adt_ids,
488+ fn_def_ids,
457489 trait_ids,
458490 adt_kinds,
491+ fn_def_kinds,
459492 trait_kinds,
460493 adt_data,
494+ fn_def_data,
461495 trait_data,
462496 well_known_traits,
463497 impl_data,
@@ -538,6 +572,16 @@ impl LowerParameterMap for StructDefn {
538572 }
539573}
540574
575+ impl LowerParameterMap for FnDefn {
576+ fn synthetic_parameters ( & self ) -> Option < NamedGenericArg > {
577+ None
578+ }
579+
580+ fn declared_parameters ( & self ) -> & [ VariableKind ] {
581+ & self . variable_kinds
582+ }
583+ }
584+
541585impl LowerParameterMap for Impl {
542586 fn synthetic_parameters ( & self ) -> Option < NamedGenericArg > {
543587 None
@@ -631,6 +675,26 @@ impl LowerTypeKind for StructDefn {
631675 }
632676}
633677
678+ impl LowerTypeKind for FnDefn {
679+ fn lower_type_kind ( & self ) -> LowerResult < TypeKind > {
680+ let interner = & ChalkIr ;
681+ Ok ( TypeKind {
682+ sort : TypeSort :: FnDef ,
683+ name : self . name . str . clone ( ) ,
684+ binders : chalk_ir:: Binders :: new (
685+ chalk_ir:: VariableKinds :: from ( interner, self . all_parameters ( ) . anonymize ( ) ) ,
686+ crate :: Unit ,
687+ ) ,
688+ } )
689+ }
690+ }
691+
692+ impl LowerWhereClauses for FnDefn {
693+ fn where_clauses ( & self ) -> & [ QuantifiedWhereClause ] {
694+ & self . where_clauses
695+ }
696+ }
697+
634698impl LowerWhereClauses for StructDefn {
635699 fn where_clauses ( & self ) -> & [ QuantifiedWhereClause ] {
636700 & self . where_clauses
@@ -850,6 +914,39 @@ impl LowerAdtDefn for StructDefn {
850914 }
851915}
852916
917+ trait LowerFnDefn {
918+ fn lower_fn_def (
919+ & self ,
920+ fn_def_id : chalk_ir:: FnDefId < ChalkIr > ,
921+ env : & Env ,
922+ ) -> LowerResult < rust_ir:: FnDefDatum < ChalkIr > > ;
923+ }
924+
925+ impl LowerFnDefn for FnDefn {
926+ fn lower_fn_def (
927+ & self ,
928+ fn_def_id : chalk_ir:: FnDefId < ChalkIr > ,
929+ env : & Env ,
930+ ) -> LowerResult < rust_ir:: FnDefDatum < ChalkIr > > {
931+ let binders = env. in_binders ( self . all_parameters ( ) , |env| {
932+ let args: LowerResult < _ > = self . argument_types . iter ( ) . map ( |t| t. lower ( env) ) . collect ( ) ;
933+ let where_clauses = self . lower_where_clauses ( env) ?;
934+ let return_type = self . return_type . lower ( env) ?;
935+
936+ Ok ( rust_ir:: FnDefDatumBound {
937+ argument_types : args?,
938+ where_clauses,
939+ return_type,
940+ } )
941+ } ) ?;
942+
943+ Ok ( rust_ir:: FnDefDatum {
944+ id : fn_def_id,
945+ binders,
946+ } )
947+ }
948+ }
949+
853950trait LowerTraitRef {
854951 fn lower ( & self , env : & Env ) -> LowerResult < chalk_ir:: TraitRef < ChalkIr > > ;
855952}
@@ -1121,6 +1218,22 @@ impl LowerTy for Ty {
11211218 }
11221219 }
11231220 TypeLookup :: GenericArg ( d) => Ok ( chalk_ir:: TyData :: BoundVar ( d) . intern ( interner) ) ,
1221+ TypeLookup :: FnDef ( id) => {
1222+ let k = env. fn_def_kind ( id) ;
1223+ if k. binders . len ( interner) > 0 {
1224+ Err ( RustIrError :: IncorrectNumberOfTypeParameters {
1225+ identifier : name. clone ( ) ,
1226+ expected : k. binders . len ( interner) ,
1227+ actual : 0 ,
1228+ } )
1229+ } else {
1230+ Ok ( chalk_ir:: TyData :: Function ( chalk_ir:: Fn {
1231+ num_binders : k. binders . len ( interner) ,
1232+ substitution : chalk_ir:: Substitution :: empty ( interner) ,
1233+ } )
1234+ . intern ( interner) )
1235+ }
1236+ }
11241237 TypeLookup :: Opaque ( id) => Ok ( chalk_ir:: TyData :: Alias ( chalk_ir:: AliasTy :: Opaque (
11251238 chalk_ir:: OpaqueTy {
11261239 opaque_ty_id : id,
@@ -1157,14 +1270,14 @@ impl LowerTy for Ty {
11571270 . intern ( interner) ) ,
11581271
11591272 Ty :: Apply { name, ref args } => {
1160- let id = match env. lookup_type ( name) ? {
1161- TypeLookup :: Adt ( id) => id ,
1273+ let ( id , k ) = match env. lookup_type ( name) ? {
1274+ TypeLookup :: Adt ( id) => ( id . 0 , env . adt_kind ( id ) ) ,
11621275 TypeLookup :: GenericArg ( _) | TypeLookup :: Opaque ( _) => {
11631276 Err ( RustIrError :: CannotApplyTypeParameter ( name. clone ( ) ) ) ?
11641277 }
1278+ TypeLookup :: FnDef ( id) => ( id. 0 , env. fn_def_kind ( id) ) ,
11651279 } ;
11661280
1167- let k = env. adt_kind ( id) ;
11681281 if k. binders . len ( interner) != args. len ( ) {
11691282 Err ( RustIrError :: IncorrectNumberOfTypeParameters {
11701283 identifier : name. clone ( ) ,
@@ -1188,11 +1301,18 @@ impl LowerTy for Ty {
11881301 }
11891302 }
11901303
1191- Ok ( chalk_ir:: TyData :: Apply ( chalk_ir:: ApplicationTy {
1192- name : chalk_ir:: TypeName :: Adt ( id) ,
1193- substitution,
1194- } )
1195- . intern ( interner) )
1304+ match k. sort {
1305+ TypeSort :: FnDef => Ok ( chalk_ir:: TyData :: Apply ( chalk_ir:: ApplicationTy {
1306+ name : chalk_ir:: TypeName :: FnDef ( FnDefId ( id) ) ,
1307+ substitution,
1308+ } )
1309+ . intern ( interner) ) ,
1310+ _ => Ok ( chalk_ir:: TyData :: Apply ( chalk_ir:: ApplicationTy {
1311+ name : chalk_ir:: TypeName :: Adt ( AdtId ( id) ) ,
1312+ substitution,
1313+ } )
1314+ . intern ( interner) ) ,
1315+ }
11961316 }
11971317
11981318 Ty :: Projection { ref proj } => Ok ( chalk_ir:: TyData :: Alias (
@@ -1485,9 +1605,11 @@ impl LowerGoal<LoweredProgram> for Goal {
14851605
14861606 let env = Env {
14871607 adt_ids : & program. adt_ids ,
1608+ fn_def_ids : & program. fn_def_ids ,
14881609 trait_ids : & program. trait_ids ,
14891610 opaque_ty_ids : & program. opaque_ty_ids ,
14901611 adt_kinds : & program. adt_kinds ,
1612+ fn_def_kinds : & program. fn_def_kinds ,
14911613 trait_kinds : & program. trait_kinds ,
14921614 associated_ty_lookups : & associated_ty_lookups,
14931615 parameter_map : BTreeMap :: new ( ) ,
0 commit comments