@@ -136,6 +136,17 @@ fn projection_equality() {
136136 }
137137 }
138138
139+ goal {
140+ exists<U > {
141+ S : Trait1 <Type = U >
142+ }
143+ } yields[ SolverChoice :: slg_default( ) ] {
144+ // this is wrong, chalk#234
145+ "Ambiguous"
146+ } yields[ SolverChoice :: recursive( ) ] {
147+ "Unique; substitution [?0 := u32]"
148+ }
149+
139150 goal {
140151 exists<U > {
141152 S : Trait2 <U >
@@ -149,6 +160,127 @@ fn projection_equality() {
149160 }
150161}
151162
163+ #[ test]
164+ fn projection_equality_priority1 ( ) {
165+ test ! {
166+ program {
167+ trait Trait1 <T > {
168+ type Type ;
169+ }
170+
171+ struct u32 { }
172+ struct S1 { }
173+ struct S2 { }
174+ struct S3 { }
175+
176+ impl Trait1 <S2 > for S1 {
177+ type Type = u32 ;
178+ }
179+ }
180+
181+ goal {
182+ exists<T , U > {
183+ S1 : Trait1 <T , Type = U >
184+ }
185+ } yields[ SolverChoice :: slg_default( ) ] {
186+ // this is wrong, chalk#234
187+ "Ambiguous"
188+ } yields[ SolverChoice :: recursive( ) ] {
189+ // This is.. interesting, but not necessarily wrong.
190+ // It's certainly true that based on the impls we see
191+ // the only possible value for `U` is `u32`.
192+ //
193+ // Can we come to any harm by inferring that `T = S2`
194+ // here, even though we could've chosen to say that
195+ // `U = !<S1 as Trait1<T>>::Type` and thus not
196+ // constrained `T` at all? I can't come up with
197+ // an example where that's the case, so maybe
198+ // not. -Niko
199+ "Unique; substitution [?0 := S2, ?1 := u32]"
200+ }
201+ }
202+ }
203+
204+ #[ test]
205+ fn projection_equality_priority2 ( ) {
206+ test ! {
207+ program {
208+ trait Trait1 <T > {
209+ type Type ;
210+ }
211+
212+ struct u32 { }
213+ struct S1 { }
214+ struct S2 { }
215+ struct S3 { }
216+
217+ impl <X > Trait1 <S1 > for X {
218+ type Type = u32 ;
219+ }
220+ }
221+
222+ goal {
223+ forall<X , Y > {
224+ if ( X : Trait1 <Y >) {
225+ exists<Out1 , Out2 > {
226+ X : Trait1 <Out1 , Type = Out2 >
227+ }
228+ }
229+ }
230+ } yields {
231+ // Correct: Ambiguous because Out1 = Y and Out1 = S1 are both value.
232+ "Ambiguous; no inference guidance"
233+ }
234+
235+ goal {
236+ forall<X , Y > {
237+ if ( X : Trait1 <Y >) {
238+ exists<Out1 , Out2 > {
239+ X : Trait1 <Out1 , Type = Out2 >,
240+ Out1 = Y
241+ }
242+ }
243+ }
244+ } yields {
245+ // Constraining Out1 = Y gives us only one choice.
246+ "Unique; substitution [?0 := !1_1, ?1 := (Trait1::Type)<!1_0, !1_1>], lifetime constraints []"
247+ }
248+
249+ goal {
250+ forall<X , Y > {
251+ if ( X : Trait1 <Y >) {
252+ exists<Out1 , Out2 > {
253+ Out1 = Y ,
254+ X : Trait1 <Out1 , Type = Out2 >
255+ }
256+ }
257+ }
258+ } yields {
259+ // Constraining Out1 = Y gives us only one choice.
260+ "Unique; substitution [?0 := !1_1, ?1 := (Trait1::Type)<!1_0, !1_1>], lifetime constraints []"
261+ }
262+
263+ goal {
264+ forall<X , Y > {
265+ if ( X : Trait1 <Y >) {
266+ exists<Out1 , Out2 > {
267+ Out1 = S1 ,
268+ X : Trait1 <Out1 , Type = Out2 >
269+ }
270+ }
271+ }
272+ } yields[ SolverChoice :: slg_default( ) ] {
273+ // chalk#234: Constraining Out1 = S1 gives us only the choice to
274+ // use the impl, but the SLG solver can't decide between
275+ // the placeholder and the normalized form.
276+ "Ambiguous; definite substitution for<?U1> { [?0 := S1, ?1 := ^0.0] }"
277+ } yields[ SolverChoice :: recursive( ) ] {
278+ // Constraining Out1 = S1 gives us only one choice, use the impl,
279+ // and the recursive solver prefers the normalized form.
280+ "Unique; substitution [?0 := S1, ?1 := u32], lifetime constraints []"
281+ }
282+ }
283+ }
152284#[ test]
153285fn projection_equality_from_env ( ) {
154286 test ! {
0 commit comments