Skip to content

Commit a3b372c

Browse files
committed
Don't flounder on int/float vars in recursive solver either
To achieve this, we pass the binders. It's slightly hacky; it would be nicer if we could just pass the `Canonical`, but that would require the SLG solver to pass a canonicalized goal, which it doesn't currently. So passing the binders separately feels slightly less bad.
1 parent 30b7eb9 commit a3b372c

File tree

4 files changed

+30
-13
lines changed

4 files changed

+30
-13
lines changed

chalk-engine/src/slg.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,12 @@ impl<'me, I: Interner> context::ContextOps<I, SlgContext<I>> for SlgContextOps<'
9898
goal: &DomainGoal<I>,
9999
_infer: &mut TruncatingInferenceTable<I>,
100100
) -> Result<Vec<ProgramClause<I>>, Floundered> {
101-
let clauses: Vec<_> = program_clauses_for_goal(self.program, environment, goal)?;
101+
let clauses: Vec<_> = program_clauses_for_goal(
102+
self.program,
103+
environment,
104+
goal,
105+
&CanonicalVarKinds::empty(self.program.interner()),
106+
)?;
102107

103108
Ok(clauses)
104109
}

chalk-ir/src/lib.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,9 +395,15 @@ impl<I: Interner> Ty<I> {
395395
}
396396

397397
/// Returns true if this is a `BoundVar` or an `InferenceVar` of `TyKind::General`.
398-
pub fn is_general_var(&self, interner: &I) -> bool {
398+
pub fn is_general_var(&self, interner: &I, binders: &CanonicalVarKinds<I>) -> bool {
399399
match self.data(interner) {
400-
TyData::BoundVar(_) | TyData::InferenceVar(_, TyKind::General) => true,
400+
TyData::BoundVar(bv)
401+
if bv.debruijn == DebruijnIndex::INNERMOST
402+
&& binders.at(interner, bv.index).kind == VariableKind::Ty(TyKind::General) =>
403+
{
404+
true
405+
}
406+
TyData::InferenceVar(_, TyKind::General) => true,
401407
_ => false,
402408
}
403409
}

chalk-recursive/src/solve.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,10 @@ pub(super) trait SolveIteration<I: Interner>: SolveDatabase<I> {
6969
// or from the lowered program, which includes fallback
7070
// clauses. We try each approach in turn:
7171

72-
let InEnvironment { environment, goal } = &canonical_goal.canonical.value;
73-
7472
let (prog_solution, prog_prio) = {
7573
debug_span!("prog_clauses");
7674

77-
let prog_clauses = self.program_clauses_for_goal(environment, &goal);
75+
let prog_clauses = self.program_clauses_for_goal(&canonical_goal);
7876
match prog_clauses {
7977
Ok(clauses) => self.solve_from_clauses(&canonical_goal, clauses, minimums),
8078
Err(Floundered) => {
@@ -202,10 +200,14 @@ trait SolveIterationHelpers<I: Interner>: SolveDatabase<I> {
202200

203201
fn program_clauses_for_goal(
204202
&self,
205-
environment: &Environment<I>,
206-
goal: &DomainGoal<I>,
203+
canonical_goal: &UCanonical<InEnvironment<DomainGoal<I>>>,
207204
) -> Result<Vec<ProgramClause<I>>, Floundered> {
208-
program_clauses_for_goal(self.db(), environment, goal)
205+
program_clauses_for_goal(
206+
self.db(),
207+
&canonical_goal.canonical.value.environment,
208+
&canonical_goal.canonical.value.goal,
209+
&canonical_goal.canonical.binders,
210+
)
209211
}
210212
}
211213

chalk-solve/src/clauses.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,12 +176,13 @@ pub fn program_clauses_for_goal<'db, I: Interner>(
176176
db: &'db dyn RustIrDatabase<I>,
177177
environment: &Environment<I>,
178178
goal: &DomainGoal<I>,
179+
binders: &CanonicalVarKinds<I>,
179180
) -> Result<Vec<ProgramClause<I>>, Floundered> {
180181
let interner = db.interner();
181182

182183
let custom_clauses = db.custom_clauses().into_iter();
183-
let clauses_that_could_match =
184-
program_clauses_that_could_match(db, environment, goal).map(|cl| cl.into_iter())?;
184+
let clauses_that_could_match = program_clauses_that_could_match(db, environment, goal, binders)
185+
.map(|cl| cl.into_iter())?;
185186

186187
let clauses: Vec<ProgramClause<I>> = custom_clauses
187188
.chain(clauses_that_could_match)
@@ -207,6 +208,7 @@ fn program_clauses_that_could_match<I: Interner>(
207208
db: &dyn RustIrDatabase<I>,
208209
environment: &Environment<I>,
209210
goal: &DomainGoal<I>,
211+
binders: &CanonicalVarKinds<I>,
210212
) -> Result<Vec<ProgramClause<I>>, Floundered> {
211213
let interner = db.interner();
212214
let mut clauses: Vec<ProgramClause<I>> = vec![];
@@ -225,7 +227,7 @@ fn program_clauses_that_could_match<I: Interner>(
225227
if trait_datum.is_auto_trait() {
226228
push_auto_trait_impls_opaque(builder, trait_id, opaque_ty.opaque_ty_id)
227229
}
228-
} else if self_ty.is_general_var(interner) {
230+
} else if self_ty.is_general_var(interner, binders) {
229231
return Err(Floundered);
230232
}
231233
}
@@ -386,7 +388,9 @@ fn program_clauses_that_could_match<I: Interner>(
386388
// Flounder if the self-type is unknown and the trait is non-enumerable.
387389
//
388390
// e.g., Normalize(<?X as Iterator>::Item = u32)
389-
if (self_ty.is_general_var(interner)) && trait_datum.is_non_enumerable_trait() {
391+
if (self_ty.is_general_var(interner, binders))
392+
&& trait_datum.is_non_enumerable_trait()
393+
{
390394
return Err(Floundered);
391395
}
392396

0 commit comments

Comments
 (0)