Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit aeeb9e0

Browse files
committed
Add TyBuilder method to build Substitution for generator
1 parent ba64c93 commit aeeb9e0

File tree

1 file changed

+34
-2
lines changed

1 file changed

+34
-2
lines changed

crates/hir-ty/src/builder.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use chalk_ir::{
99
AdtId, BoundVar, DebruijnIndex, Scalar,
1010
};
1111
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,
1414
};
1515
use smallvec::SmallVec;
1616

@@ -205,6 +205,38 @@ impl TyBuilder<()> {
205205
)
206206
}
207207

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+
208240
pub fn build(self) -> Substitution {
209241
let ((), subst) = self.build_internal();
210242
subst

0 commit comments

Comments
 (0)