Skip to content

Commit a9ebee0

Browse files
committed
Add test implied_from_env and clean up
1 parent dc524eb commit a9ebee0

File tree

4 files changed

+47
-16
lines changed

4 files changed

+47
-16
lines changed

src/ir.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,9 @@ pub enum InlineBound {
269269
impl InlineBound {
270270
/// Applies the `InlineBound` to `self_ty` and lowers to a [`DomainGoal`].
271271
///
272-
/// Because an `InlineBound` not know anything about what it's binding, you
273-
/// must provide that type as `self_ty`.
274-
pub fn lower_with_self(&self, self_ty: Ty) -> Vec<DomainGoal> {
272+
/// Because an `InlineBound` does not know anything about what it's binding,
273+
/// you must provide that type as `self_ty`.
274+
crate fn lower_with_self(&self, self_ty: Ty) -> Vec<DomainGoal> {
275275
match self {
276276
InlineBound::TraitBound(b) => b.lower_with_self(self_ty),
277277
InlineBound::ProjectionEqBound(b) => b.lower_with_self(self_ty),
@@ -288,7 +288,7 @@ pub struct TraitBound {
288288
}
289289

290290
impl TraitBound {
291-
pub fn lower_with_self(&self, self_ty: Ty) -> Vec<DomainGoal> {
291+
crate fn lower_with_self(&self, self_ty: Ty) -> Vec<DomainGoal> {
292292
let trait_ref = self.as_trait_ref(self_ty);
293293
vec![DomainGoal::Holds(WhereClauseAtom::Implemented(trait_ref))]
294294
}
@@ -314,7 +314,7 @@ pub struct ProjectionEqBound {
314314
}
315315

316316
impl ProjectionEqBound {
317-
pub fn lower_with_self(&self, self_ty: Ty) -> Vec<DomainGoal> {
317+
crate fn lower_with_self(&self, self_ty: Ty) -> Vec<DomainGoal> {
318318
let trait_ref = self.trait_bound.as_trait_ref(self_ty);
319319

320320
let mut parameters = self.parameters.clone();
@@ -354,7 +354,7 @@ pub struct AssociatedTyDatum {
354354
/// would result in a well-formed projection.
355355
crate bounds: Vec<InlineBound>,
356356

357-
/// Where clauses that must hold for the projection be well-formed.
357+
/// Where clauses that must hold for the projection to be well-formed.
358358
crate where_clauses: Vec<QuantifiedDomainGoal>,
359359
}
360360

@@ -364,7 +364,7 @@ impl AssociatedTyDatum {
364364
/// ```notrust
365365
/// Implemented(<?0 as Foo>::Item<?1>: Sized)
366366
/// ```
367-
pub fn bounds_on_self(&self) -> Vec<DomainGoal> {
367+
crate fn bounds_on_self(&self) -> Vec<DomainGoal> {
368368
let parameters = self.parameter_kinds
369369
.anonymize()
370370
.iter()

src/rules.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ impl ir::AssociatedTyValue {
237237
let projection = ir::ProjectionTy {
238238
associated_ty_id: self.associated_ty_id,
239239

240-
// Add the remaining parameters of the trait-ref if any
240+
// Add the remaining parameters of the trait-ref, if any
241241
parameters: parameters.iter()
242242
.chain(&impl_trait_ref.parameters[1..])
243243
.cloned()
@@ -528,10 +528,7 @@ impl ir::AssociatedTyDatum {
528528
}.cast());
529529

530530
// Assuming well-formedness of projection type means we can assume
531-
// the trait ref as well.
532-
//
533-
// Currently we do not use this rule in chalk (it's used in fn bodies),
534-
// but it's here for completeness.
531+
// the trait ref as well. Mostly used in function bodies.
535532
//
536533
// forall<Self> {
537534
// FromEnv(Self: Foo) :- FromEnv((Foo::Assoc)<Self>).

src/rules/wf.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,9 @@ impl WfSolver {
258258
.map(|p| p.to_parameter())
259259
.chain(trait_ref.parameters.iter().cloned())
260260
.collect();
261-
261+
262+
// Add bounds from the trait. Because they are defined on the trait,
263+
// their parameters must be substituted with those of the impl.
262264
let bound_goals =
263265
bounds.iter()
264266
.map(|b| Subst::apply(&all_parameters, b))
@@ -271,14 +273,16 @@ impl WfSolver {
271273
None => return None,
272274
};
273275

276+
// Add where clauses from the associated ty definition. We must
277+
// substitute parameters here, like we did with the bounds above.
274278
let hypotheses =
275279
assoc_ty_datum.where_clauses
276280
.iter()
277281
.map(|wc| Subst::apply(&all_parameters, wc))
278282
.map(|wc| wc.map(|bound| bound.into_from_env_goal()))
279283
.casted()
280284
.collect();
281-
285+
282286
let goal = Goal::Implies(
283287
hypotheses,
284288
Box::new(goal)

src/solve/test.rs

+32-2
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,7 @@ fn normalize_gat_with_higher_ranked_trait_bound() {
740740
}
741741

742742
#[test]
743-
fn normalize_implied_bound() {
743+
fn implied_bounds() {
744744
test! {
745745
program {
746746
trait Clone { }
@@ -761,7 +761,7 @@ fn normalize_implied_bound() {
761761
}
762762

763763
#[test]
764-
fn normalize_implied_bound_gat() {
764+
fn gat_implied_bounds() {
765765
test! {
766766
program {
767767
trait Clone { }
@@ -800,6 +800,36 @@ fn normalize_implied_bound_gat() {
800800
}
801801
}
802802

803+
#[test]
804+
fn implied_from_env() {
805+
test! {
806+
program {
807+
trait Clone { }
808+
trait Foo<U> { type Item<V>; }
809+
}
810+
811+
goal {
812+
forall<T, U, V> {
813+
if (FromEnv(<T as Foo<U>>::Item<V>)) {
814+
FromEnv(T: Foo<U>)
815+
}
816+
}
817+
} yields {
818+
"Unique"
819+
}
820+
821+
goal {
822+
forall<T, U, V> {
823+
if (FromEnv(<T as Foo<U>>::Item<V>)) {
824+
FromEnv(T: Clone)
825+
}
826+
}
827+
} yields {
828+
"No possible solution"
829+
}
830+
}
831+
}
832+
803833
/// Demonstrates that, given the expected value of the associated
804834
/// type, we can use that to narrow down the relevant impls.
805835
#[test]

0 commit comments

Comments
 (0)