@@ -11,6 +11,7 @@ use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
11
11
12
12
use base_db:: CrateId ;
13
13
use hir_def:: {
14
+ expr:: Movability ,
14
15
lang_item:: { lang_attr, LangItemTarget } ,
15
16
AssocItemId , GenericDefId , HasModule , ItemContainerId , Lookup , ModuleId , TypeAliasId ,
16
17
} ;
@@ -26,9 +27,9 @@ use crate::{
26
27
to_assoc_type_id, to_chalk_trait_id,
27
28
traits:: ChalkContext ,
28
29
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 ,
32
33
} ;
33
34
34
35
pub ( crate ) type AssociatedTyDatum = chalk_solve:: rust_ir:: AssociatedTyDatum < Interner > ;
@@ -372,17 +373,63 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
372
373
}
373
374
fn generator_datum (
374
375
& self ,
375
- _ : chalk_ir:: GeneratorId < Interner > ,
376
+ id : chalk_ir:: GeneratorId < Interner > ,
376
377
) -> 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 } )
379
415
}
380
416
fn generator_witness_datum (
381
417
& self ,
382
- _ : chalk_ir:: GeneratorId < Interner > ,
418
+ id : chalk_ir:: GeneratorId < Interner > ,
383
419
) -> 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 } )
386
433
}
387
434
388
435
fn unification_database ( & self ) -> & dyn chalk_ir:: UnificationDatabase < Interner > {
0 commit comments