@@ -59,10 +59,12 @@ struct Candidate<'tcx> {
59
59
}
60
60
61
61
enum CandidateKind < ' tcx > {
62
- InherentImplCandidate ( /* Impl */ ast:: DefId , subst:: Substs < ' tcx > ) ,
62
+ InherentImplCandidate ( /* Impl */ ast:: DefId , subst:: Substs < ' tcx > ,
63
+ /* Normalize obligations */ Vec < traits:: PredicateObligation < ' tcx > > ) ,
63
64
ObjectCandidate ( /* Trait */ ast:: DefId , /* method_num */ usize , /* vtable index */ usize ) ,
64
65
ExtensionImplCandidate ( /* Impl */ ast:: DefId , ty:: TraitRef < ' tcx > ,
65
- subst:: Substs < ' tcx > , ItemIndex ) ,
66
+ subst:: Substs < ' tcx > , ItemIndex ,
67
+ /* Normalize obligations */ Vec < traits:: PredicateObligation < ' tcx > > ) ,
66
68
ClosureCandidate ( /* Trait */ ast:: DefId , ItemIndex ) ,
67
69
WhereClauseCandidate ( ty:: PolyTraitRef < ' tcx > , ItemIndex ) ,
68
70
ProjectionCandidate ( ast:: DefId , ItemIndex ) ,
@@ -398,24 +400,24 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
398
400
}
399
401
400
402
let ( impl_ty, impl_substs) = self . impl_ty_and_substs ( impl_def_id) ;
403
+ let impl_ty = impl_ty. subst ( self . tcx ( ) , & impl_substs) ;
401
404
402
- // We can't use instantiate_type_scheme here as it will pollute
403
- // the fcx's fulfillment context if this probe is rolled back.
405
+ // Determine the receiver type that the method itself expects.
406
+ let xform_self_ty = self . xform_self_ty ( & item, impl_ty, & impl_substs) ;
407
+
408
+ // We can't use normalize_associated_types_in as it will pollute the
409
+ // fcx's fulfillment context after this probe is over.
404
410
let cause = traits:: ObligationCause :: misc ( self . span , self . fcx . body_id ) ;
405
411
let mut selcx = & mut traits:: SelectionContext :: new ( self . fcx . infcx ( ) , self . fcx ) ;
406
- let traits:: Normalized { value : impl_ty, .. } =
407
- traits:: normalize ( selcx, cause, & impl_ty. subst ( self . tcx ( ) , & impl_substs) ) ;
408
-
409
- // Determine the receiver type that the method itself expects.
410
- let xform_self_ty =
411
- self . xform_self_ty ( & item, impl_ty, & impl_substs) ;
412
- debug ! ( "assemble_inherent_impl_probe: self ty = {:?}" ,
412
+ let traits:: Normalized { value : xform_self_ty, obligations } =
413
+ traits:: normalize ( selcx, cause, & xform_self_ty) ;
414
+ debug ! ( "assemble_inherent_impl_probe: xform_self_ty = {:?}" ,
413
415
xform_self_ty. repr( self . tcx( ) ) ) ;
414
416
415
417
self . inherent_candidates . push ( Candidate {
416
418
xform_self_ty : xform_self_ty,
417
419
item : item,
418
- kind : InherentImplCandidate ( impl_def_id, impl_substs)
420
+ kind : InherentImplCandidate ( impl_def_id, impl_substs, obligations )
419
421
} ) ;
420
422
}
421
423
@@ -661,12 +663,24 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
661
663
impl_trait_ref. self_ty ( ) ,
662
664
impl_trait_ref. substs ) ;
663
665
666
+ // Normalize the receiver. We can't use normalize_associated_types_in
667
+ // as it will pollute the fcx's fulfillment context after this probe
668
+ // is over.
669
+ let cause = traits:: ObligationCause :: misc ( self . span , self . fcx . body_id ) ;
670
+ let mut selcx = & mut traits:: SelectionContext :: new ( self . fcx . infcx ( ) , self . fcx ) ;
671
+ let traits:: Normalized { value : xform_self_ty, obligations } =
672
+ traits:: normalize ( selcx, cause, & xform_self_ty) ;
673
+
664
674
debug ! ( "xform_self_ty={}" , xform_self_ty. repr( self . tcx( ) ) ) ;
665
675
666
676
self . extension_candidates . push ( Candidate {
667
677
xform_self_ty : xform_self_ty,
668
678
item : item. clone ( ) ,
669
- kind : ExtensionImplCandidate ( impl_def_id, impl_trait_ref, impl_substs, item_index)
679
+ kind : ExtensionImplCandidate ( impl_def_id,
680
+ impl_trait_ref,
681
+ impl_substs,
682
+ item_index,
683
+ obligations)
670
684
} ) ;
671
685
} ) ;
672
686
}
@@ -1034,8 +1048,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
1034
1048
// match as well (or at least may match, sometimes we
1035
1049
// don't have enough information to fully evaluate).
1036
1050
match probe. kind {
1037
- InherentImplCandidate ( impl_def_id, ref substs) |
1038
- ExtensionImplCandidate ( impl_def_id, _, ref substs, _) => {
1051
+ InherentImplCandidate ( impl_def_id, ref substs, ref ref_obligations ) |
1052
+ ExtensionImplCandidate ( impl_def_id, _, ref substs, _, ref ref_obligations ) => {
1039
1053
let selcx = & mut traits:: SelectionContext :: new ( self . infcx ( ) , self . fcx ) ;
1040
1054
let cause = traits:: ObligationCause :: misc ( self . span , self . fcx . body_id ) ;
1041
1055
@@ -1054,8 +1068,10 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
1054
1068
debug ! ( "impl_obligations={}" , obligations. repr( self . tcx( ) ) ) ;
1055
1069
1056
1070
// Evaluate those obligations to see if they might possibly hold.
1057
- obligations. iter ( ) . all ( |o| selcx. evaluate_obligation ( o) ) &&
1058
- norm_obligations. iter ( ) . all ( |o| selcx. evaluate_obligation ( o) )
1071
+ obligations. iter ( )
1072
+ . chain ( norm_obligations. iter ( ) ) . chain ( ref_obligations. iter ( ) )
1073
+ . all ( |o| selcx. evaluate_obligation ( o) )
1074
+
1059
1075
}
1060
1076
1061
1077
ProjectionCandidate ( ..) |
@@ -1289,13 +1305,13 @@ impl<'tcx> Candidate<'tcx> {
1289
1305
Pick {
1290
1306
item : self . item . clone ( ) ,
1291
1307
kind : match self . kind {
1292
- InherentImplCandidate ( def_id, _) => {
1308
+ InherentImplCandidate ( def_id, _, _ ) => {
1293
1309
InherentImplPick ( def_id)
1294
1310
}
1295
1311
ObjectCandidate ( def_id, item_num, real_index) => {
1296
1312
ObjectPick ( def_id, item_num, real_index)
1297
1313
}
1298
- ExtensionImplCandidate ( def_id, _, _, index) => {
1314
+ ExtensionImplCandidate ( def_id, _, _, index, _ ) => {
1299
1315
ExtensionImplPick ( def_id, index)
1300
1316
}
1301
1317
ClosureCandidate ( trait_def_id, index) => {
@@ -1323,9 +1339,9 @@ impl<'tcx> Candidate<'tcx> {
1323
1339
1324
1340
fn to_source ( & self ) -> CandidateSource {
1325
1341
match self . kind {
1326
- InherentImplCandidate ( def_id, _) => ImplSource ( def_id) ,
1342
+ InherentImplCandidate ( def_id, _, _ ) => ImplSource ( def_id) ,
1327
1343
ObjectCandidate ( def_id, _, _) => TraitSource ( def_id) ,
1328
- ExtensionImplCandidate ( def_id, _, _, _) => ImplSource ( def_id) ,
1344
+ ExtensionImplCandidate ( def_id, _, _, _, _ ) => ImplSource ( def_id) ,
1329
1345
ClosureCandidate ( trait_def_id, _) => TraitSource ( trait_def_id) ,
1330
1346
WhereClauseCandidate ( ref trait_ref, _) => TraitSource ( trait_ref. def_id ( ) ) ,
1331
1347
ProjectionCandidate ( trait_def_id, _) => TraitSource ( trait_def_id) ,
@@ -1343,7 +1359,7 @@ impl<'tcx> Candidate<'tcx> {
1343
1359
ClosureCandidate ( trait_def_id, item_num) => {
1344
1360
Some ( ( trait_def_id, item_num) )
1345
1361
}
1346
- ExtensionImplCandidate ( _, ref trait_ref, _, item_num) => {
1362
+ ExtensionImplCandidate ( _, ref trait_ref, _, item_num, _ ) => {
1347
1363
Some ( ( trait_ref. def_id , item_num) )
1348
1364
}
1349
1365
WhereClauseCandidate ( ref trait_ref, item_num) => {
@@ -1367,13 +1383,14 @@ impl<'tcx> Repr<'tcx> for Candidate<'tcx> {
1367
1383
impl < ' tcx > Repr < ' tcx > for CandidateKind < ' tcx > {
1368
1384
fn repr ( & self , tcx : & ty:: ctxt < ' tcx > ) -> String {
1369
1385
match * self {
1370
- InherentImplCandidate ( ref a, ref b) =>
1371
- format ! ( "InherentImplCandidate({},{})" , a. repr( tcx) , b. repr( tcx) ) ,
1386
+ InherentImplCandidate ( ref a, ref b, ref c) =>
1387
+ format ! ( "InherentImplCandidate({},{},{})" , a. repr( tcx) , b. repr( tcx) ,
1388
+ c. repr( tcx) ) ,
1372
1389
ObjectCandidate ( a, b, c) =>
1373
1390
format ! ( "ObjectCandidate({},{},{})" , a. repr( tcx) , b, c) ,
1374
- ExtensionImplCandidate ( ref a, ref b, ref c, ref d) =>
1375
- format ! ( "ExtensionImplCandidate({},{},{},{})" , a. repr( tcx) , b. repr( tcx) ,
1376
- c. repr( tcx) , d) ,
1391
+ ExtensionImplCandidate ( ref a, ref b, ref c, ref d, ref e ) =>
1392
+ format ! ( "ExtensionImplCandidate({},{},{},{},{} )" , a. repr( tcx) , b. repr( tcx) ,
1393
+ c. repr( tcx) , d, e . repr ( tcx ) ) ,
1377
1394
ClosureCandidate ( ref a, ref b) =>
1378
1395
format ! ( "ClosureCandidate({},{})" , a. repr( tcx) , b) ,
1379
1396
WhereClauseCandidate ( ref a, ref b) =>
0 commit comments