@@ -21,8 +21,10 @@ use super::VtableImplData;
2121
2222use middle:: infer;
2323use 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 } ;
2526use middle:: ty_fold:: { mod, TypeFoldable , TypeFolder } ;
27+ use std:: rc:: Rc ;
2628use util:: ppaux:: Repr ;
2729
2830pub type PolyProjectionObligation < ' tcx > =
@@ -372,22 +374,34 @@ fn project_type<'cx,'tcx>(
372374 return Err ( ProjectionTyError :: TraitSelectionError ( Overflow ) ) ;
373375 }
374376
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+
375386 let mut candidates = ProjectionTyCandidateSet {
376387 vec : Vec :: new ( ) ,
377388 ambiguous : false ,
378389 } ;
379390
380391 assemble_candidates_from_object_type ( selcx,
381392 obligation,
393+ & obligation_trait_ref,
382394 & mut candidates) ;
383395
384396 if candidates. vec . is_empty ( ) {
385397 assemble_candidates_from_param_env ( selcx,
386398 obligation,
399+ & obligation_trait_ref,
387400 & mut candidates) ;
388401
389402 if let Err ( e) = assemble_candidates_from_impls ( selcx,
390403 obligation,
404+ & obligation_trait_ref,
391405 & mut candidates) {
392406 return Err ( ProjectionTyError :: TraitSelectionError ( e) ) ;
393407 }
@@ -421,17 +435,20 @@ fn project_type<'cx,'tcx>(
421435/// there that can answer this question.
422436fn assemble_candidates_from_param_env < ' cx , ' tcx > (
423437 selcx : & mut SelectionContext < ' cx , ' tcx > ,
424- obligation : & ProjectionTyObligation < ' tcx > ,
438+ obligation : & ProjectionTyObligation < ' tcx > ,
439+ obligation_trait_ref : & Rc < ty:: TraitRef < ' tcx > > ,
425440 candidate_set : & mut ProjectionTyCandidateSet < ' tcx > )
426441{
427442 let env_predicates = selcx. param_env ( ) . caller_bounds . predicates . clone ( ) ;
428443 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) ;
430446}
431447
432448fn assemble_candidates_from_predicates < ' cx , ' tcx > (
433449 selcx : & mut SelectionContext < ' cx , ' tcx > ,
434- obligation : & ProjectionTyObligation < ' tcx > ,
450+ obligation : & ProjectionTyObligation < ' tcx > ,
451+ obligation_trait_ref : & Rc < ty:: TraitRef < ' tcx > > ,
435452 candidate_set : & mut ProjectionTyCandidateSet < ' tcx > ,
436453 env_predicates : Vec < ty:: Predicate < ' tcx > > )
437454{
@@ -445,7 +462,7 @@ fn assemble_candidates_from_predicates<'cx,'tcx>(
445462 let is_match = infcx. probe ( |_| {
446463 let origin = infer:: Misc ( obligation. cause . span ) ;
447464 let obligation_poly_trait_ref =
448- obligation . predicate . trait_ref . to_poly_trait_ref ( ) ;
465+ obligation_trait_ref . to_poly_trait_ref ( ) ;
449466 let data_poly_trait_ref =
450467 data. to_poly_trait_ref ( ) ;
451468 infcx. sub_poly_trait_refs ( false ,
@@ -466,14 +483,14 @@ fn assemble_candidates_from_predicates<'cx,'tcx>(
466483
467484fn assemble_candidates_from_object_type < ' cx , ' tcx > (
468485 selcx : & mut SelectionContext < ' cx , ' tcx > ,
469- obligation : & ProjectionTyObligation < ' tcx > ,
486+ obligation : & ProjectionTyObligation < ' tcx > ,
487+ obligation_trait_ref : & Rc < ty:: TraitRef < ' tcx > > ,
470488 candidate_set : & mut ProjectionTyCandidateSet < ' tcx > )
471489{
472490 let infcx = selcx. infcx ( ) ;
473- let trait_ref = infcx. resolve_type_vars_if_possible ( & obligation. predicate . trait_ref ) ;
474491 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 ( ) ;
477494 let data = match self_ty. sty {
478495 ty:: ty_trait( ref data) => data,
479496 _ => { return ; }
@@ -482,21 +499,21 @@ fn assemble_candidates_from_object_type<'cx,'tcx>(
482499 let env_predicates = projection_bounds. iter ( )
483500 . map ( |p| p. as_predicate ( ) )
484501 . 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)
486504}
487505
488506fn assemble_candidates_from_impls < ' cx , ' tcx > (
489507 selcx : & mut SelectionContext < ' cx , ' tcx > ,
490508 obligation : & ProjectionTyObligation < ' tcx > ,
509+ obligation_trait_ref : & Rc < ty:: TraitRef < ' tcx > > ,
491510 candidate_set : & mut ProjectionTyCandidateSet < ' tcx > )
492511 -> Result < ( ) , SelectionError < ' tcx > >
493512{
494513 // If we are resolving `<T as TraitRef<...>>::Item == Type`,
495514 // 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 ( ) ) ;
500517 let vtable = match selcx. select ( & trait_obligation) {
501518 Ok ( Some ( vtable) ) => vtable,
502519 Ok ( None ) => {
0 commit comments