@@ -69,10 +69,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
69
69
}
70
70
71
71
ProjectionCandidate ( idx) => {
72
- let obligations = self . confirm_projection_candidate ( obligation, idx) ;
72
+ let obligations = self . confirm_projection_candidate ( obligation, idx) ? ;
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
@@ -120,7 +120,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
120
120
& mut self ,
121
121
obligation : & TraitObligation < ' tcx > ,
122
122
idx : usize ,
123
- ) -> Vec < PredicateObligation < ' tcx > > {
123
+ ) -> Result < Vec < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
124
124
self . infcx . commit_unconditionally ( |_| {
125
125
let tcx = self . tcx ( ) ;
126
126
@@ -148,19 +148,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
148
148
& mut obligations,
149
149
) ;
150
150
151
- obligations. extend (
151
+ obligations. extend ( self . infcx . commit_if_ok ( |_| {
152
152
self . infcx
153
153
. at ( & obligation. cause , obligation. param_env )
154
154
. sup ( placeholder_trait_predicate. trait_ref . to_poly_trait_ref ( ) , candidate)
155
155
. map ( |InferOk { obligations, .. } | obligations)
156
- . unwrap_or_else ( |_| {
157
- bug ! (
158
- "Projection bound `{:?}` was applicable to `{:?}` but now is not" ,
159
- candidate,
160
- obligation
161
- ) ;
162
- } ) ,
163
- ) ;
156
+ . map_err ( |_| Unimplemented )
157
+ } ) ?) ;
164
158
165
159
if let ty:: Projection ( ..) = placeholder_self_ty. kind ( ) {
166
160
for predicate in tcx. predicates_of ( def_id) . instantiate_own ( tcx, substs) . predicates {
@@ -181,7 +175,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
181
175
}
182
176
}
183
177
184
- obligations
178
+ Ok ( obligations)
185
179
} )
186
180
}
187
181
@@ -371,9 +365,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
371
365
fn confirm_object_candidate (
372
366
& mut self ,
373
367
obligation : & TraitObligation < ' tcx > ,
374
- ) -> ImplSourceObjectData < ' tcx , PredicateObligation < ' tcx > > {
375
- debug ! ( ?obligation , "confirm_object_candidate" ) ;
368
+ index : usize ,
369
+ ) -> Result < ImplSourceObjectData < ' tcx , PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
376
370
let tcx = self . tcx ( ) ;
371
+ debug ! ( ?obligation, ?index, "confirm_object_candidate" ) ;
377
372
378
373
let trait_predicate =
379
374
self . infcx . replace_bound_vars_with_placeholders ( & obligation. predicate ) ;
@@ -399,43 +394,39 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
399
394
} )
400
395
. with_self_ty ( self . tcx ( ) , self_ty) ;
401
396
402
- let mut upcast_trait_ref = None ;
403
397
let mut nested = vec ! [ ] ;
404
- let vtable_base;
405
398
406
- {
407
- // We want to find the first supertrait in the list of
408
- // supertraits that we can unify with, and do that
409
- // unification. We know that there is exactly one in the list
410
- // where we can unify, because otherwise select would have
411
- // reported an ambiguity. (When we do find a match, also
412
- // record it for later.)
413
- let nonmatching = util:: supertraits ( tcx, ty:: Binder :: dummy ( object_trait_ref) )
414
- . take_while ( |& t| {
415
- match self . infcx . commit_if_ok ( |_| {
416
- self . infcx
417
- . at ( & obligation. cause , obligation. param_env )
418
- . sup ( obligation_trait_ref, t)
419
- . map ( |InferOk { obligations, .. } | obligations)
420
- . map_err ( |_| ( ) )
421
- } ) {
422
- Ok ( obligations) => {
423
- upcast_trait_ref = Some ( t) ;
424
- nested. extend ( obligations) ;
425
- false
426
- }
427
- Err ( _) => true ,
428
- }
429
- } ) ;
399
+ let mut supertraits = util:: supertraits ( tcx, ty:: Binder :: dummy ( object_trait_ref) ) ;
430
400
431
- // Additionally, for each of the non-matching predicates that
432
- // we pass over, we sum up the set of number of vtable
433
- // entries, so that we can compute the offset for the selected
434
- // trait.
435
- vtable_base = nonmatching. map ( |t| super :: util:: count_own_vtable_entries ( tcx, t) ) . sum ( ) ;
436
- }
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
+ ) ;
437
422
438
- 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
+ } ) ?) ;
439
430
440
431
// Check supertraits hold. This is so that their associated type bounds
441
432
// will be checked in the code below.
@@ -501,7 +492,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
501
492
}
502
493
503
494
debug ! ( ?nested, "object nested obligations" ) ;
504
- ImplSourceObjectData { upcast_trait_ref, vtable_base, nested }
495
+ Ok ( ImplSourceObjectData { upcast_trait_ref, vtable_base, nested } )
505
496
}
506
497
507
498
fn confirm_fn_pointer_candidate (
0 commit comments