@@ -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+ // No side-effects, no need to register obligations.
1429+ }
1430+ EvaluationResult::EvaluatedToOkModuloRegions
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+ // No side-effects, no need to register obligations.
1495+ }
1496+ EvaluationResult::EvaluatedToOkModuloRegions
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