@@ -11,6 +11,7 @@ use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
1111
1212use base_db:: CrateId ;
1313use hir_def:: {
14+ expr:: Movability ,
1415 lang_item:: { lang_attr, LangItemTarget } ,
1516 AssocItemId , GenericDefId , HasModule , ItemContainerId , Lookup , ModuleId , TypeAliasId ,
1617} ;
@@ -26,9 +27,9 @@ use crate::{
2627 to_assoc_type_id, to_chalk_trait_id,
2728 traits:: ChalkContext ,
2829 utils:: generics,
29- AliasEq , AliasTy , BoundVar , CallableDefId , DebruijnIndex , FnDefId , Interner , ProjectionTy ,
30- ProjectionTyExt , QuantifiedWhereClause , Substitution , TraitRef , TraitRefExt , Ty , TyBuilder ,
31- TyExt , TyKind , WhereClause ,
30+ wrap_empty_binders , AliasEq , AliasTy , BoundVar , CallableDefId , DebruijnIndex , FnDefId ,
31+ Interner , ProjectionTy , ProjectionTyExt , QuantifiedWhereClause , Substitution , TraitRef ,
32+ TraitRefExt , Ty , TyBuilder , TyExt , TyKind , WhereClause ,
3233} ;
3334
3435pub ( crate ) type AssociatedTyDatum = chalk_solve:: rust_ir:: AssociatedTyDatum < Interner > ;
@@ -372,17 +373,63 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
372373 }
373374 fn generator_datum (
374375 & self ,
375- _ : chalk_ir:: GeneratorId < Interner > ,
376+ id : chalk_ir:: GeneratorId < Interner > ,
376377 ) -> std:: sync:: Arc < chalk_solve:: rust_ir:: GeneratorDatum < Interner > > {
377- // FIXME
378- unimplemented ! ( )
378+ let ( parent, expr) = self . db . lookup_intern_generator ( id. into ( ) ) ;
379+
380+ // We fill substitution with unknown type, because we only need to know whether the generic
381+ // params are types or consts to build `Binders` and those being filled up are for
382+ // `resume_type`, `yield_type`, and `return_type` of the generator in question.
383+ let subst = TyBuilder :: subst_for_generator ( self . db , parent) . fill_with_unknown ( ) . build ( ) ;
384+
385+ let len = subst. len ( Interner ) ;
386+ let input_output = rust_ir:: GeneratorInputOutputDatum {
387+ resume_type : TyKind :: BoundVar ( BoundVar :: new ( DebruijnIndex :: INNERMOST , len - 3 ) )
388+ . intern ( Interner ) ,
389+ yield_type : TyKind :: BoundVar ( BoundVar :: new ( DebruijnIndex :: INNERMOST , len - 2 ) )
390+ . intern ( Interner ) ,
391+ return_type : TyKind :: BoundVar ( BoundVar :: new ( DebruijnIndex :: INNERMOST , len - 1 ) )
392+ . intern ( Interner ) ,
393+ // FIXME: calculate upvars
394+ upvars : vec ! [ ] ,
395+ } ;
396+
397+ let it = subst
398+ . iter ( Interner )
399+ . map ( |it| it. constant ( Interner ) . map ( |c| c. data ( Interner ) . ty . clone ( ) ) ) ;
400+ let input_output = crate :: make_type_and_const_binders ( it, input_output) ;
401+
402+ let movability = match self . db . body ( parent) [ expr] {
403+ hir_def:: expr:: Expr :: Closure {
404+ closure_kind : hir_def:: expr:: ClosureKind :: Generator ( movability) ,
405+ ..
406+ } => movability,
407+ _ => unreachable ! ( "non generator expression interned as generator" ) ,
408+ } ;
409+ let movability = match movability {
410+ Movability :: Static => rust_ir:: Movability :: Static ,
411+ Movability :: Movable => rust_ir:: Movability :: Movable ,
412+ } ;
413+
414+ Arc :: new ( rust_ir:: GeneratorDatum { movability, input_output } )
379415 }
380416 fn generator_witness_datum (
381417 & self ,
382- _ : chalk_ir:: GeneratorId < Interner > ,
418+ id : chalk_ir:: GeneratorId < Interner > ,
383419 ) -> std:: sync:: Arc < chalk_solve:: rust_ir:: GeneratorWitnessDatum < Interner > > {
384- // FIXME
385- unimplemented ! ( )
420+ // FIXME: calculate inner types
421+ let inner_types =
422+ rust_ir:: GeneratorWitnessExistential { types : wrap_empty_binders ( vec ! [ ] ) } ;
423+
424+ let ( parent, _) = self . db . lookup_intern_generator ( id. into ( ) ) ;
425+ // See the comment in `generator_datum()` for unknown types.
426+ let subst = TyBuilder :: subst_for_generator ( self . db , parent) . fill_with_unknown ( ) . build ( ) ;
427+ let it = subst
428+ . iter ( Interner )
429+ . map ( |it| it. constant ( Interner ) . map ( |c| c. data ( Interner ) . ty . clone ( ) ) ) ;
430+ let inner_types = crate :: make_type_and_const_binders ( it, inner_types) ;
431+
432+ Arc :: new ( rust_ir:: GeneratorWitnessDatum { inner_types } )
386433 }
387434
388435 fn unification_database ( & self ) -> & dyn chalk_ir:: UnificationDatabase < Interner > {
0 commit comments