@@ -1382,6 +1382,41 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
13821382
13831383#[ extension( pub ( super ) trait InferCtxtPrivExt <' tcx>) ]
13841384impl < ' 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+
13851420 // returns if `cond` not occurring implies that `error` does not occur - i.e., that
13861421 // `error` occurring implies that `cond` occurs.
13871422 fn error_implies ( & self , cond : ty:: Predicate < ' tcx > , error : ty:: Predicate < ' tcx > ) -> bool {
@@ -1390,39 +1425,27 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
13901425 }
13911426
13921427 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+ } )
14111439 } else if let Some ( error) = error. to_opt_poly_projection_pred ( ) {
14121440 self . enter_forall ( error, |error| {
14131441 elaborate ( self . tcx , std:: iter:: once ( cond) )
14141442 . filter_map ( |implied| implied. to_opt_poly_projection_pred ( ) )
14151443 . 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
14261449 } )
14271450 } )
14281451 } else {
0 commit comments