@@ -1586,60 +1586,113 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
15861586        } 
15871587
15881588        self . probe ( |_| { 
1589-             let  ocx = ObligationCtxt :: new ( self ) ; 
1590- 
15911589            // try to find the mismatched types to report the error with. 
15921590            // 
15931591            // this can fail if the problem was higher-ranked, in which 
15941592            // cause I have no idea for a good error message. 
15951593            let  bound_predicate = predicate. kind ( ) ; 
1596-             let  ( values,  err)  = if  let  ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Projection ( data) )  =
1597-                 bound_predicate. skip_binder ( ) 
1598-             { 
1599-                 let  data = self . instantiate_binder_with_fresh_vars ( 
1600-                     obligation. cause . span , 
1601-                     infer:: BoundRegionConversionTime :: HigherRankedType , 
1602-                     bound_predicate. rebind ( data) , 
1603-                 ) ; 
1604-                 let  unnormalized_term = data. projection_term . to_term ( self . tcx ) ; 
1605-                 // FIXME(-Znext-solver): For diagnostic purposes, it would be nice 
1606-                 // to deeply normalize this type. 
1607-                 let  normalized_term =
1608-                     ocx. normalize ( & obligation. cause ,  obligation. param_env ,  unnormalized_term) ; 
1609- 
1610-                 debug ! ( ?obligation. cause,  ?obligation. param_env) ; 
1611- 
1612-                 debug ! ( ?normalized_term,  data. ty = ?data. term) ; 
1594+             let  ( values,  err)  = match  bound_predicate. skip_binder ( )  { 
1595+                 ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Projection ( data) )  => { 
1596+                     let  ocx = ObligationCtxt :: new ( self ) ; 
1597+ 
1598+                     let  data = self . instantiate_binder_with_fresh_vars ( 
1599+                         obligation. cause . span , 
1600+                         infer:: BoundRegionConversionTime :: HigherRankedType , 
1601+                         bound_predicate. rebind ( data) , 
1602+                     ) ; 
1603+                     let  unnormalized_term = data. projection_term . to_term ( self . tcx ) ; 
1604+                     // FIXME(-Znext-solver): For diagnostic purposes, it would be nice 
1605+                     // to deeply normalize this type. 
1606+                     let  normalized_term =
1607+                         ocx. normalize ( & obligation. cause ,  obligation. param_env ,  unnormalized_term) ; 
1608+ 
1609+                     let  is_normalized_term_expected = !matches ! ( 
1610+                         obligation. cause. code( ) . peel_derives( ) , 
1611+                         ObligationCauseCode :: WhereClause ( ..) 
1612+                             | ObligationCauseCode :: WhereClauseInExpr ( ..) 
1613+                             | ObligationCauseCode :: Coercion  {  .. } 
1614+                     ) ; 
16131615
1614-                 let  is_normalized_term_expected = !matches ! ( 
1615-                     obligation. cause. code( ) . peel_derives( ) , 
1616-                     |ObligationCauseCode :: WhereClause ( ..) | ObligationCauseCode :: WhereClauseInExpr ( 
1617-                         ..
1618-                     )  | ObligationCauseCode :: Coercion  {  .. } 
1619-                 ) ; 
1616+                     let  ( expected,  actual)  = if  is_normalized_term_expected { 
1617+                         ( normalized_term,  data. term ) 
1618+                     }  else  { 
1619+                         ( data. term ,  normalized_term) 
1620+                     } ; 
16201621
1621-                 let  ( expected,  actual)  = if  is_normalized_term_expected { 
1622-                     ( normalized_term,  data. term ) 
1623-                 }  else  { 
1624-                     ( data. term ,  normalized_term) 
1625-                 } ; 
1622+                     // constrain inference variables a bit more to nested obligations from normalize so 
1623+                     // we can have more helpful errors. 
1624+                     // 
1625+                     // we intentionally drop errors from normalization here, 
1626+                     // since the normalization is just done to improve the error message. 
1627+                     let  _ = ocx. select_where_possible ( ) ; 
16261628
1627-                 // constrain inference variables a bit more to nested obligations from normalize so 
1628-                 // we can have more helpful errors. 
1629-                 // 
1630-                 // we intentionally drop errors from normalization here, 
1631-                 // since the normalization is just done to improve the error message. 
1632-                 let  _ = ocx. select_where_possible ( ) ; 
1629+                     if  let  Err ( new_err)  =
1630+                         ocx. eq ( & obligation. cause ,  obligation. param_env ,  expected,  actual) 
1631+                     { 
1632+                         ( 
1633+                             Some ( ( 
1634+                                 data. projection_term , 
1635+                                 is_normalized_term_expected, 
1636+                                 self . resolve_vars_if_possible ( normalized_term) , 
1637+                                 data. term , 
1638+                             ) ) , 
1639+                             new_err, 
1640+                         ) 
1641+                     }  else  { 
1642+                         ( None ,  error. err ) 
1643+                     } 
1644+                 } 
1645+                 ty:: PredicateKind :: AliasRelate ( lhs,  rhs,  _)  => { 
1646+                     let  derive_better_type_error =
1647+                         |alias_term :  ty:: AliasTerm < ' tcx > ,  expected_term :  ty:: Term < ' tcx > | { 
1648+                             let  ocx = ObligationCtxt :: new ( self ) ; 
1649+                             let  normalized_term = match  expected_term. unpack ( )  { 
1650+                                 ty:: TermKind :: Ty ( _)  => self . next_ty_var ( DUMMY_SP ) . into ( ) , 
1651+                                 ty:: TermKind :: Const ( _)  => self . next_const_var ( DUMMY_SP ) . into ( ) , 
1652+                             } ; 
1653+                             ocx. register_obligation ( Obligation :: new ( 
1654+                                 self . tcx , 
1655+                                 ObligationCause :: dummy ( ) , 
1656+                                 obligation. param_env , 
1657+                                 ty:: PredicateKind :: NormalizesTo ( ty:: NormalizesTo  { 
1658+                                     alias :  alias_term, 
1659+                                     term :  normalized_term, 
1660+                                 } ) , 
1661+                             ) ) ; 
1662+                             let  _ = ocx. select_where_possible ( ) ; 
1663+                             if  let  Err ( terr)  = ocx. eq ( 
1664+                                 & ObligationCause :: dummy ( ) , 
1665+                                 obligation. param_env , 
1666+                                 expected_term, 
1667+                                 normalized_term, 
1668+                             )  { 
1669+                                 Some ( ( terr,  self . resolve_vars_if_possible ( normalized_term) ) ) 
1670+                             }  else  { 
1671+                                 None 
1672+                             } 
1673+                         } ; 
16331674
1634-                 if  let  Err ( new_err)  =
1635-                     ocx. eq ( & obligation. cause ,  obligation. param_env ,  expected,  actual) 
1636-                 { 
1637-                     ( Some ( ( data,  is_normalized_term_expected,  normalized_term,  data. term ) ) ,  new_err) 
1638-                 }  else  { 
1639-                     ( None ,  error. err ) 
1675+                     if  let  Some ( lhs)  = lhs. to_alias_term ( ) 
1676+                         && let  Some ( ( better_type_err,  expected_term) )  =
1677+                             derive_better_type_error ( lhs,  rhs) 
1678+                     { 
1679+                         ( 
1680+                             Some ( ( lhs,  true ,  self . resolve_vars_if_possible ( expected_term) ,  rhs) ) , 
1681+                             better_type_err, 
1682+                         ) 
1683+                     }  else  if  let  Some ( rhs)  = rhs. to_alias_term ( ) 
1684+                         && let  Some ( ( better_type_err,  expected_term) )  =
1685+                             derive_better_type_error ( rhs,  lhs) 
1686+                     { 
1687+                         ( 
1688+                             Some ( ( rhs,  true ,  self . resolve_vars_if_possible ( expected_term) ,  lhs) ) , 
1689+                             better_type_err, 
1690+                         ) 
1691+                     }  else  { 
1692+                         ( None ,  error. err ) 
1693+                     } 
16401694                } 
1641-             }  else  { 
1642-                 ( None ,  error. err ) 
1695+                 _ => ( None ,  error. err ) , 
16431696            } ; 
16441697
16451698            let  msg = values
@@ -1737,15 +1790,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
17371790
17381791    fn  maybe_detailed_projection_msg ( 
17391792        & self , 
1740-         pred :  ty:: ProjectionPredicate < ' tcx > , 
1793+         projection_term :  ty:: AliasTerm < ' tcx > , 
17411794        normalized_ty :  ty:: Term < ' tcx > , 
17421795        expected_ty :  ty:: Term < ' tcx > , 
17431796    )  -> Option < String >  { 
1744-         let  trait_def_id = pred . projection_term . trait_def_id ( self . tcx ) ; 
1745-         let  self_ty = pred . projection_term . self_ty ( ) ; 
1797+         let  trait_def_id = projection_term. trait_def_id ( self . tcx ) ; 
1798+         let  self_ty = projection_term. self_ty ( ) ; 
17461799
17471800        with_forced_trimmed_paths !  { 
1748-             if  self . tcx. is_lang_item( pred . projection_term. def_id, LangItem :: FnOnceOutput )  { 
1801+             if  self . tcx. is_lang_item( projection_term. def_id,   LangItem :: FnOnceOutput )  { 
17491802                let  fn_kind = self_ty. prefix_string( self . tcx) ; 
17501803                let  item = match  self_ty. kind( )  { 
17511804                    ty:: FnDef ( def,  _)  => self . tcx. item_name( * def) . to_string( ) , 
0 commit comments