@@ -73,6 +73,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
73
73
Ok ( ImplSource :: Param ( obligations) )
74
74
}
75
75
76
+ ObjectCandidate ( idx) => {
77
+ let data = self . confirm_object_candidate ( obligation, idx) ?;
78
+ Ok ( ImplSource :: Object ( data) )
79
+ }
80
+
76
81
ClosureCandidate => {
77
82
let vtable_closure = self . confirm_closure_candidate ( obligation) ?;
78
83
Ok ( ImplSource :: Closure ( vtable_closure) )
@@ -97,11 +102,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
97
102
Ok ( ImplSource :: TraitAlias ( data) )
98
103
}
99
104
100
- ObjectCandidate => {
101
- let data = self . confirm_object_candidate ( obligation) ;
102
- Ok ( ImplSource :: Object ( data) )
103
- }
104
-
105
105
BuiltinObjectCandidate => {
106
106
// This indicates something like `Trait + Send: Send`. In this case, we know that
107
107
// this holds because that's what the object type is telling us, and there's really
@@ -365,9 +365,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
365
365
fn confirm_object_candidate (
366
366
& mut self ,
367
367
obligation : & TraitObligation < ' tcx > ,
368
- ) -> ImplSourceObjectData < ' tcx , PredicateObligation < ' tcx > > {
369
- debug ! ( ?obligation , "confirm_object_candidate" ) ;
368
+ index : usize ,
369
+ ) -> Result < ImplSourceObjectData < ' tcx , PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
370
370
let tcx = self . tcx ( ) ;
371
+ debug ! ( ?obligation, ?index, "confirm_object_candidate" ) ;
371
372
372
373
let trait_predicate =
373
374
self . infcx . replace_bound_vars_with_placeholders ( & obligation. predicate ) ;
@@ -393,43 +394,39 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
393
394
} )
394
395
. with_self_ty ( self . tcx ( ) , self_ty) ;
395
396
396
- let mut upcast_trait_ref = None ;
397
397
let mut nested = vec ! [ ] ;
398
- let vtable_base;
399
398
400
- {
401
- // We want to find the first supertrait in the list of
402
- // supertraits that we can unify with, and do that
403
- // unification. We know that there is exactly one in the list
404
- // where we can unify, because otherwise select would have
405
- // reported an ambiguity. (When we do find a match, also
406
- // record it for later.)
407
- let nonmatching = util:: supertraits ( tcx, ty:: Binder :: dummy ( object_trait_ref) )
408
- . take_while ( |& t| {
409
- match self . infcx . commit_if_ok ( |_| {
410
- self . infcx
411
- . at ( & obligation. cause , obligation. param_env )
412
- . sup ( obligation_trait_ref, t)
413
- . map ( |InferOk { obligations, .. } | obligations)
414
- . map_err ( |_| ( ) )
415
- } ) {
416
- Ok ( obligations) => {
417
- upcast_trait_ref = Some ( t) ;
418
- nested. extend ( obligations) ;
419
- false
420
- }
421
- Err ( _) => true ,
422
- }
423
- } ) ;
399
+ let mut supertraits = util:: supertraits ( tcx, ty:: Binder :: dummy ( object_trait_ref) ) ;
424
400
425
- // Additionally, for each of the non-matching predicates that
426
- // we pass over, we sum up the set of number of vtable
427
- // entries, so that we can compute the offset for the selected
428
- // trait.
429
- vtable_base = nonmatching. map ( |t| super :: util:: count_own_vtable_entries ( tcx, t) ) . sum ( ) ;
430
- }
401
+ // For each of the non-matching predicates that
402
+ // we pass over, we sum up the set of number of vtable
403
+ // entries, so that we can compute the offset for the selected
404
+ // trait.
405
+ let vtable_base = supertraits
406
+ . by_ref ( )
407
+ . take ( index)
408
+ . map ( |t| super :: util:: count_own_vtable_entries ( tcx, t) )
409
+ . sum ( ) ;
410
+
411
+ let unnormalized_upcast_trait_ref =
412
+ supertraits. next ( ) . expect ( "supertraits iterator no longer has as many elements" ) ;
413
+
414
+ let upcast_trait_ref = normalize_with_depth_to (
415
+ self ,
416
+ obligation. param_env ,
417
+ obligation. cause . clone ( ) ,
418
+ obligation. recursion_depth + 1 ,
419
+ & unnormalized_upcast_trait_ref,
420
+ & mut nested,
421
+ ) ;
431
422
432
- let upcast_trait_ref = upcast_trait_ref. unwrap ( ) ;
423
+ nested. extend ( self . infcx . commit_if_ok ( |_| {
424
+ self . infcx
425
+ . at ( & obligation. cause , obligation. param_env )
426
+ . sup ( obligation_trait_ref, upcast_trait_ref)
427
+ . map ( |InferOk { obligations, .. } | obligations)
428
+ . map_err ( |_| Unimplemented )
429
+ } ) ?) ;
433
430
434
431
// Check supertraits hold. This is so that their associated type bounds
435
432
// will be checked in the code below.
@@ -495,7 +492,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
495
492
}
496
493
497
494
debug ! ( ?nested, "object nested obligations" ) ;
498
- ImplSourceObjectData { upcast_trait_ref, vtable_base, nested }
495
+ Ok ( ImplSourceObjectData { upcast_trait_ref, vtable_base, nested } )
499
496
}
500
497
501
498
fn confirm_fn_pointer_candidate (
0 commit comments