@@ -21,8 +21,10 @@ use super::VtableImplData;
21
21
22
22
use middle:: infer;
23
23
use middle:: subst:: Subst ;
24
- use middle:: ty:: { mod, AsPredicate , RegionEscape , HasProjectionTypes , ToPolyTraitRef , Ty } ;
24
+ use middle:: ty:: { mod, AsPredicate , ReferencesError , RegionEscape ,
25
+ HasProjectionTypes , ToPolyTraitRef , Ty } ;
25
26
use middle:: ty_fold:: { mod, TypeFoldable , TypeFolder } ;
27
+ use std:: rc:: Rc ;
26
28
use util:: ppaux:: Repr ;
27
29
28
30
pub type PolyProjectionObligation < ' tcx > =
@@ -372,22 +374,34 @@ fn project_type<'cx,'tcx>(
372
374
return Err ( ProjectionTyError :: TraitSelectionError ( Overflow ) ) ;
373
375
}
374
376
377
+ let obligation_trait_ref =
378
+ selcx. infcx ( ) . resolve_type_vars_if_possible ( & obligation. predicate . trait_ref ) ;
379
+
380
+ debug ! ( "project: obligation_trait_ref={}" , obligation_trait_ref. repr( selcx. tcx( ) ) ) ;
381
+
382
+ if obligation_trait_ref. references_error ( ) {
383
+ return Ok ( ProjectedTy :: Progress ( selcx. tcx ( ) . types . err , vec ! ( ) ) ) ;
384
+ }
385
+
375
386
let mut candidates = ProjectionTyCandidateSet {
376
387
vec : Vec :: new ( ) ,
377
388
ambiguous : false ,
378
389
} ;
379
390
380
391
assemble_candidates_from_object_type ( selcx,
381
392
obligation,
393
+ & obligation_trait_ref,
382
394
& mut candidates) ;
383
395
384
396
if candidates. vec . is_empty ( ) {
385
397
assemble_candidates_from_param_env ( selcx,
386
398
obligation,
399
+ & obligation_trait_ref,
387
400
& mut candidates) ;
388
401
389
402
if let Err ( e) = assemble_candidates_from_impls ( selcx,
390
403
obligation,
404
+ & obligation_trait_ref,
391
405
& mut candidates) {
392
406
return Err ( ProjectionTyError :: TraitSelectionError ( e) ) ;
393
407
}
@@ -421,17 +435,20 @@ fn project_type<'cx,'tcx>(
421
435
/// there that can answer this question.
422
436
fn assemble_candidates_from_param_env < ' cx , ' tcx > (
423
437
selcx : & mut SelectionContext < ' cx , ' tcx > ,
424
- obligation : & ProjectionTyObligation < ' tcx > ,
438
+ obligation : & ProjectionTyObligation < ' tcx > ,
439
+ obligation_trait_ref : & Rc < ty:: TraitRef < ' tcx > > ,
425
440
candidate_set : & mut ProjectionTyCandidateSet < ' tcx > )
426
441
{
427
442
let env_predicates = selcx. param_env ( ) . caller_bounds . predicates . clone ( ) ;
428
443
let env_predicates = env_predicates. iter ( ) . cloned ( ) . collect ( ) ;
429
- assemble_candidates_from_predicates ( selcx, obligation, candidate_set, env_predicates) ;
444
+ assemble_candidates_from_predicates ( selcx, obligation, obligation_trait_ref,
445
+ candidate_set, env_predicates) ;
430
446
}
431
447
432
448
fn assemble_candidates_from_predicates < ' cx , ' tcx > (
433
449
selcx : & mut SelectionContext < ' cx , ' tcx > ,
434
- obligation : & ProjectionTyObligation < ' tcx > ,
450
+ obligation : & ProjectionTyObligation < ' tcx > ,
451
+ obligation_trait_ref : & Rc < ty:: TraitRef < ' tcx > > ,
435
452
candidate_set : & mut ProjectionTyCandidateSet < ' tcx > ,
436
453
env_predicates : Vec < ty:: Predicate < ' tcx > > )
437
454
{
@@ -445,7 +462,7 @@ fn assemble_candidates_from_predicates<'cx,'tcx>(
445
462
let is_match = infcx. probe ( |_| {
446
463
let origin = infer:: Misc ( obligation. cause . span ) ;
447
464
let obligation_poly_trait_ref =
448
- obligation . predicate . trait_ref . to_poly_trait_ref ( ) ;
465
+ obligation_trait_ref . to_poly_trait_ref ( ) ;
449
466
let data_poly_trait_ref =
450
467
data. to_poly_trait_ref ( ) ;
451
468
infcx. sub_poly_trait_refs ( false ,
@@ -466,14 +483,14 @@ fn assemble_candidates_from_predicates<'cx,'tcx>(
466
483
467
484
fn assemble_candidates_from_object_type < ' cx , ' tcx > (
468
485
selcx : & mut SelectionContext < ' cx , ' tcx > ,
469
- obligation : & ProjectionTyObligation < ' tcx > ,
486
+ obligation : & ProjectionTyObligation < ' tcx > ,
487
+ obligation_trait_ref : & Rc < ty:: TraitRef < ' tcx > > ,
470
488
candidate_set : & mut ProjectionTyCandidateSet < ' tcx > )
471
489
{
472
490
let infcx = selcx. infcx ( ) ;
473
- let trait_ref = infcx. resolve_type_vars_if_possible ( & obligation. predicate . trait_ref ) ;
474
491
debug ! ( "assemble_candidates_from_object_type(trait_ref={})" ,
475
- trait_ref . repr( infcx. tcx) ) ;
476
- let self_ty = trait_ref . self_ty ( ) ;
492
+ obligation_trait_ref . repr( infcx. tcx) ) ;
493
+ let self_ty = obligation_trait_ref . self_ty ( ) ;
477
494
let data = match self_ty. sty {
478
495
ty:: ty_trait( ref data) => data,
479
496
_ => { return ; }
@@ -482,21 +499,21 @@ fn assemble_candidates_from_object_type<'cx,'tcx>(
482
499
let env_predicates = projection_bounds. iter ( )
483
500
. map ( |p| p. as_predicate ( ) )
484
501
. collect ( ) ;
485
- assemble_candidates_from_predicates ( selcx, obligation, candidate_set, env_predicates)
502
+ assemble_candidates_from_predicates ( selcx, obligation, obligation_trait_ref,
503
+ candidate_set, env_predicates)
486
504
}
487
505
488
506
fn assemble_candidates_from_impls < ' cx , ' tcx > (
489
507
selcx : & mut SelectionContext < ' cx , ' tcx > ,
490
508
obligation : & ProjectionTyObligation < ' tcx > ,
509
+ obligation_trait_ref : & Rc < ty:: TraitRef < ' tcx > > ,
491
510
candidate_set : & mut ProjectionTyCandidateSet < ' tcx > )
492
511
-> Result < ( ) , SelectionError < ' tcx > >
493
512
{
494
513
// If we are resolving `<T as TraitRef<...>>::Item == Type`,
495
514
// start out by selecting the predicate `T as TraitRef<...>`:
496
- let trait_ref =
497
- obligation. predicate . trait_ref . to_poly_trait_ref ( ) ;
498
- let trait_obligation =
499
- obligation. with ( trait_ref. to_poly_trait_predicate ( ) ) ;
515
+ let poly_trait_ref = obligation_trait_ref. to_poly_trait_ref ( ) ;
516
+ let trait_obligation = obligation. with ( poly_trait_ref. to_poly_trait_predicate ( ) ) ;
500
517
let vtable = match selcx. select ( & trait_obligation) {
501
518
Ok ( Some ( vtable) ) => vtable,
502
519
Ok ( None ) => {
0 commit comments