@@ -1577,32 +1577,26 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
15771577 }
15781578
15791579 self . probe ( |_| {
1580- let mut err = error. err ;
1581- let mut values = None ;
1580+ let ocx = ObligationCtxt :: new_in_snapshot ( self ) ;
15821581
15831582 // try to find the mismatched types to report the error with.
15841583 //
15851584 // this can fail if the problem was higher-ranked, in which
15861585 // cause I have no idea for a good error message.
15871586 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) ) =
15891588 bound_predicate. skip_binder ( )
15901589 {
1591- let mut selcx = SelectionContext :: new ( self ) ;
15921590 let data = self . replace_bound_vars_with_fresh_vars (
15931591 obligation. cause . span ,
15941592 infer:: LateBoundRegionConversionTime :: HigherRankedType ,
15951593 bound_predicate. rebind ( data) ,
15961594 ) ;
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 ,
16011597 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 ) ,
16061600 ) ;
16071601
16081602 debug ! ( ?obligation. cause, ?obligation. param_env) ;
@@ -1618,19 +1612,34 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
16181612 | ObligationCauseCode :: ObjectCastObligation ( ..)
16191613 | ObligationCauseCode :: OpaqueType
16201614 ) ;
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 ,
16221624 is_normalized_ty_expected,
16231625 normalized_ty,
1624- data . term ,
1626+ expected_ty ,
16251627 ) {
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 )
16281631 }
1629- }
1632+ } else {
1633+ ( None , error. err )
1634+ } ;
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