@@ -1576,9 +1576,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1576
1576
return ;
1577
1577
}
1578
1578
1579
+ let mut values = None ;
1580
+
1579
1581
self . probe ( |_| {
1582
+ let ocx = ObligationCtxt :: new_in_snapshot ( self ) ;
1580
1583
let mut err = error. err ;
1581
- let mut values = None ;
1582
1584
1583
1585
// try to find the mismatched types to report the error with.
1584
1586
//
@@ -1588,21 +1590,16 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1588
1590
if let ty:: PredicateKind :: Clause ( ty:: Clause :: Projection ( data) ) =
1589
1591
bound_predicate. skip_binder ( )
1590
1592
{
1591
- let mut selcx = SelectionContext :: new ( self ) ;
1592
1593
let data = self . replace_bound_vars_with_fresh_vars (
1593
1594
obligation. cause . span ,
1594
1595
infer:: LateBoundRegionConversionTime :: HigherRankedType ,
1595
1596
bound_predicate. rebind ( data) ,
1596
1597
) ;
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,
1598
+ let normalized_ty = ocx. normalize (
1599
+ & obligation. cause ,
1601
1600
obligation. param_env ,
1602
- data. projection_ty ,
1603
- obligation. cause . clone ( ) ,
1604
- 0 ,
1605
- & mut obligations,
1601
+ self . tcx
1602
+ . mk_projection ( data. projection_ty . item_def_id , data. projection_ty . substs ) ,
1606
1603
) ;
1607
1604
1608
1605
debug ! ( ?obligation. cause, ?obligation. param_env) ;
@@ -1618,19 +1615,31 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1618
1615
| ObligationCauseCode :: ObjectCastObligation ( ..)
1619
1616
| ObligationCauseCode :: OpaqueType
1620
1617
) ;
1621
- if let Err ( new_err) = self . at ( & obligation. cause , obligation. param_env ) . eq_exp (
1618
+ let expected_ty = data. term . ty ( ) . unwrap ( ) ;
1619
+
1620
+ // constrain inference variables a bit more to nested obligations from normalize so
1621
+ // we can have more helpful errors.
1622
+ ocx. select_where_possible ( ) ;
1623
+
1624
+ if let Err ( new_err) = ocx. eq_exp (
1625
+ & obligation. cause ,
1626
+ obligation. param_env ,
1622
1627
is_normalized_ty_expected,
1623
1628
normalized_ty,
1624
- data . term ,
1629
+ expected_ty ,
1625
1630
) {
1626
- values = Some ( ( data, is_normalized_ty_expected, normalized_ty, data . term ) ) ;
1631
+ values = Some ( ( data, is_normalized_ty_expected, normalized_ty, expected_ty ) ) ;
1627
1632
err = new_err;
1628
1633
}
1629
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