@@ -15,6 +15,7 @@ use rustc_infer::infer::canonical::{Canonical, QueryResponse};
1515use rustc_infer:: infer:: error_reporting:: TypeAnnotationNeeded :: E0282 ;
1616use rustc_infer:: infer:: DefineOpaqueTypes ;
1717use rustc_infer:: infer:: { self , InferOk , TyCtxtInferExt } ;
18+ use rustc_infer:: traits:: EvaluationResult ;
1819use rustc_middle:: middle:: stability;
1920use rustc_middle:: query:: Providers ;
2021use rustc_middle:: ty:: fast_reject:: { simplify_type, TreatParams } ;
@@ -37,6 +38,7 @@ use rustc_trait_selection::traits::query::method_autoderef::{
3738 CandidateStep , MethodAutoderefStepsResult ,
3839} ;
3940use rustc_trait_selection:: traits:: query:: CanonicalTyGoal ;
41+ use rustc_trait_selection:: traits:: NormalizeExt ;
4042use rustc_trait_selection:: traits:: ObligationCtxt ;
4143use rustc_trait_selection:: traits:: { self , ObligationCause } ;
4244use std:: cell:: RefCell ;
@@ -1375,7 +1377,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
13751377 let impl_ty = self . tcx . type_of ( impl_def_id) . instantiate ( self . tcx , impl_args) ;
13761378 ( xform_self_ty, xform_ret_ty) =
13771379 self . xform_self_ty ( probe. item , impl_ty, impl_args) ;
1378- xform_self_ty = ocx. normalize ( cause, self . param_env , xform_self_ty) ;
1380+ let InferOk { value : normalized, mut obligations } =
1381+ self . at ( cause, self . param_env ) . normalize ( xform_self_ty) ;
1382+ xform_self_ty = normalized;
13791383 // FIXME: Make this `ocx.sup` once we define opaques more eagerly.
13801384 match self . at ( cause, self . param_env ) . sup (
13811385 DefineOpaqueTypes :: No ,
@@ -1397,8 +1401,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
13971401 let impl_bounds =
13981402 self . tcx . predicates_of ( impl_def_id) . instantiate ( self . tcx , impl_args) ;
13991403 let impl_bounds = ocx. normalize ( cause, self . param_env , impl_bounds) ;
1400- // Convert the bounds into obligations.
1401- ocx. register_obligations ( traits:: predicates_for_generics (
1404+ obligations. extend ( traits:: predicates_for_generics (
14021405 |idx, span| {
14031406 let code = if span. is_dummy ( ) {
14041407 traits:: ExprItemObligation ( impl_def_id, self . scope_expr_id , idx)
@@ -1415,6 +1418,32 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
14151418 self . param_env ,
14161419 impl_bounds,
14171420 ) ) ;
1421+
1422+ for obligation in obligations {
1423+ if self . infcx . next_trait_solver ( ) {
1424+ ocx. register_obligation ( obligation) ;
1425+ } else {
1426+ match self . infcx . evaluate_obligation_no_overflow ( & obligation) {
1427+ EvaluationResult :: EvaluatedToOk
1428+ | EvaluationResult :: EvaluatedToOkModuloRegions => {
1429+ // No side-effects, no need to register obligations.
1430+ }
1431+ EvaluationResult :: EvaluatedToOkModuloOpaqueTypes
1432+ | EvaluationResult :: EvaluatedToAmbig
1433+ | EvaluationResult :: EvaluatedToAmbigStackDependent => {
1434+ ocx. register_obligation ( obligation) ;
1435+ }
1436+ EvaluationResult :: EvaluatedToErr => {
1437+ result = ProbeResult :: NoMatch ;
1438+ possibly_unsatisfied_predicates. push ( (
1439+ self . resolve_vars_if_possible ( obligation. predicate ) ,
1440+ None ,
1441+ Some ( obligation. cause . clone ( ) ) ,
1442+ ) ) ;
1443+ }
1444+ }
1445+ }
1446+ }
14181447 }
14191448 TraitCandidate ( poly_trait_ref) => {
14201449 // Some trait methods are excluded for arrays before 2021.
@@ -1436,7 +1465,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
14361465 let trait_ref = ocx. normalize ( cause, self . param_env , trait_ref) ;
14371466 ( xform_self_ty, xform_ret_ty) =
14381467 self . xform_self_ty ( probe. item , trait_ref. self_ty ( ) , trait_ref. args ) ;
1439- xform_self_ty = ocx. normalize ( cause, self . param_env , xform_self_ty) ;
1468+
1469+ let InferOk { value : normalized, obligations : normalize_obligations } =
1470+ self . at ( cause, self . param_env ) . normalize ( xform_self_ty) ;
1471+ xform_self_ty = normalized;
1472+
14401473 // FIXME: Make this `ocx.sup` once we define opaques more eagerly.
14411474 match self . at ( cause, self . param_env ) . sup (
14421475 DefineOpaqueTypes :: No ,
@@ -1451,28 +1484,70 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
14511484 return ProbeResult :: NoMatch ;
14521485 }
14531486 }
1487+
1488+ for obligation in normalize_obligations {
1489+ if self . infcx . next_trait_solver ( ) {
1490+ ocx. register_obligation ( obligation) ;
1491+ } else {
1492+ match self . infcx . evaluate_obligation_no_overflow ( & obligation) {
1493+ EvaluationResult :: EvaluatedToOk
1494+ | EvaluationResult :: EvaluatedToOkModuloRegions => {
1495+ // No side-effects, no need to register obligations.
1496+ }
1497+ EvaluationResult :: EvaluatedToOkModuloOpaqueTypes
1498+ | EvaluationResult :: EvaluatedToAmbig
1499+ | EvaluationResult :: EvaluatedToAmbigStackDependent => {
1500+ ocx. register_obligation ( obligation) ;
1501+ }
1502+ EvaluationResult :: EvaluatedToErr => {
1503+ result = ProbeResult :: NoMatch ;
1504+ possibly_unsatisfied_predicates. push ( (
1505+ self . resolve_vars_if_possible ( obligation. predicate ) ,
1506+ None ,
1507+ Some ( obligation. cause . clone ( ) ) ,
1508+ ) ) ;
1509+ }
1510+ }
1511+ }
1512+ }
1513+
14541514 let obligation = traits:: Obligation :: new (
14551515 self . tcx ,
14561516 cause. clone ( ) ,
14571517 self . param_env ,
14581518 ty:: Binder :: dummy ( trait_ref) ,
14591519 ) ;
14601520
1461- // FIXME(-Znext-solver): We only need this hack to deal with fatal
1462- // overflow in the old solver.
1463- if self . infcx . next_trait_solver ( ) || self . infcx . predicate_may_hold ( & obligation)
1464- {
1521+ if self . infcx . next_trait_solver ( ) {
14651522 ocx. register_obligation ( obligation) ;
14661523 } else {
1467- result = ProbeResult :: NoMatch ;
1468- if let Ok ( Some ( candidate) ) = self . select_trait_candidate ( trait_ref) {
1469- for nested_obligation in candidate. nested_obligations ( ) {
1470- if !self . infcx . predicate_may_hold ( & nested_obligation) {
1471- possibly_unsatisfied_predicates. push ( (
1472- self . resolve_vars_if_possible ( nested_obligation. predicate ) ,
1473- Some ( self . resolve_vars_if_possible ( obligation. predicate ) ) ,
1474- Some ( nested_obligation. cause ) ,
1475- ) ) ;
1524+ match self . infcx . evaluate_obligation_no_overflow ( & obligation) {
1525+ EvaluationResult :: EvaluatedToOk => {
1526+ // No side-effects, no need to register obligations.
1527+ }
1528+ EvaluationResult :: EvaluatedToOkModuloRegions
1529+ | EvaluationResult :: EvaluatedToOkModuloOpaqueTypes
1530+ | EvaluationResult :: EvaluatedToAmbig
1531+ | EvaluationResult :: EvaluatedToAmbigStackDependent => {
1532+ ocx. register_obligation ( obligation) ;
1533+ }
1534+ EvaluationResult :: EvaluatedToErr => {
1535+ result = ProbeResult :: NoMatch ;
1536+ if let Ok ( Some ( candidate) ) = self . select_trait_candidate ( trait_ref)
1537+ {
1538+ for nested_obligation in candidate. nested_obligations ( ) {
1539+ if !self . infcx . predicate_may_hold ( & nested_obligation) {
1540+ possibly_unsatisfied_predicates. push ( (
1541+ self . resolve_vars_if_possible (
1542+ nested_obligation. predicate ,
1543+ ) ,
1544+ Some ( self . resolve_vars_if_possible (
1545+ obligation. predicate ,
1546+ ) ) ,
1547+ Some ( nested_obligation. cause ) ,
1548+ ) ) ;
1549+ }
1550+ }
14761551 }
14771552 }
14781553 }
@@ -1488,7 +1563,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
14881563 ) ;
14891564 ( xform_self_ty, xform_ret_ty) =
14901565 self . xform_self_ty ( probe. item , trait_ref. self_ty ( ) , trait_ref. args ) ;
1491- xform_self_ty = ocx. normalize ( cause, self . param_env , xform_self_ty) ;
1566+ let InferOk { value : normalized, obligations : normalize_obligations } =
1567+ self . at ( cause, self . param_env ) . normalize ( xform_self_ty) ;
1568+ xform_self_ty = normalized;
1569+
14921570 // FIXME: Make this `ocx.sup` once we define opaques more eagerly.
14931571 match self . at ( cause, self . param_env ) . sup (
14941572 DefineOpaqueTypes :: No ,
@@ -1503,26 +1581,55 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
15031581 return ProbeResult :: NoMatch ;
15041582 }
15051583 }
1584+
1585+ for obligation in normalize_obligations {
1586+ if self . infcx . next_trait_solver ( ) {
1587+ ocx. register_obligation ( obligation) ;
1588+ } else {
1589+ match self . infcx . evaluate_obligation_no_overflow ( & obligation) {
1590+ EvaluationResult :: EvaluatedToOk => {
1591+ // No side-effects, no need to register obligations.
1592+ }
1593+ EvaluationResult :: EvaluatedToOkModuloRegions
1594+ | EvaluationResult :: EvaluatedToOkModuloOpaqueTypes
1595+ | EvaluationResult :: EvaluatedToAmbig
1596+ | EvaluationResult :: EvaluatedToAmbigStackDependent => {
1597+ ocx. register_obligation ( obligation) ;
1598+ }
1599+ EvaluationResult :: EvaluatedToErr => {
1600+ result = ProbeResult :: NoMatch ;
1601+ possibly_unsatisfied_predicates. push ( (
1602+ self . resolve_vars_if_possible ( obligation. predicate ) ,
1603+ None ,
1604+ Some ( obligation. cause . clone ( ) ) ,
1605+ ) ) ;
1606+ }
1607+ }
1608+ }
1609+ }
15061610 }
15071611 }
15081612
15091613 // Evaluate those obligations to see if they might possibly hold.
1510- for error in ocx. select_where_possible ( ) {
1511- result = ProbeResult :: NoMatch ;
1512- let nested_predicate = self . resolve_vars_if_possible ( error. obligation . predicate ) ;
1513- if let Some ( trait_predicate) = trait_predicate
1514- && nested_predicate == self . resolve_vars_if_possible ( trait_predicate)
1515- {
1516- // Don't report possibly unsatisfied predicates if the root
1517- // trait obligation from a `TraitCandidate` is unsatisfied.
1518- // That just means the candidate doesn't hold.
1519- } else {
1520- possibly_unsatisfied_predicates. push ( (
1521- nested_predicate,
1522- Some ( self . resolve_vars_if_possible ( error. root_obligation . predicate ) )
1523- . filter ( |root_predicate| * root_predicate != nested_predicate) ,
1524- Some ( error. obligation . cause ) ,
1525- ) ) ;
1614+ if let ProbeResult :: Match = result {
1615+ for error in ocx. select_where_possible ( ) {
1616+ result = ProbeResult :: NoMatch ;
1617+ let nested_predicate =
1618+ self . resolve_vars_if_possible ( error. obligation . predicate ) ;
1619+ if let Some ( trait_predicate) = trait_predicate
1620+ && nested_predicate == self . resolve_vars_if_possible ( trait_predicate)
1621+ {
1622+ // Don't report possibly unsatisfied predicates if the root
1623+ // trait obligation from a `TraitCandidate` is unsatisfied.
1624+ // That just means the candidate doesn't hold.
1625+ } else {
1626+ possibly_unsatisfied_predicates. push ( (
1627+ nested_predicate,
1628+ Some ( self . resolve_vars_if_possible ( error. root_obligation . predicate ) )
1629+ . filter ( |root_predicate| * root_predicate != nested_predicate) ,
1630+ Some ( error. obligation . cause ) ,
1631+ ) ) ;
1632+ }
15261633 }
15271634 }
15281635
0 commit comments