Skip to content

Commit 8fcad2f

Browse files
committed
Address some review comments
- bring back tests I commented out - add a few comments - add an is_var helper
1 parent 2316ca6 commit 8fcad2f

File tree

4 files changed

+43
-34
lines changed

4 files changed

+43
-34
lines changed

chalk-ir/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,14 @@ impl<I: Interner> Ty<I> {
229229
}
230230
}
231231

232+
/// Returns true if this is a `BoundVar` or `InferenceVar`.
233+
pub fn is_var(&self, interner: &I) -> bool {
234+
match self.data(interner) {
235+
TyData::BoundVar(_) | TyData::InferenceVar(_) => true,
236+
_ => false,
237+
}
238+
}
239+
232240
pub fn is_alias(&self, interner: &I) -> bool {
233241
match self.data(interner) {
234242
TyData::Alias(..) => true,

chalk-solve/src/clauses.rs

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,11 @@ fn program_clauses_that_could_match<I: Interner>(
233233
// and `bounded_ty` is the `exists<T> { .. }`
234234
// clauses shown above.
235235

236+
// Turn free BoundVars in the type into new existentials. E.g.
237+
// we might get some `dyn Foo<?X>`, and we don't want to return
238+
// a clause with a free variable. We can instead return a
239+
// slightly more general clause by basically turning this into
240+
// `exists<A> dyn Foo<A>`.
236241
let generalized_dyn_ty = generalize::Generalize::apply(db.interner(), dyn_ty);
237242

238243
builder.push_binders(&generalized_dyn_ty, |builder, dyn_ty| {
@@ -278,7 +283,7 @@ fn program_clauses_that_could_match<I: Interner>(
278283
match_ty(builder, environment, ty)?
279284
}
280285
DomainGoal::FromEnv(_) => (), // Computed in the environment
281-
DomainGoal::Normalize(Normalize { alias, ty }) => {
286+
DomainGoal::Normalize(Normalize { alias, ty: _ }) => {
282287
// Normalize goals derive from `AssociatedTyValue` datums,
283288
// which are found in impls. That is, if we are
284289
// normalizing (e.g.) `<T as Iterator>::Item>`, then
@@ -294,30 +299,12 @@ fn program_clauses_that_could_match<I: Interner>(
294299
let trait_id = associated_ty_datum.trait_id;
295300
let trait_parameters = db.trait_parameters_from_projection(alias);
296301

297-
if (alias
298-
.self_type_parameter(interner)
299-
.bound(interner)
300-
.is_some()
301-
|| alias
302-
.self_type_parameter(interner)
303-
.inference_var(interner)
304-
.is_some())
305-
&& (ty.bound(interner).is_some() || ty.inference_var(interner).is_some())
306-
{
307-
return Err(Floundered);
308-
}
309-
310302
let trait_datum = db.trait_datum(trait_id);
311303

312-
// FIXME
313-
if (alias
314-
.self_type_parameter(interner)
315-
.bound(interner)
316-
.is_some()
317-
|| alias
318-
.self_type_parameter(interner)
319-
.inference_var(interner)
320-
.is_some())
304+
// Flounder if the self-type is unknown and the trait is non-enumerable.
305+
//
306+
// e.g., Normalize(<?X as Iterator>::Item = u32)
307+
if (alias.self_type_parameter(interner).is_var(interner))
321308
&& trait_datum.is_non_enumerable_trait()
322309
{
323310
return Err(Floundered);

chalk-solve/src/clauses/generalize.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
//! ones. We use this when building clauses that contain types passed to
33
//! `program_clauses`; these may contain variables, and just copying those
44
//! variables verbatim leads to problems. Instead, we return a slightly more
5-
//! general program clause, with new variables in those places.
5+
//! general program clause, with new variables in those places. This can only
6+
//! happen with `dyn Trait` currently; that's the only case where we use the
7+
//! types passed to `program_clauses` in the clauses we generate.
68
79
use chalk_engine::fallible::Fallible;
810
use chalk_ir::{

tests/test/projection.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ fn normalize_basic() {
7676
"Unique"
7777
}
7878

79-
/* TODO: this doesn't seem to be correct, actually
8079
goal {
8180
forall<T> {
8281
if (T: Iterator) {
@@ -86,10 +85,9 @@ fn normalize_basic() {
8685
}
8786
}
8887
} yields {
89-
// True for `U = T`, of course, but also true for `U = Vec<T>`.
88+
// True for `U = T`, of course, but also true for `U = Vec<<T as Iterator>::Item>`.
9089
"Ambiguous"
9190
}
92-
*/
9391
}
9492
}
9593

@@ -142,6 +140,9 @@ fn projection_equality() {
142140
exists<U> {
143141
S: Trait2<U>
144142
}
143+
} yields[SolverChoice::slg_default()] {
144+
// this is wrong, chalk#234
145+
"Ambiguous"
145146
} yields[SolverChoice::recursive()] {
146147
"Unique; substitution [?0 := u32]"
147148
}
@@ -167,6 +168,9 @@ fn projection_equality_from_env() {
167168
}
168169
}
169170
}
171+
} yields[SolverChoice::slg_default()] {
172+
// this is wrong, chalk#234
173+
"Ambiguous"
170174
} yields[SolverChoice::recursive()] {
171175
"Unique; substitution [?0 := u32]"
172176
}
@@ -194,7 +198,10 @@ fn projection_equality_nested() {
194198
}
195199
}
196200
}
197-
} yields[SolverChoice::recursive()] {
201+
} yields[SolverChoice::slg_default()] {
202+
// this is wrong, chalk#234
203+
"Ambiguous"
204+
} yields[SolverChoice::recursive()] {
198205
"Unique; substitution [?0 := u32]"
199206
}
200207
}
@@ -235,6 +242,9 @@ fn iterator_flatten() {
235242
}
236243
}
237244
}
245+
} yields[SolverChoice::slg_default()] {
246+
// this is wrong, chalk#234
247+
"Ambiguous"
238248
} yields[SolverChoice::recursive()] {
239249
"Unique; substitution [?0 := u32]"
240250
}
@@ -536,17 +546,18 @@ fn normalize_under_binder() {
536546
}
537547
}
538548

539-
/* TODO: this doesn't seem to be correct, actually
540549
goal {
541550
exists<U> {
542551
forall<'a> {
543552
Ref<'a, I32>: Deref<'a, Item = U>
544553
}
545554
}
546-
} yields {
555+
} yields[SolverChoice::slg_default()] {
556+
// chalk#234, I think
547557
"Ambiguous"
558+
} yields[SolverChoice::recursive()] {
559+
"Unique; substitution [?0 := I32], lifetime constraints []"
548560
}
549-
*/
550561

551562
goal {
552563
exists<U> {
@@ -558,17 +569,18 @@ fn normalize_under_binder() {
558569
"Unique; substitution [?0 := I32], lifetime constraints []"
559570
}
560571

561-
/* TODO: this doesn't seem to be correct, actually
562572
goal {
563573
forall<'a> {
564574
exists<U> {
565575
Ref<'a, I32>: Id<'a, Item = U>
566576
}
567577
}
568-
} yields {
578+
} yields[SolverChoice::slg_default()] {
579+
// chalk#234, I think
569580
"Ambiguous"
581+
} yields[SolverChoice::recursive()] {
582+
"Unique; substitution [?0 := Ref<'!1_0, I32>], lifetime constraints []"
570583
}
571-
*/
572584

573585
goal {
574586
forall<'a> {

0 commit comments

Comments
 (0)