@@ -9,8 +9,8 @@ use chalk_ir::{
9
9
AdtId , BoundVar , DebruijnIndex , Scalar ,
10
10
} ;
11
11
use hir_def:: {
12
- builtin_type:: BuiltinType , generics:: TypeOrConstParamData , ConstParamId , GenericDefId , TraitId ,
13
- TypeAliasId ,
12
+ builtin_type:: BuiltinType , generics:: TypeOrConstParamData , ConstParamId , DefWithBodyId ,
13
+ GenericDefId , TraitId , TypeAliasId ,
14
14
} ;
15
15
use smallvec:: SmallVec ;
16
16
@@ -205,6 +205,38 @@ impl TyBuilder<()> {
205
205
)
206
206
}
207
207
208
+ /// Creates a `TyBuilder` to build `Substitution` for a generator defined in `parent`.
209
+ ///
210
+ /// A generator's substitution consists of:
211
+ /// - generic parameters in scope on `parent`
212
+ /// - resume type of generator
213
+ /// - yield type of generator ([`Generator::Yield`](std::ops::Generator::Yield))
214
+ /// - return type of generator ([`Generator::Return`](std::ops::Generator::Return))
215
+ /// in this order.
216
+ ///
217
+ /// This method prepopulates the builder with placeholder substitution of `parent`, so you
218
+ /// should only push exactly 3 `GenericArg`s before building.
219
+ pub fn subst_for_generator ( db : & dyn HirDatabase , parent : DefWithBodyId ) -> TyBuilder < ( ) > {
220
+ let parent_subst = match parent. as_generic_def_id ( ) {
221
+ Some ( parent) => generics ( db. upcast ( ) , parent) . placeholder_subst ( db) ,
222
+ // Static initializers *may* contain generators.
223
+ None => Substitution :: empty ( Interner ) ,
224
+ } ;
225
+ let builder = TyBuilder :: new (
226
+ ( ) ,
227
+ parent_subst
228
+ . iter ( Interner )
229
+ . map ( |arg| match arg. constant ( Interner ) {
230
+ Some ( c) => ParamKind :: Const ( c. data ( Interner ) . ty . clone ( ) ) ,
231
+ None => ParamKind :: Type ,
232
+ } )
233
+ // These represent resume type, yield type, and return type of generator.
234
+ . chain ( std:: iter:: repeat ( ParamKind :: Type ) . take ( 3 ) )
235
+ . collect ( ) ,
236
+ ) ;
237
+ builder. use_parent_substs ( & parent_subst)
238
+ }
239
+
208
240
pub fn build ( self ) -> Substitution {
209
241
let ( ( ) , subst) = self . build_internal ( ) ;
210
242
subst
0 commit comments