@@ -15,6 +15,7 @@ use rustc_infer::infer::canonical::{Canonical, QueryResponse};
15
15
use rustc_infer:: infer:: error_reporting:: TypeAnnotationNeeded :: E0282 ;
16
16
use rustc_infer:: infer:: DefineOpaqueTypes ;
17
17
use rustc_infer:: infer:: { self , InferOk , TyCtxtInferExt } ;
18
+ use rustc_infer:: traits:: EvaluationResult ;
18
19
use rustc_middle:: middle:: stability;
19
20
use rustc_middle:: query:: Providers ;
20
21
use rustc_middle:: ty:: fast_reject:: { simplify_type, TreatParams } ;
@@ -1397,8 +1398,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1397
1398
let impl_bounds =
1398
1399
self . tcx . predicates_of ( impl_def_id) . instantiate ( self . tcx , impl_args) ;
1399
1400
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 (
1401
+ for obligation in traits:: predicates_for_generics (
1402
1402
|idx, span| {
1403
1403
let code = if span. is_dummy ( ) {
1404
1404
traits:: ExprItemObligation ( impl_def_id, self . scope_expr_id , idx)
@@ -1414,7 +1414,31 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1414
1414
} ,
1415
1415
self . param_env ,
1416
1416
impl_bounds,
1417
- ) ) ;
1417
+ ) {
1418
+ if self . infcx . next_trait_solver ( ) {
1419
+ ocx. register_obligation ( obligation) ;
1420
+ } else {
1421
+ match self . infcx . evaluate_obligation_no_overflow ( & obligation) {
1422
+ EvaluationResult :: EvaluatedToOk => {
1423
+ // No side-effects, no need to register obligations.
1424
+ }
1425
+ EvaluationResult :: EvaluatedToOkModuloRegions
1426
+ | EvaluationResult :: EvaluatedToOkModuloOpaqueTypes
1427
+ | EvaluationResult :: EvaluatedToAmbig
1428
+ | EvaluationResult :: EvaluatedToAmbigStackDependent => {
1429
+ ocx. register_obligation ( obligation) ;
1430
+ }
1431
+ EvaluationResult :: EvaluatedToErr => {
1432
+ result = ProbeResult :: NoMatch ;
1433
+ possibly_unsatisfied_predicates. push ( (
1434
+ self . resolve_vars_if_possible ( obligation. predicate ) ,
1435
+ None ,
1436
+ Some ( obligation. cause . clone ( ) ) ,
1437
+ ) ) ;
1438
+ }
1439
+ }
1440
+ }
1441
+ }
1418
1442
}
1419
1443
TraitCandidate ( poly_trait_ref) => {
1420
1444
// Some trait methods are excluded for arrays before 2021.
@@ -1458,21 +1482,36 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1458
1482
ty:: Binder :: dummy ( trait_ref) ,
1459
1483
) ;
1460
1484
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
- {
1485
+ if self . infcx . next_trait_solver ( ) {
1465
1486
ocx. register_obligation ( obligation) ;
1466
1487
} 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
- ) ) ;
1488
+ match self . infcx . evaluate_obligation_no_overflow ( & obligation) {
1489
+ EvaluationResult :: EvaluatedToOk => {
1490
+ // No side-effects, no need to register obligations.
1491
+ }
1492
+ EvaluationResult :: EvaluatedToOkModuloRegions
1493
+ | EvaluationResult :: EvaluatedToOkModuloOpaqueTypes
1494
+ | EvaluationResult :: EvaluatedToAmbig
1495
+ | EvaluationResult :: EvaluatedToAmbigStackDependent => {
1496
+ ocx. register_obligation ( obligation) ;
1497
+ }
1498
+ EvaluationResult :: EvaluatedToErr => {
1499
+ result = ProbeResult :: NoMatch ;
1500
+ if let Ok ( Some ( candidate) ) = self . select_trait_candidate ( trait_ref)
1501
+ {
1502
+ for nested_obligation in candidate. nested_obligations ( ) {
1503
+ if !self . infcx . predicate_may_hold ( & nested_obligation) {
1504
+ possibly_unsatisfied_predicates. push ( (
1505
+ self . resolve_vars_if_possible (
1506
+ nested_obligation. predicate ,
1507
+ ) ,
1508
+ Some ( self . resolve_vars_if_possible (
1509
+ obligation. predicate ,
1510
+ ) ) ,
1511
+ Some ( nested_obligation. cause ) ,
1512
+ ) ) ;
1513
+ }
1514
+ }
1476
1515
}
1477
1516
}
1478
1517
}
@@ -1507,22 +1546,25 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1507
1546
}
1508
1547
1509
1548
// 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
- ) ) ;
1549
+ if let ProbeResult :: Match = result {
1550
+ for error in ocx. select_where_possible ( ) {
1551
+ result = ProbeResult :: NoMatch ;
1552
+ let nested_predicate =
1553
+ self . resolve_vars_if_possible ( error. obligation . predicate ) ;
1554
+ if let Some ( trait_predicate) = trait_predicate
1555
+ && nested_predicate == self . resolve_vars_if_possible ( trait_predicate)
1556
+ {
1557
+ // Don't report possibly unsatisfied predicates if the root
1558
+ // trait obligation from a `TraitCandidate` is unsatisfied.
1559
+ // That just means the candidate doesn't hold.
1560
+ } else {
1561
+ possibly_unsatisfied_predicates. push ( (
1562
+ nested_predicate,
1563
+ Some ( self . resolve_vars_if_possible ( error. root_obligation . predicate ) )
1564
+ . filter ( |root_predicate| * root_predicate != nested_predicate) ,
1565
+ Some ( error. obligation . cause ) ,
1566
+ ) ) ;
1567
+ }
1526
1568
}
1527
1569
}
1528
1570
0 commit comments