@@ -33,21 +33,21 @@ 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 ,
42- TypeVisitableExt , TypingMode , Upcast , fold_regions,
41+ self , Const , GenericArgKind , GenericArgsRef , GenericParamDefKind , Ty , TyCtxt , TypeVisitableExt ,
42+ TypingMode , Upcast , fold_regions,
4343} ;
4444use rustc_middle:: { bug, span_bug} ;
4545use rustc_session:: lint:: builtin:: AMBIGUOUS_ASSOCIATED_ITEMS ;
4646use 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. clone ( ) ) ;
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