Skip to content

Commit b5f04ad

Browse files
committed
Move substitution into push_binders
1 parent be9f62a commit b5f04ad

File tree

2 files changed

+27
-20
lines changed

2 files changed

+27
-20
lines changed

chalk-integration/src/lowering.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,9 +388,13 @@ impl LowerProgram for Program {
388388
.map(|k| k.lower())
389389
.collect::<Vec<_>>();
390390

391+
// Introduce the parameters declared on the opaque type definition.
392+
// So if we have `type Foo<P1..Pn> = impl Trait<T1..Tn>`, this would introduce `P1..Pn`
391393
let binders = empty_env.in_binders(parameter_kinds, |env| {
392394
let hidden_ty = opaque_ty.ty.lower(&env)?;
393395

396+
// Introduce a variable to represent the hidden "self type". This will be used in the bounds.
397+
// So the `impl Trait<T1..Tn>` will be lowered to `exists<Self> { Self: Trait<T1..Tn> }`.
394398
let bounds: chalk_ir::Binders<Vec<chalk_ir::Binders<_>>> = env
395399
.in_binders(
396400
Some(chalk_ir::ParameterKind::Ty(intern(FIXME_SELF))),
@@ -401,6 +405,7 @@ impl LowerProgram for Program {
401405
.lower(&env1)?
402406
.iter()
403407
.flat_map(|qil| {
408+
// Instantiate the bounds with the innermost bound variable, which represents Self, as the self type.
404409
qil.into_where_clauses(
405410
interner,
406411
chalk_ir::TyData::BoundVar(BoundVar::new(

chalk-solve/src/clauses/program_clauses.rs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -130,22 +130,22 @@ impl<I: Interner> ToProgramClauses<I> for OpaqueTyDatum<I> {
130130
/// ```
131131
/// where `!T<..>` is the placeholder for the unnormalized type `T<..>`.
132132
fn to_program_clauses(&self, builder: &mut ClauseBuilder<'_, I>) {
133-
let interner = builder.interner();
134-
let substitution = builder.substitution_in_scope();
135-
let alias = AliasTy::Opaque(OpaqueTy {
136-
opaque_ty_id: self.opaque_ty_id,
137-
substitution: substitution.clone(),
138-
});
133+
builder.push_binders(&self.bound, |builder, opaque_ty_bound| {
134+
let interner = builder.interner();
135+
let substitution = builder.substitution_in_scope();
136+
let alias = AliasTy::Opaque(OpaqueTy {
137+
opaque_ty_id: self.opaque_ty_id,
138+
substitution: substitution.clone(),
139+
});
139140

140-
let alias_ty = Ty::new(
141-
interner,
142-
ApplicationTy {
143-
name: TypeName::OpaqueType(self.opaque_ty_id),
144-
substitution,
145-
},
146-
);
141+
let alias_placeholder_ty = Ty::new(
142+
interner,
143+
ApplicationTy {
144+
name: TypeName::OpaqueType(self.opaque_ty_id),
145+
substitution,
146+
},
147+
);
147148

148-
builder.push_binders(&self.bound, |builder, opaque_ty_bound| {
149149
// AliasEq(T<..> = HiddenTy) :- Reveal.
150150
builder.push_clause(
151151
DomainGoal::Holds(
@@ -162,17 +162,19 @@ impl<I: Interner> ToProgramClauses<I> for OpaqueTyDatum<I> {
162162
builder.push_fact(DomainGoal::Holds(
163163
AliasEq {
164164
alias: alias.clone(),
165-
ty: alias_ty.clone(),
165+
ty: alias_placeholder_ty.clone(),
166166
}
167167
.cast(interner),
168168
));
169169

170170
for bound in &opaque_ty_bound.bounds {
171171
// Implemented(!T<..>: Bound).
172-
builder.push_binders(&bound, |builder, bound| {
173-
builder.push_binders(&bound, |builder, bound| {
174-
builder.push_fact(bound.into_well_formed_goal(interner));
175-
});
172+
let bound_with_placeholder_ty = bound.substitute(
173+
interner,
174+
&Substitution::from1(interner, alias_placeholder_ty.clone()),
175+
);
176+
builder.push_binders(&bound_with_placeholder_ty, |builder, bound| {
177+
builder.push_fact(bound.into_well_formed_goal(interner));
176178
});
177179
}
178180

@@ -181,7 +183,7 @@ impl<I: Interner> ToProgramClauses<I> for OpaqueTyDatum<I> {
181183
builder.push_clause(
182184
TraitRef {
183185
trait_id: auto_trait_id,
184-
substitution: Substitution::from1(interner, alias_ty.clone()),
186+
substitution: Substitution::from1(interner, alias_placeholder_ty.clone()),
185187
},
186188
iter::once(TraitRef {
187189
trait_id: auto_trait_id,

0 commit comments

Comments
 (0)