@@ -33,13 +33,13 @@ 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 , AssocTag , Const , GenericArgKind , GenericArgsRef , GenericParamDefKind , ParamEnv , Ty ,
42- TyCtxt , TypeVisitableExt , TypingMode , Upcast , fold_regions,
41+ self , AssocTag , Const , GenericArgKind , GenericArgsRef , GenericParamDefKind , Ty , TyCtxt ,
42+ TypeVisitableExt , TypingMode , Upcast , fold_regions,
4343} ;
4444use rustc_middle:: { bug, span_bug} ;
4545use rustc_session:: lint:: builtin:: AMBIGUOUS_ASSOCIATED_ITEMS ;
@@ -48,7 +48,7 @@ use rustc_span::edit_distance::find_best_match_for_name;
4848use rustc_span:: { DUMMY_SP , Ident , Span , Symbol , kw, sym} ;
4949use rustc_trait_selection:: infer:: InferCtxtExt ;
5050use rustc_trait_selection:: traits:: wf:: object_region_bounds;
51- use rustc_trait_selection:: traits:: { self , ObligationCtxt } ;
51+ use rustc_trait_selection:: traits:: { self , FulfillmentError } ;
5252use tracing:: { debug, instrument} ;
5353
5454use self :: errors:: assoc_tag_str;
@@ -101,6 +101,13 @@ pub enum RegionInferReason<'a> {
101101 OutlivesBound ,
102102}
103103
104+ #[ derive( Copy , Clone , TypeFoldable , TypeVisitable , Debug ) ]
105+ pub struct InherentAssocCandidate {
106+ pub impl_ : DefId ,
107+ pub assoc_item : DefId ,
108+ pub scope : DefId ,
109+ }
110+
104111/// A context which can lower type-system entities from the [HIR][hir] to
105112/// the [`rustc_middle::ty`] representation.
106113///
@@ -150,6 +157,13 @@ pub trait HirTyLowerer<'tcx> {
150157 assoc_ident : Ident ,
151158 ) -> ty:: EarlyBinder < ' tcx , & ' tcx [ ( ty:: Clause < ' tcx > , Span ) ] > ;
152159
160+ fn select_inherent_assoc_candidates (
161+ & self ,
162+ span : Span ,
163+ self_ty : Ty < ' tcx > ,
164+ candidates : & Vec < InherentAssocCandidate > ,
165+ ) -> ( Vec < InherentAssocCandidate > , Vec < FulfillmentError < ' tcx > > ) ;
166+
153167 /// Lower an associated type/const (from a trait) to a projection.
154168 ///
155169 /// This method has to be defined by the concrete lowering context because
@@ -1513,48 +1527,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
15131527 . filter_map ( |& impl_| {
15141528 let ( item, scope) =
15151529 self . probe_assoc_item_unchecked ( name, assoc_tag, block, impl_) ?;
1516- Some ( ( impl_, ( item. def_id , scope) ) )
1530+ Some ( InherentAssocCandidate { impl_, assoc_item : item. def_id , scope } )
15171531 } )
15181532 . collect ( ) ;
15191533
1520- if candidates. is_empty ( ) {
1521- return Ok ( None ) ;
1522- }
1523-
1524- //
1525- // Select applicable inherent associated type candidates modulo regions.
1526- //
1527-
1528- // In contexts that have no inference context, just make a new one.
1529- // We do need a local variable to store it, though.
1530- let infcx = match self . infcx ( ) {
1531- Some ( infcx) => infcx,
1532- None => {
1533- assert ! ( !self_ty. has_infer( ) ) ;
1534- & tcx. infer_ctxt ( ) . ignoring_regions ( ) . build ( TypingMode :: non_body_analysis ( ) )
1535- }
1536- } ;
1534+ let ( applicable_candidates, fulfillment_errors) =
1535+ self . select_inherent_assoc_candidates ( span, self_ty, & candidates) ;
15371536
1538- // FIXME(inherent_associated_types): Acquiring the ParamEnv this early leads to cycle errors
1539- // when inside of an ADT (#108491) or where clause.
1540- let param_env = tcx. param_env ( block. owner ) ;
1537+ let InherentAssocCandidate { impl_, assoc_item, scope : def_scope } =
1538+ match & applicable_candidates[ ..] {
1539+ & [ ] => Err ( self . complain_about_inherent_assoc_not_found (
1540+ name,
1541+ self_ty,
1542+ candidates,
1543+ fulfillment_errors,
1544+ span,
1545+ assoc_tag,
1546+ ) ) ,
15411547
1542- let mut universes = if self_ty. has_escaping_bound_vars ( ) {
1543- vec ! [ None ; self_ty. outer_exclusive_binder( ) . as_usize( ) ]
1544- } else {
1545- vec ! [ ]
1546- } ;
1548+ & [ applicable_candidate] => Ok ( applicable_candidate) ,
15471549
1548- let ( impl_, ( assoc_item, def_scope) ) = crate :: traits:: with_replaced_escaping_bound_vars (
1549- infcx,
1550- & mut universes,
1551- self_ty,
1552- |self_ty| {
1553- self . select_inherent_assoc_candidates (
1554- infcx, name, span, self_ty, param_env, candidates, assoc_tag,
1555- )
1556- } ,
1557- ) ?;
1550+ & [ _, ..] => Err ( self . complain_about_ambiguous_inherent_assoc (
1551+ name,
1552+ candidates. into_iter ( ) . map ( |cand| cand. assoc_item ) . collect ( ) ,
1553+ span,
1554+ ) ) ,
1555+ } ?;
15581556
15591557 self . check_assoc_item ( assoc_item, name, def_scope, block, span) ;
15601558
@@ -1571,78 +1569,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
15711569 Ok ( Some ( ( assoc_item, args) ) )
15721570 }
15731571
1574- fn select_inherent_assoc_candidates (
1575- & self ,
1576- infcx : & InferCtxt < ' tcx > ,
1577- name : Ident ,
1578- span : Span ,
1579- self_ty : Ty < ' tcx > ,
1580- param_env : ParamEnv < ' tcx > ,
1581- candidates : Vec < ( DefId , ( DefId , DefId ) ) > ,
1582- assoc_tag : ty:: AssocTag ,
1583- ) -> Result < ( DefId , ( DefId , DefId ) ) , ErrorGuaranteed > {
1584- let tcx = self . tcx ( ) ;
1585- let mut fulfillment_errors = Vec :: new ( ) ;
1586-
1587- let applicable_candidates: Vec < _ > = candidates
1588- . iter ( )
1589- . copied ( )
1590- . filter ( |& ( impl_, _) | {
1591- infcx. probe ( |_| {
1592- let ocx = ObligationCtxt :: new_with_diagnostics ( infcx) ;
1593- let self_ty = ocx. normalize ( & ObligationCause :: dummy ( ) , param_env, self_ty) ;
1594-
1595- let impl_args = infcx. fresh_args_for_item ( span, impl_) ;
1596- let impl_ty = tcx. type_of ( impl_) . instantiate ( tcx, impl_args) ;
1597- let impl_ty = ocx. normalize ( & ObligationCause :: dummy ( ) , param_env, impl_ty) ;
1598-
1599- // Check that the self types can be related.
1600- if ocx. eq ( & ObligationCause :: dummy ( ) , param_env, impl_ty, self_ty) . is_err ( ) {
1601- return false ;
1602- }
1603-
1604- // Check whether the impl imposes obligations we have to worry about.
1605- let impl_bounds = tcx. predicates_of ( impl_) . instantiate ( tcx, impl_args) ;
1606- let impl_bounds =
1607- ocx. normalize ( & ObligationCause :: dummy ( ) , param_env, impl_bounds) ;
1608- let impl_obligations = traits:: predicates_for_generics (
1609- |_, _| ObligationCause :: dummy ( ) ,
1610- param_env,
1611- impl_bounds,
1612- ) ;
1613- ocx. register_obligations ( impl_obligations) ;
1614-
1615- let mut errors = ocx. select_where_possible ( ) ;
1616- if !errors. is_empty ( ) {
1617- fulfillment_errors. append ( & mut errors) ;
1618- return false ;
1619- }
1620-
1621- true
1622- } )
1623- } )
1624- . collect ( ) ;
1625-
1626- match & applicable_candidates[ ..] {
1627- & [ ] => Err ( self . complain_about_inherent_assoc_not_found (
1628- name,
1629- self_ty,
1630- candidates,
1631- fulfillment_errors,
1632- span,
1633- assoc_tag,
1634- ) ) ,
1635-
1636- & [ applicable_candidate] => Ok ( applicable_candidate) ,
1637-
1638- & [ _, ..] => Err ( self . complain_about_ambiguous_inherent_assoc (
1639- name,
1640- applicable_candidates. into_iter ( ) . map ( |( _, ( candidate, _) ) | candidate) . collect ( ) ,
1641- span,
1642- ) ) ,
1643- }
1644- }
1645-
16461572 /// Given name and kind search for the assoc item in the provided scope and check if it's accessible[^1].
16471573 ///
16481574 /// [^1]: I.e., accessible in the provided scope wrt. visibility and stability.
0 commit comments