@@ -279,11 +279,16 @@ fn check_predicates<'tcx>(
279
279
span : Span ,
280
280
) {
281
281
let tcx = infcx. tcx ;
282
- let impl1_predicates: Vec < _ > = traits:: elaborate_predicates (
282
+ let instantiated = tcx. predicates_of ( impl1_def_id) . instantiate ( tcx, impl1_substs) ;
283
+ let impl1_predicates: Vec < _ > = traits:: elaborate_predicates_with_span (
283
284
tcx,
284
- tcx. predicates_of ( impl1_def_id) . instantiate ( tcx, impl1_substs) . predicates . into_iter ( ) ,
285
+ std:: iter:: zip (
286
+ instantiated. predicates ,
287
+ // Don't drop predicates (unsound!) because `spans` is too short
288
+ instantiated. spans . into_iter ( ) . chain ( std:: iter:: repeat ( span) ) ,
289
+ ) ,
285
290
)
286
- . map ( |obligation| obligation. predicate )
291
+ . map ( |obligation| ( obligation. predicate , obligation . cause . span ) )
287
292
. collect ( ) ;
288
293
289
294
let mut impl2_predicates = if impl2_node. is_from_trait ( ) {
@@ -321,7 +326,7 @@ fn check_predicates<'tcx>(
321
326
// which is sound because we forbid impls like the following
322
327
//
323
328
// impl<D: Debug> AlwaysApplicable for D { }
324
- let always_applicable_traits = impl1_predicates. iter ( ) . copied ( ) . filter ( |& predicate| {
329
+ let always_applicable_traits = impl1_predicates. iter ( ) . copied ( ) . filter ( |& ( predicate, _ ) | {
325
330
matches ! (
326
331
trait_predicate_kind( tcx, predicate) ,
327
332
Some ( TraitSpecializationKind :: AlwaysApplicable )
@@ -345,11 +350,11 @@ fn check_predicates<'tcx>(
345
350
}
346
351
}
347
352
impl2_predicates. extend (
348
- traits:: elaborate_predicates ( tcx, always_applicable_traits)
353
+ traits:: elaborate_predicates_with_span ( tcx, always_applicable_traits)
349
354
. map ( |obligation| obligation. predicate ) ,
350
355
) ;
351
356
352
- for predicate in impl1_predicates {
357
+ for ( predicate, span ) in impl1_predicates {
353
358
if !impl2_predicates. contains ( & predicate) {
354
359
check_specialization_on ( tcx, predicate, span)
355
360
}
@@ -384,9 +389,17 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
384
389
. emit ( ) ;
385
390
}
386
391
}
392
+ ty:: PredicateKind :: Projection ( ty:: ProjectionPredicate { projection_ty, term } ) => {
393
+ tcx. sess
394
+ . struct_span_err (
395
+ span,
396
+ & format ! ( "cannot specialize on associated type `{projection_ty} == {term}`" , ) ,
397
+ )
398
+ . emit ( ) ;
399
+ }
387
400
_ => {
388
401
tcx. sess
389
- . struct_span_err ( span, & format ! ( "cannot specialize on `{:? }`" , predicate) )
402
+ . struct_span_err ( span, & format ! ( "cannot specialize on predicate `{ }`" , predicate) )
390
403
. emit ( ) ;
391
404
}
392
405
}
0 commit comments