@@ -74,7 +74,7 @@ use rustc_infer::infer::{InferCtxt, RegionckMode, TyCtxtInferExt};
74
74
use rustc_infer:: traits:: specialization_graph:: Node ;
75
75
use rustc_middle:: ty:: subst:: { GenericArg , InternalSubsts , SubstsRef } ;
76
76
use rustc_middle:: ty:: trait_def:: TraitSpecializationKind ;
77
- use rustc_middle:: ty:: { self , InstantiatedPredicates , TyCtxt , TypeFoldable } ;
77
+ use rustc_middle:: ty:: { self , TyCtxt , TypeFoldable } ;
78
78
use rustc_span:: Span ;
79
79
use rustc_trait_selection:: traits:: { self , translate_substs, wf} ;
80
80
@@ -294,13 +294,27 @@ fn check_predicates<'tcx>(
294
294
span : Span ,
295
295
) {
296
296
let tcx = infcx. tcx ;
297
- let impl1_predicates = tcx. predicates_of ( impl1_def_id) . instantiate ( tcx, impl1_substs) ;
297
+ let impl1_predicates: Vec < _ > = traits:: elaborate_predicates (
298
+ tcx,
299
+ tcx. predicates_of ( impl1_def_id) . instantiate ( tcx, impl1_substs) . predicates . into_iter ( ) ,
300
+ )
301
+ . map ( |obligation| obligation. predicate )
302
+ . collect ( ) ;
303
+
298
304
let mut impl2_predicates = if impl2_node. is_from_trait ( ) {
299
305
// Always applicable traits have to be always applicable without any
300
306
// assumptions.
301
- InstantiatedPredicates :: empty ( )
307
+ Vec :: new ( )
302
308
} else {
303
- tcx. predicates_of ( impl2_node. def_id ( ) ) . instantiate ( tcx, impl2_substs)
309
+ traits:: elaborate_predicates (
310
+ tcx,
311
+ tcx. predicates_of ( impl2_node. def_id ( ) )
312
+ . instantiate ( tcx, impl2_substs)
313
+ . predicates
314
+ . into_iter ( ) ,
315
+ )
316
+ . map ( |obligation| obligation. predicate )
317
+ . collect ( )
304
318
} ;
305
319
debug ! (
306
320
"check_always_applicable(\n impl1_predicates={:?},\n impl2_predicates={:?}\n )" ,
@@ -322,13 +336,12 @@ fn check_predicates<'tcx>(
322
336
// which is sound because we forbid impls like the following
323
337
//
324
338
// impl<D: Debug> AlwaysApplicable for D { }
325
- let always_applicable_traits =
326
- impl1_predicates. predicates . iter ( ) . copied ( ) . filter ( |& predicate| {
327
- matches ! (
328
- trait_predicate_kind( tcx, predicate) ,
329
- Some ( TraitSpecializationKind :: AlwaysApplicable )
330
- )
331
- } ) ;
339
+ let always_applicable_traits = impl1_predicates. iter ( ) . copied ( ) . filter ( |& predicate| {
340
+ matches ! (
341
+ trait_predicate_kind( tcx, predicate) ,
342
+ Some ( TraitSpecializationKind :: AlwaysApplicable )
343
+ )
344
+ } ) ;
332
345
333
346
// Include the well-formed predicates of the type parameters of the impl.
334
347
for arg in tcx. impl_trait_ref ( impl1_def_id) . unwrap ( ) . substs {
@@ -340,18 +353,19 @@ fn check_predicates<'tcx>(
340
353
arg,
341
354
span,
342
355
) {
343
- impl2_predicates
344
- . predicates
345
- . extend ( obligations. into_iter ( ) . map ( |obligation| obligation. predicate ) )
356
+ impl2_predicates. extend (
357
+ traits:: elaborate_obligations ( tcx, obligations)
358
+ . map ( |obligation| obligation. predicate ) ,
359
+ )
346
360
}
347
361
}
348
- impl2_predicates. predicates . extend (
362
+ impl2_predicates. extend (
349
363
traits:: elaborate_predicates ( tcx, always_applicable_traits)
350
364
. map ( |obligation| obligation. predicate ) ,
351
365
) ;
352
366
353
- for predicate in impl1_predicates. predicates {
354
- if !impl2_predicates. predicates . contains ( & predicate) {
367
+ for predicate in impl1_predicates {
368
+ if !impl2_predicates. contains ( & predicate) {
355
369
check_specialization_on ( tcx, predicate, span)
356
370
}
357
371
}
0 commit comments