@@ -33,12 +33,12 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
3333use  rustc_hir:: def_id:: { DefId ,  LocalDefId } ; 
3434use  rustc_hir:: { self  as  hir,  AnonConst ,  GenericArg ,  GenericArgs ,  HirId } ; 
3535use  rustc_infer:: infer:: { InferCtxt ,  TyCtxtInferExt } ; 
36- use  rustc_infer :: traits :: ObligationCause ; 
36+ use  rustc_macros :: { TypeFoldable ,   TypeVisitable } ; 
3737use  rustc_middle:: middle:: stability:: AllowUnstable ; 
3838use  rustc_middle:: mir:: interpret:: LitToConstInput ; 
3939use  rustc_middle:: ty:: print:: PrintPolyTraitRefExt  as  _; 
4040use  rustc_middle:: ty:: { 
41-     self ,  Const ,  GenericArgKind ,  GenericArgsRef ,  GenericParamDefKind ,  ParamEnv ,   Ty ,  TyCtxt , 
41+     self ,  Const ,  GenericArgKind ,  GenericArgsRef ,  GenericParamDefKind ,  Ty ,  TyCtxt , 
4242    TypeVisitableExt ,  TypingMode ,  Upcast ,  fold_regions, 
4343} ; 
4444use  rustc_middle:: { bug,  span_bug} ; 
@@ -47,7 +47,7 @@ use rustc_session::parse::feature_err;
4747use  rustc_span:: { DUMMY_SP ,  Ident ,  Span ,  kw,  sym} ; 
4848use  rustc_trait_selection:: infer:: InferCtxtExt ; 
4949use  rustc_trait_selection:: traits:: wf:: object_region_bounds; 
50- use  rustc_trait_selection:: traits:: { self ,  ObligationCtxt } ; 
50+ use  rustc_trait_selection:: traits:: { self ,  FulfillmentError } ; 
5151use  tracing:: { debug,  instrument} ; 
5252
5353use  crate :: check:: check_abi_fn_ptr; 
@@ -99,6 +99,13 @@ pub enum RegionInferReason<'a> {
9999    OutlivesBound , 
100100} 
101101
102+ #[ derive( Copy ,  Clone ,  TypeFoldable ,  TypeVisitable ,  Debug ) ]  
103+ pub  struct  InherentAssocCandidate  { 
104+     pub  impl_ :  DefId , 
105+     pub  assoc_item :  DefId , 
106+     pub  scope :  DefId , 
107+ } 
108+ 
102109/// A context which can lower type-system entities from the [HIR][hir] to 
103110/// the [`rustc_middle::ty`] representation. 
104111/// 
@@ -148,6 +155,13 @@ pub trait HirTyLowerer<'tcx> {
148155        assoc_ident :  Ident , 
149156    )  -> ty:: EarlyBinder < ' tcx ,  & ' tcx  [ ( ty:: Clause < ' tcx > ,  Span ) ] > ; 
150157
158+     fn  select_inherent_assoc_candidates ( 
159+         & self , 
160+         span :  Span , 
161+         self_ty :  Ty < ' tcx > , 
162+         candidates :  & Vec < InherentAssocCandidate > , 
163+     )  -> ( Vec < InherentAssocCandidate > ,  Vec < FulfillmentError < ' tcx > > ) ; 
164+ 
151165    /// Lower a path to an associated item (of a trait) to a projection. 
152166     /// 
153167     /// This method has to be defined by the concrete lowering context because 
@@ -1441,48 +1455,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
14411455            . filter_map ( |& impl_| { 
14421456                let  ( item,  scope)  =
14431457                    self . probe_assoc_item_unchecked ( name,  assoc_tag,  block,  impl_) ?; 
1444-                 Some ( ( impl_,  ( item. def_id ,  scope) ) ) 
1458+                 Some ( InherentAssocCandidate   {   impl_,  assoc_item :   item. def_id ,  scope  } ) 
14451459            } ) 
14461460            . collect ( ) ; 
14471461
1448-         if  candidates. is_empty ( )  { 
1449-             return  Ok ( None ) ; 
1450-         } 
1451- 
1452-         // 
1453-         // Select applicable inherent associated type candidates modulo regions. 
1454-         // 
1455- 
1456-         // In contexts that have no inference context, just make a new one. 
1457-         // We do need a local variable to store it, though. 
1458-         let  infcx = match  self . infcx ( )  { 
1459-             Some ( infcx)  => infcx, 
1460-             None  => { 
1461-                 assert ! ( !self_ty. has_infer( ) ) ; 
1462-                 & tcx. infer_ctxt ( ) . ignoring_regions ( ) . build ( TypingMode :: non_body_analysis ( ) ) 
1463-             } 
1464-         } ; 
1462+         let  ( applicable_candidates,  fulfillment_errors)  =
1463+             self . select_inherent_assoc_candidates ( span,  self_ty,  & candidates) ; 
14651464
1466-         // FIXME(inherent_associated_types): Acquiring the ParamEnv this early leads to cycle errors 
1467-         // when inside of an ADT (#108491) or where clause. 
1468-         let  param_env = tcx. param_env ( block. owner ) ; 
1465+         let  InherentAssocCandidate  {  impl_,  assoc_item,  scope :  def_scope }  =
1466+             match  & applicable_candidates[ ..]  { 
1467+                 & [ ]  => Err ( self . report_unresolved_inherent_assoc_item ( 
1468+                     name, 
1469+                     self_ty, 
1470+                     candidates, 
1471+                     fulfillment_errors, 
1472+                     span, 
1473+                     assoc_tag, 
1474+                 ) ) , 
14691475
1470-         let  mut  universes = if  self_ty. has_escaping_bound_vars ( )  { 
1471-             vec ! [ None ;  self_ty. outer_exclusive_binder( ) . as_usize( ) ] 
1472-         }  else  { 
1473-             vec ! [ ] 
1474-         } ; 
1476+                 & [ applicable_candidate]  => Ok ( applicable_candidate) , 
14751477
1476-         let  ( impl_,  ( assoc_item,  def_scope) )  = crate :: traits:: with_replaced_escaping_bound_vars ( 
1477-             infcx, 
1478-             & mut  universes, 
1479-             self_ty, 
1480-             |self_ty| { 
1481-                 self . select_inherent_assoc_candidates ( 
1482-                     infcx,  name,  span,  self_ty,  param_env,  candidates,  assoc_tag, 
1483-                 ) 
1484-             } , 
1485-         ) ?; 
1478+                 & [ _,  ..]  => Err ( self . report_ambiguous_inherent_assoc_item ( 
1479+                     name, 
1480+                     candidates. into_iter ( ) . map ( |cand| cand. assoc_item ) . collect ( ) , 
1481+                     span, 
1482+                 ) ) , 
1483+             } ?; 
14861484
14871485        self . check_assoc_item ( assoc_item,  name,  def_scope,  block,  span) ; 
14881486
@@ -1499,78 +1497,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
14991497        Ok ( Some ( ( assoc_item,  args) ) ) 
15001498    } 
15011499
1502-     fn  select_inherent_assoc_candidates ( 
1503-         & self , 
1504-         infcx :  & InferCtxt < ' tcx > , 
1505-         name :  Ident , 
1506-         span :  Span , 
1507-         self_ty :  Ty < ' tcx > , 
1508-         param_env :  ParamEnv < ' tcx > , 
1509-         candidates :  Vec < ( DefId ,  ( DefId ,  DefId ) ) > , 
1510-         assoc_tag :  ty:: AssocTag , 
1511-     )  -> Result < ( DefId ,  ( DefId ,  DefId ) ) ,  ErrorGuaranteed >  { 
1512-         let  tcx = self . tcx ( ) ; 
1513-         let  mut  fulfillment_errors = Vec :: new ( ) ; 
1514- 
1515-         let  applicable_candidates:  Vec < _ >  = candidates
1516-             . iter ( ) 
1517-             . copied ( ) 
1518-             . filter ( |& ( impl_,  _) | { 
1519-                 infcx. probe ( |_| { 
1520-                     let  ocx = ObligationCtxt :: new_with_diagnostics ( infcx) ; 
1521-                     let  self_ty = ocx. normalize ( & ObligationCause :: dummy ( ) ,  param_env,  self_ty) ; 
1522- 
1523-                     let  impl_args = infcx. fresh_args_for_item ( span,  impl_) ; 
1524-                     let  impl_ty = tcx. type_of ( impl_) . instantiate ( tcx,  impl_args) ; 
1525-                     let  impl_ty = ocx. normalize ( & ObligationCause :: dummy ( ) ,  param_env,  impl_ty) ; 
1526- 
1527-                     // Check that the self types can be related. 
1528-                     if  ocx. eq ( & ObligationCause :: dummy ( ) ,  param_env,  impl_ty,  self_ty) . is_err ( )  { 
1529-                         return  false ; 
1530-                     } 
1531- 
1532-                     // Check whether the impl imposes obligations we have to worry about. 
1533-                     let  impl_bounds = tcx. predicates_of ( impl_) . instantiate ( tcx,  impl_args) ; 
1534-                     let  impl_bounds =
1535-                         ocx. normalize ( & ObligationCause :: dummy ( ) ,  param_env,  impl_bounds) ; 
1536-                     let  impl_obligations = traits:: predicates_for_generics ( 
1537-                         |_,  _| ObligationCause :: dummy ( ) , 
1538-                         param_env, 
1539-                         impl_bounds, 
1540-                     ) ; 
1541-                     ocx. register_obligations ( impl_obligations) ; 
1542- 
1543-                     let  mut  errors = ocx. select_where_possible ( ) ; 
1544-                     if  !errors. is_empty ( )  { 
1545-                         fulfillment_errors. append ( & mut  errors) ; 
1546-                         return  false ; 
1547-                     } 
1548- 
1549-                     true 
1550-                 } ) 
1551-             } ) 
1552-             . collect ( ) ; 
1553- 
1554-         match  & applicable_candidates[ ..]  { 
1555-             & [ ]  => Err ( self . report_unresolved_inherent_assoc_item ( 
1556-                 name, 
1557-                 self_ty, 
1558-                 candidates, 
1559-                 fulfillment_errors, 
1560-                 span, 
1561-                 assoc_tag, 
1562-             ) ) , 
1563- 
1564-             & [ applicable_candidate]  => Ok ( applicable_candidate) , 
1565- 
1566-             & [ _,  ..]  => Err ( self . report_ambiguous_inherent_assoc_item ( 
1567-                 name, 
1568-                 applicable_candidates. into_iter ( ) . map ( |( _,  ( candidate,  _) ) | candidate) . collect ( ) , 
1569-                 span, 
1570-             ) ) , 
1571-         } 
1572-     } 
1573- 
15741500    /// Given name and kind search for the assoc item in the provided scope and check if it's accessible[^1]. 
15751501     /// 
15761502     /// [^1]: I.e., accessible in the provided scope wrt. visibility and stability. 
0 commit comments