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