@@ -136,6 +136,17 @@ fn projection_equality() {
136
136
}
137
137
}
138
138
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
+
139
150
goal {
140
151
exists<U > {
141
152
S : Trait2 <U >
@@ -149,6 +160,127 @@ fn projection_equality() {
149
160
}
150
161
}
151
162
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
+ }
152
284
#[ test]
153
285
fn projection_equality_from_env ( ) {
154
286
test ! {
0 commit comments