@@ -1577,32 +1577,26 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1577
1577
}
1578
1578
1579
1579
self . probe ( |_| {
1580
- let mut err = error. err ;
1581
- let mut values = None ;
1580
+ let ocx = ObligationCtxt :: new_in_snapshot ( self ) ;
1582
1581
1583
1582
// try to find the mismatched types to report the error with.
1584
1583
//
1585
1584
// this can fail if the problem was higher-ranked, in which
1586
1585
// cause I have no idea for a good error message.
1587
1586
let bound_predicate = predicate. kind ( ) ;
1588
- if let ty:: PredicateKind :: Clause ( ty:: Clause :: Projection ( data) ) =
1587
+ let ( values , err ) = if let ty:: PredicateKind :: Clause ( ty:: Clause :: Projection ( data) ) =
1589
1588
bound_predicate. skip_binder ( )
1590
1589
{
1591
- let mut selcx = SelectionContext :: new ( self ) ;
1592
1590
let data = self . replace_bound_vars_with_fresh_vars (
1593
1591
obligation. cause . span ,
1594
1592
infer:: LateBoundRegionConversionTime :: HigherRankedType ,
1595
1593
bound_predicate. rebind ( data) ,
1596
1594
) ;
1597
- let mut obligations = vec ! [ ] ;
1598
- // FIXME(normalization): Change this to use `At::normalize`
1599
- let normalized_ty = super :: normalize_projection_type (
1600
- & mut selcx,
1595
+ let normalized_ty = ocx. normalize (
1596
+ & obligation. cause ,
1601
1597
obligation. param_env ,
1602
- data. projection_ty ,
1603
- obligation. cause . clone ( ) ,
1604
- 0 ,
1605
- & mut obligations,
1598
+ self . tcx
1599
+ . mk_projection ( data. projection_ty . item_def_id , data. projection_ty . substs ) ,
1606
1600
) ;
1607
1601
1608
1602
debug ! ( ?obligation. cause, ?obligation. param_env) ;
@@ -1618,19 +1612,34 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1618
1612
| ObligationCauseCode :: ObjectCastObligation ( ..)
1619
1613
| ObligationCauseCode :: OpaqueType
1620
1614
) ;
1621
- if let Err ( new_err) = self . at ( & obligation. cause , obligation. param_env ) . eq_exp (
1615
+ let expected_ty = data. term . ty ( ) . unwrap ( ) ;
1616
+
1617
+ // constrain inference variables a bit more to nested obligations from normalize so
1618
+ // we can have more helpful errors.
1619
+ ocx. select_where_possible ( ) ;
1620
+
1621
+ if let Err ( new_err) = ocx. eq_exp (
1622
+ & obligation. cause ,
1623
+ obligation. param_env ,
1622
1624
is_normalized_ty_expected,
1623
1625
normalized_ty,
1624
- data . term ,
1626
+ expected_ty ,
1625
1627
) {
1626
- values = Some ( ( data, is_normalized_ty_expected, normalized_ty, data. term ) ) ;
1627
- err = new_err;
1628
+ ( Some ( ( data, is_normalized_ty_expected, normalized_ty, expected_ty) ) , new_err)
1629
+ } else {
1630
+ ( None , error. err )
1628
1631
}
1629
- }
1632
+ } else {
1633
+ ( None , error. err )
1634
+ } ;
1630
1635
1631
1636
let msg = values
1632
1637
. and_then ( |( predicate, _, normalized_ty, expected_ty) | {
1633
- self . maybe_detailed_projection_msg ( predicate, normalized_ty, expected_ty)
1638
+ self . maybe_detailed_projection_msg (
1639
+ predicate,
1640
+ normalized_ty. into ( ) ,
1641
+ expected_ty. into ( ) ,
1642
+ )
1634
1643
} )
1635
1644
. unwrap_or_else ( || format ! ( "type mismatch resolving `{}`" , predicate) ) ;
1636
1645
let mut diag = struct_span_err ! ( self . tcx. sess, obligation. cause. span, E0271 , "{msg}" ) ;
@@ -1672,11 +1681,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1672
1681
& mut diag,
1673
1682
& obligation. cause ,
1674
1683
secondary_span,
1675
- values. map ( |( _, is_normalized_ty_expected, normalized_ty, term ) | {
1684
+ values. map ( |( _, is_normalized_ty_expected, normalized_ty, expected_ty ) | {
1676
1685
infer:: ValuePairs :: Terms ( ExpectedFound :: new (
1677
1686
is_normalized_ty_expected,
1678
- normalized_ty,
1679
- term ,
1687
+ normalized_ty. into ( ) ,
1688
+ expected_ty . into ( ) ,
1680
1689
) )
1681
1690
} ) ,
1682
1691
err,
0 commit comments