@@ -1576,9 +1576,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
15761576 return ;
15771577 }
15781578
1579+ let mut values = None ;
1580+
15791581 self . probe ( |_| {
1582+ let ocx = ObligationCtxt :: new_in_snapshot ( self ) ;
15801583 let mut err = error. err ;
1581- let mut values = None ;
15821584
15831585 // try to find the mismatched types to report the error with.
15841586 //
@@ -1588,21 +1590,16 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
15881590 if let ty:: PredicateKind :: Clause ( ty:: Clause :: Projection ( data) ) =
15891591 bound_predicate. skip_binder ( )
15901592 {
1591- let mut selcx = SelectionContext :: new ( self ) ;
15921593 let data = self . replace_bound_vars_with_fresh_vars (
15931594 obligation. cause . span ,
15941595 infer:: LateBoundRegionConversionTime :: HigherRankedType ,
15951596 bound_predicate. rebind ( data) ,
15961597 ) ;
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 ,
16011600 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 ) ,
16061603 ) ;
16071604
16081605 debug ! ( ?obligation. cause, ?obligation. param_env) ;
@@ -1618,19 +1615,31 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
16181615 | ObligationCauseCode :: ObjectCastObligation ( ..)
16191616 | ObligationCauseCode :: OpaqueType
16201617 ) ;
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 ,
16221627 is_normalized_ty_expected,
16231628 normalized_ty,
1624- data . term ,
1629+ expected_ty ,
16251630 ) {
1626- values = Some ( ( data, is_normalized_ty_expected, normalized_ty, data . term ) ) ;
1631+ values = Some ( ( data, is_normalized_ty_expected, normalized_ty, expected_ty ) ) ;
16271632 err = new_err;
16281633 }
16291634 }
16301635
16311636 let msg = values
16321637 . 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+ )
16341643 } )
16351644 . unwrap_or_else ( || format ! ( "type mismatch resolving `{}`" , predicate) ) ;
16361645 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> {
16721681 & mut diag,
16731682 & obligation. cause ,
16741683 secondary_span,
1675- values. map ( |( _, is_normalized_ty_expected, normalized_ty, term ) | {
1684+ values. map ( |( _, is_normalized_ty_expected, normalized_ty, expected_ty ) | {
16761685 infer:: ValuePairs :: Terms ( ExpectedFound :: new (
16771686 is_normalized_ty_expected,
1678- normalized_ty,
1679- term ,
1687+ normalized_ty. into ( ) ,
1688+ expected_ty . into ( ) ,
16801689 ) )
16811690 } ) ,
16821691 err,
0 commit comments