@@ -1382,6 +1382,41 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
1382
1382
1383
1383
#[ extension( pub ( super ) trait InferCtxtPrivExt <' tcx>) ]
1384
1384
impl < ' tcx > TypeErrCtxt < ' _ , ' tcx > {
1385
+ fn can_match_trait (
1386
+ & self ,
1387
+ goal : ty:: TraitPredicate < ' tcx > ,
1388
+ assumption : ty:: PolyTraitPredicate < ' tcx > ,
1389
+ ) -> bool {
1390
+ if goal. polarity != assumption. polarity ( ) {
1391
+ return false ;
1392
+ }
1393
+
1394
+ let trait_goal = goal. trait_ref ;
1395
+ let trait_assumption = self . instantiate_binder_with_fresh_vars (
1396
+ DUMMY_SP ,
1397
+ infer:: BoundRegionConversionTime :: HigherRankedType ,
1398
+ assumption. to_poly_trait_ref ( ) ,
1399
+ ) ;
1400
+
1401
+ self . can_eq ( ty:: ParamEnv :: empty ( ) , trait_goal, trait_assumption)
1402
+ }
1403
+
1404
+ fn can_match_projection (
1405
+ & self ,
1406
+ goal : ty:: ProjectionPredicate < ' tcx > ,
1407
+ assumption : ty:: PolyProjectionPredicate < ' tcx > ,
1408
+ ) -> bool {
1409
+ let assumption = self . instantiate_binder_with_fresh_vars (
1410
+ DUMMY_SP ,
1411
+ infer:: BoundRegionConversionTime :: HigherRankedType ,
1412
+ assumption,
1413
+ ) ;
1414
+
1415
+ let param_env = ty:: ParamEnv :: empty ( ) ;
1416
+ self . can_eq ( param_env, goal. projection_ty , assumption. projection_ty )
1417
+ && self . can_eq ( param_env, goal. term , assumption. term )
1418
+ }
1419
+
1385
1420
// returns if `cond` not occurring implies that `error` does not occur - i.e., that
1386
1421
// `error` occurring implies that `cond` occurs.
1387
1422
fn error_implies ( & self , cond : ty:: Predicate < ' tcx > , error : ty:: Predicate < ' tcx > ) -> bool {
@@ -1390,39 +1425,27 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
1390
1425
}
1391
1426
1392
1427
if let Some ( error) = error. to_opt_poly_trait_pred ( ) {
1393
- elaborate ( self . tcx , std:: iter:: once ( cond) )
1394
- . filter_map ( |implied| implied. to_opt_poly_trait_pred ( ) )
1395
- . any ( |implied| {
1396
- if error. polarity ( ) != implied. polarity ( ) {
1397
- return false ;
1398
- }
1399
- let error = error. to_poly_trait_ref ( ) ;
1400
- let implied = implied. to_poly_trait_ref ( ) ;
1401
- // FIXME: I'm just not taking associated types at all here.
1402
- // Eventually I'll need to implement param-env-aware
1403
- // `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic.
1404
- let param_env = ty:: ParamEnv :: empty ( ) ;
1405
- let is_implied = self . can_sub ( param_env, error, implied) ;
1406
- if is_implied {
1407
- debug ! ( "error_implies: {:?} -> {:?} -> {:?}" , cond, error, implied) ;
1408
- }
1409
- is_implied
1410
- } )
1428
+ self . enter_forall ( error, |error| {
1429
+ elaborate ( self . tcx , std:: iter:: once ( cond) )
1430
+ . filter_map ( |implied| implied. to_opt_poly_trait_pred ( ) )
1431
+ . any ( |implied| {
1432
+ let is_implied = self . can_match_trait ( error, implied) ;
1433
+ if is_implied {
1434
+ debug ! ( "error_implies: {:?} -> {:?} -> {:?}" , cond, error, implied) ;
1435
+ }
1436
+ is_implied
1437
+ } )
1438
+ } )
1411
1439
} else if let Some ( error) = error. to_opt_poly_projection_pred ( ) {
1412
1440
self . enter_forall ( error, |error| {
1413
1441
elaborate ( self . tcx , std:: iter:: once ( cond) )
1414
1442
. filter_map ( |implied| implied. to_opt_poly_projection_pred ( ) )
1415
1443
. any ( |implied| {
1416
- self . enter_forall ( implied, |implied| {
1417
- let param_env = ty:: ParamEnv :: empty ( ) ;
1418
- let is_implied =
1419
- self . can_eq ( param_env, error. projection_ty , implied. projection_ty )
1420
- && self . can_eq ( param_env, error. term , implied. term ) ;
1421
- if is_implied {
1422
- debug ! ( "error_implies: {:?} -> {:?} -> {:?}" , cond, error, implied) ;
1423
- }
1424
- is_implied
1425
- } )
1444
+ let is_implied = self . can_match_projection ( error, implied) ;
1445
+ if is_implied {
1446
+ debug ! ( "error_implies: {:?} -> {:?} -> {:?}" , cond, error, implied) ;
1447
+ }
1448
+ is_implied
1426
1449
} )
1427
1450
} )
1428
1451
} else {
0 commit comments