@@ -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 } ;
@@ -37,6 +38,7 @@ use rustc_trait_selection::traits::query::method_autoderef::{
37
38
CandidateStep , MethodAutoderefStepsResult ,
38
39
} ;
39
40
use rustc_trait_selection:: traits:: query:: CanonicalTyGoal ;
41
+ use rustc_trait_selection:: traits:: NormalizeExt ;
40
42
use rustc_trait_selection:: traits:: ObligationCtxt ;
41
43
use rustc_trait_selection:: traits:: { self , ObligationCause } ;
42
44
use std:: cell:: RefCell ;
@@ -1375,7 +1377,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1375
1377
let impl_ty = self . tcx . type_of ( impl_def_id) . instantiate ( self . tcx , impl_args) ;
1376
1378
( xform_self_ty, xform_ret_ty) =
1377
1379
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;
1379
1383
// FIXME: Make this `ocx.sup` once we define opaques more eagerly.
1380
1384
match self . at ( cause, self . param_env ) . sup (
1381
1385
DefineOpaqueTypes :: No ,
@@ -1397,8 +1401,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1397
1401
let impl_bounds =
1398
1402
self . tcx . predicates_of ( impl_def_id) . instantiate ( self . tcx , impl_args) ;
1399
1403
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 (
1402
1405
|idx, span| {
1403
1406
let code = if span. is_dummy ( ) {
1404
1407
traits:: ExprItemObligation ( impl_def_id, self . scope_expr_id , idx)
@@ -1415,6 +1418,32 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1415
1418
self . param_env ,
1416
1419
impl_bounds,
1417
1420
) ) ;
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
+ }
1418
1447
}
1419
1448
TraitCandidate ( poly_trait_ref) => {
1420
1449
// Some trait methods are excluded for arrays before 2021.
@@ -1436,7 +1465,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1436
1465
let trait_ref = ocx. normalize ( cause, self . param_env , trait_ref) ;
1437
1466
( xform_self_ty, xform_ret_ty) =
1438
1467
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
+
1440
1473
// FIXME: Make this `ocx.sup` once we define opaques more eagerly.
1441
1474
match self . at ( cause, self . param_env ) . sup (
1442
1475
DefineOpaqueTypes :: No ,
@@ -1451,28 +1484,70 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1451
1484
return ProbeResult :: NoMatch ;
1452
1485
}
1453
1486
}
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
+
1454
1514
let obligation = traits:: Obligation :: new (
1455
1515
self . tcx ,
1456
1516
cause. clone ( ) ,
1457
1517
self . param_env ,
1458
1518
ty:: Binder :: dummy ( trait_ref) ,
1459
1519
) ;
1460
1520
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 ( ) {
1465
1522
ocx. register_obligation ( obligation) ;
1466
1523
} 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
+ }
1476
1551
}
1477
1552
}
1478
1553
}
@@ -1488,7 +1563,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1488
1563
) ;
1489
1564
( xform_self_ty, xform_ret_ty) =
1490
1565
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
+
1492
1570
// FIXME: Make this `ocx.sup` once we define opaques more eagerly.
1493
1571
match self . at ( cause, self . param_env ) . sup (
1494
1572
DefineOpaqueTypes :: No ,
@@ -1503,26 +1581,55 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1503
1581
return ProbeResult :: NoMatch ;
1504
1582
}
1505
1583
}
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
+ }
1506
1610
}
1507
1611
}
1508
1612
1509
1613
// 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
+ }
1526
1633
}
1527
1634
}
1528
1635
0 commit comments