@@ -202,3 +202,105 @@ fn test_neg_CoreTrait_for_CoreStruct_implies_no_overlap() {
202
202
]" ,
203
203
) ) ;
204
204
}
205
+
206
+ #[ test]
207
+ fn test_overlap_normalize_alias_to_LocalType ( ) {
208
+ // `LocalTrait` has a blanket impl for all `T: Iterator`
209
+ // and then an impl for `<LocalType as Mirror>::T`...
210
+
211
+ let gen_program = |addl : & str | {
212
+ const BASE_PROGRAM : & str = "[
213
+ crate core {
214
+ trait Iterator<> where [] {
215
+ }
216
+
217
+ trait Mirror<> where [] {
218
+ type T<> : [] where [];
219
+ }
220
+
221
+ impl<ty A> Mirror<> for A where [] {
222
+ type T<> = A where [];
223
+ }
224
+
225
+ struct LocalType<> where [] {}
226
+
227
+ trait LocalTrait<> where [] { }
228
+
229
+ impl<ty T> LocalTrait<> for T where [T: Iterator<>] { }
230
+
231
+ impl<> LocalTrait<> for <LocalType as Mirror>::T where [] { }
232
+
233
+ ADDITIONAL
234
+ }
235
+ ]" ;
236
+
237
+ BASE_PROGRAM . replace ( "ADDITIONAL" , addl)
238
+ } ;
239
+
240
+ // ...on its own, this is OK. Figuring this out, though, requires proving
241
+ // `<LocalType as Mirror>::T: Iterator` which requires normalizing
242
+ // the alias to `LocalType`...
243
+
244
+ expect_test:: expect![ [ r#"
245
+ Ok(
246
+ (),
247
+ )
248
+ "# ] ]
249
+ . assert_debug_eq ( & test_program_ok ( & gen_program ( "" ) ) ) ;
250
+
251
+ // ...but it's an error if LocalType implements Iterator (figuring *this* out also
252
+ // requires normalizing).
253
+
254
+ expect_test:: expect![ [ r#"
255
+ Err(
256
+ "impls may overlap: `impl <ty> LocalTrait < > for ^ty0_0 where [^ty0_0 : Iterator < >] { }` vs `impl <> LocalTrait < > for (alias (Mirror :: T) (rigid (adt LocalType))) where [] { }`",
257
+ )
258
+ "# ] ]
259
+ . assert_debug_eq ( & test_program_ok ( & gen_program ( "impl<> Iterator<> for LocalType<> where [] {}" ) ) ) ;
260
+ }
261
+
262
+ #[ test]
263
+ fn test_overlap_alias_not_normalizable ( ) {
264
+ // `LocalTrait` has a blanket impl for all `T: Iterator`
265
+ // and then an impl for `<LocalType as Mirror>::T`...
266
+
267
+ let gen_program = |addl : & str | {
268
+ const BASE_PROGRAM : & str = "[
269
+ crate core {
270
+ trait Iterator<> where [] {
271
+ }
272
+
273
+ trait Mirror<> where [] {
274
+ type T<> : [] where [];
275
+ }
276
+
277
+ impl<ty A> Mirror<> for A where [] {
278
+ type T<> = A where [];
279
+ }
280
+
281
+ struct LocalType<> where [] {}
282
+
283
+ trait LocalTrait<> where [] { }
284
+
285
+ impl<ty T> LocalTrait<> for T where [T: Iterator<>] { }
286
+
287
+ impl<ty T> LocalTrait<> for <T as Mirror>::T where [T: Mirror<>] { }
288
+
289
+ ADDITIONAL
290
+ }
291
+ ]" ;
292
+
293
+ BASE_PROGRAM . replace ( "ADDITIONAL" , addl)
294
+ } ;
295
+
296
+ // ...on its own, this is OK. Figuring this out, though, requires proving
297
+ // `<LocalType as Mirror>::T: Iterator` which requires normalizing
298
+ // the alias to `LocalType`...
299
+
300
+ expect_test:: expect![ [ r#"
301
+ Ok(
302
+ (),
303
+ )
304
+ "# ] ] // FIXME
305
+ . assert_debug_eq ( & test_program_ok ( & gen_program ( "" ) ) ) ;
306
+ }
0 commit comments