@@ -31,7 +31,8 @@ use rustc_infer::traits::ObligationCause;
3131use rustc_middle:: middle:: stability:: AllowUnstable ;
3232use rustc_middle:: ty:: GenericParamDefKind ;
3333use rustc_middle:: ty:: {
34- self , Const , GenericArgKind , GenericArgsRef , IsSuggestable , Ty , TyCtxt , TypeVisitableExt ,
34+ self , Const , GenericArgKind , GenericArgsRef , IsSuggestable , ParamEnv , Ty , TyCtxt ,
35+ TypeVisitableExt ,
3536} ;
3637use rustc_session:: lint:: builtin:: AMBIGUOUS_ASSOCIATED_ITEMS ;
3738use rustc_span:: edit_distance:: find_best_match_for_name;
@@ -1607,7 +1608,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16071608 let param_env = tcx. param_env ( block. owner ) ;
16081609 let cause = ObligationCause :: misc ( span, block. owner . def_id ) ;
16091610
1610- let mut fulfillment_errors = Vec :: new ( ) ;
16111611 infcx. probe ( |_| {
16121612 let mut universes = if self_ty. has_escaping_bound_vars ( ) {
16131613 vec ! [ None ; self_ty. outer_exclusive_binder( ) . as_usize( ) ]
@@ -1620,99 +1620,102 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16201620 & mut universes,
16211621 self_ty,
16221622 |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+ }
16251630
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) ;
16451647
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+ }
16561664
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) ;
16621674
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 ;
16771679 }
16781680
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 ( ) ;
16961685
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+ }
17021693
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+ ) ;
17051706
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+ ) )
17161719 }
17171720
17181721 fn lookup_assoc_ty (
0 commit comments