@@ -31,7 +31,8 @@ use rustc_infer::traits::ObligationCause;
31
31
use rustc_middle:: middle:: stability:: AllowUnstable ;
32
32
use rustc_middle:: ty:: GenericParamDefKind ;
33
33
use rustc_middle:: ty:: {
34
- self , Const , GenericArgKind , GenericArgsRef , IsSuggestable , Ty , TyCtxt , TypeVisitableExt ,
34
+ self , Const , GenericArgKind , GenericArgsRef , IsSuggestable , ParamEnv , Ty , TyCtxt ,
35
+ TypeVisitableExt ,
35
36
} ;
36
37
use rustc_session:: lint:: builtin:: AMBIGUOUS_ASSOCIATED_ITEMS ;
37
38
use rustc_span:: edit_distance:: find_best_match_for_name;
@@ -1607,7 +1608,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1607
1608
let param_env = tcx. param_env ( block. owner ) ;
1608
1609
let cause = ObligationCause :: misc ( span, block. owner . def_id ) ;
1609
1610
1610
- let mut fulfillment_errors = Vec :: new ( ) ;
1611
1611
infcx. probe ( |_| {
1612
1612
let mut universes = if self_ty. has_escaping_bound_vars ( ) {
1613
1613
vec ! [ None ; self_ty. outer_exclusive_binder( ) . as_usize( ) ]
@@ -1620,99 +1620,102 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1620
1620
& mut universes,
1621
1621
self_ty,
1622
1622
|self_ty| {
1623
- let InferOk { value : self_ty, obligations } =
1624
- infcx. at ( & cause, param_env) . normalize ( self_ty) ;
1623
+ self . find_candidate (
1624
+ infcx, self_ty, name, segment, block, span, cause, param_env, candidates,
1625
+ )
1626
+ } ,
1627
+ )
1628
+ } )
1629
+ }
1625
1630
1626
- let mut applicable_candidates: Vec < _ > = candidates
1627
- . iter ( )
1628
- . copied ( )
1629
- . filter ( |& ( impl_, _) | {
1630
- infcx. probe ( |_| {
1631
- let ocx = ObligationCtxt :: new ( & infcx) ;
1632
- ocx. register_obligations ( obligations. clone ( ) ) ;
1633
-
1634
- let impl_args = infcx. fresh_args_for_item ( span, impl_) ;
1635
- let impl_ty = tcx. type_of ( impl_) . instantiate ( tcx, impl_args) ;
1636
- let impl_ty = ocx. normalize ( & cause, param_env, impl_ty) ;
1637
-
1638
- // Check that the self types can be related.
1639
- if ocx
1640
- . eq ( & ObligationCause :: dummy ( ) , param_env, impl_ty, self_ty)
1641
- . is_err ( )
1642
- {
1643
- return false ;
1644
- }
1631
+ fn find_candidate (
1632
+ & self ,
1633
+ infcx : & InferCtxt < ' tcx > ,
1634
+ self_ty : Ty < ' tcx > ,
1635
+ name : Ident ,
1636
+ segment : & hir:: PathSegment < ' _ > ,
1637
+ block : hir:: HirId ,
1638
+ span : Span ,
1639
+ cause : ObligationCause < ' tcx > ,
1640
+ param_env : ParamEnv < ' tcx > ,
1641
+ candidates : Vec < ( DefId , ( DefId , DefId ) ) > ,
1642
+ ) -> Result < Option < ( Ty < ' tcx > , DefId ) > , ErrorGuaranteed > {
1643
+ let mut fulfillment_errors = Vec :: new ( ) ;
1644
+ let tcx = self . tcx ( ) ;
1645
+ let InferOk { value : self_ty, obligations } =
1646
+ infcx. at ( & cause, param_env) . normalize ( self_ty) ;
1645
1647
1646
- // Check whether the impl imposes obligations we have to worry about.
1647
- let impl_bounds =
1648
- tcx. predicates_of ( impl_) . instantiate ( tcx, impl_args) ;
1649
- let impl_bounds = ocx. normalize ( & cause, param_env, impl_bounds) ;
1650
- let impl_obligations = traits:: predicates_for_generics (
1651
- |_, _| cause. clone ( ) ,
1652
- param_env,
1653
- impl_bounds,
1654
- ) ;
1655
- ocx. register_obligations ( impl_obligations) ;
1648
+ let mut applicable_candidates: Vec < _ > = candidates
1649
+ . iter ( )
1650
+ . copied ( )
1651
+ . filter ( |& ( impl_, _) | {
1652
+ infcx. probe ( |_| {
1653
+ let ocx = ObligationCtxt :: new ( & infcx) ;
1654
+ ocx. register_obligations ( obligations. clone ( ) ) ;
1655
+
1656
+ let impl_args = infcx. fresh_args_for_item ( span, impl_) ;
1657
+ let impl_ty = tcx. type_of ( impl_) . instantiate ( tcx, impl_args) ;
1658
+ let impl_ty = ocx. normalize ( & cause, param_env, impl_ty) ;
1659
+
1660
+ // Check that the self types can be related.
1661
+ if ocx. eq ( & ObligationCause :: dummy ( ) , param_env, impl_ty, self_ty) . is_err ( ) {
1662
+ return false ;
1663
+ }
1656
1664
1657
- let mut errors = ocx. select_where_possible ( ) ;
1658
- if !errors. is_empty ( ) {
1659
- fulfillment_errors. append ( & mut errors) ;
1660
- return false ;
1661
- }
1665
+ // Check whether the impl imposes obligations we have to worry about.
1666
+ let impl_bounds = tcx. predicates_of ( impl_) . instantiate ( tcx, impl_args) ;
1667
+ let impl_bounds = ocx. normalize ( & cause, param_env, impl_bounds) ;
1668
+ let impl_obligations = traits:: predicates_for_generics (
1669
+ |_, _| cause. clone ( ) ,
1670
+ param_env,
1671
+ impl_bounds,
1672
+ ) ;
1673
+ ocx. register_obligations ( impl_obligations) ;
1662
1674
1663
- true
1664
- } )
1665
- } )
1666
- . collect ( ) ;
1667
-
1668
- if applicable_candidates. len ( ) > 1 {
1669
- return Err ( self . complain_about_ambiguous_inherent_assoc_type (
1670
- name,
1671
- applicable_candidates
1672
- . into_iter ( )
1673
- . map ( |( _, ( candidate, _) ) | candidate)
1674
- . collect ( ) ,
1675
- span,
1676
- ) ) ;
1675
+ let mut errors = ocx. select_where_possible ( ) ;
1676
+ if !errors. is_empty ( ) {
1677
+ fulfillment_errors. append ( & mut errors) ;
1678
+ return false ;
1677
1679
}
1678
1680
1679
- if let Some ( ( impl_, ( assoc_item, def_scope) ) ) = applicable_candidates. pop ( ) {
1680
- self . check_assoc_ty ( assoc_item, name, def_scope, block, span) ;
1681
-
1682
- // FIXME(fmease): Currently creating throwaway `parent_args` to please
1683
- // `create_args_for_associated_item`. Modify the latter instead (or sth. similar) to
1684
- // not require the parent args logic.
1685
- let parent_args = ty:: GenericArgs :: identity_for_item ( tcx, impl_) ;
1686
- let args = self . create_args_for_associated_item (
1687
- span,
1688
- assoc_item,
1689
- segment,
1690
- parent_args,
1691
- ) ;
1692
- let args = tcx. mk_args_from_iter (
1693
- std:: iter:: once ( ty:: GenericArg :: from ( self_ty) )
1694
- . chain ( args. into_iter ( ) . skip ( parent_args. len ( ) ) ) ,
1695
- ) ;
1681
+ true
1682
+ } )
1683
+ } )
1684
+ . collect ( ) ;
1696
1685
1697
- let ty = Ty :: new_alias (
1698
- tcx,
1699
- ty:: Inherent ,
1700
- ty:: AliasTy :: new ( tcx, assoc_item, args) ,
1701
- ) ;
1686
+ if applicable_candidates. len ( ) > 1 {
1687
+ return Err ( self . complain_about_ambiguous_inherent_assoc_type (
1688
+ name,
1689
+ applicable_candidates. into_iter ( ) . map ( |( _, ( candidate, _) ) | candidate) . collect ( ) ,
1690
+ span,
1691
+ ) ) ;
1692
+ }
1702
1693
1703
- return Ok ( Some ( ( ty, assoc_item) ) ) ;
1704
- }
1694
+ if let Some ( ( impl_, ( assoc_item, def_scope) ) ) = applicable_candidates. pop ( ) {
1695
+ self . check_assoc_ty ( assoc_item, name, def_scope, block, span) ;
1696
+
1697
+ // FIXME(fmease): Currently creating throwaway `parent_args` to please
1698
+ // `create_args_for_associated_item`. Modify the latter instead (or sth. similar) to
1699
+ // not require the parent args logic.
1700
+ let parent_args = ty:: GenericArgs :: identity_for_item ( tcx, impl_) ;
1701
+ let args = self . create_args_for_associated_item ( span, assoc_item, segment, parent_args) ;
1702
+ let args = tcx. mk_args_from_iter (
1703
+ std:: iter:: once ( ty:: GenericArg :: from ( self_ty) )
1704
+ . chain ( args. into_iter ( ) . skip ( parent_args. len ( ) ) ) ,
1705
+ ) ;
1705
1706
1706
- Err ( self . complain_about_inherent_assoc_type_not_found (
1707
- name,
1708
- self_ty,
1709
- candidates,
1710
- fulfillment_errors,
1711
- span,
1712
- ) )
1713
- } ,
1714
- )
1715
- } )
1707
+ let ty = Ty :: new_alias ( tcx, ty:: Inherent , ty:: AliasTy :: new ( tcx, assoc_item, args) ) ;
1708
+
1709
+ return Ok ( Some ( ( ty, assoc_item) ) ) ;
1710
+ }
1711
+
1712
+ Err ( self . complain_about_inherent_assoc_type_not_found (
1713
+ name,
1714
+ self_ty,
1715
+ candidates,
1716
+ fulfillment_errors,
1717
+ span,
1718
+ ) )
1716
1719
}
1717
1720
1718
1721
fn lookup_assoc_ty (
0 commit comments