@@ -33,21 +33,22 @@ 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:: { DynCompatibilityViolation , ObligationCause } ;
36+ use rustc_infer:: traits:: DynCompatibilityViolation ;
37+ use rustc_macros:: { TypeFoldable , TypeVisitable } ;
3738use rustc_middle:: middle:: stability:: AllowUnstable ;
3839use rustc_middle:: mir:: interpret:: LitToConstInput ;
3940use rustc_middle:: ty:: print:: PrintPolyTraitRefExt as _;
4041use rustc_middle:: ty:: {
41- self , Const , GenericArgKind , GenericArgsRef , GenericParamDefKind , ParamEnv , Ty , TyCtxt ,
42- TypeVisitableExt , TypingMode , Upcast , fold_regions,
42+ self , Const , GenericArgKind , GenericArgsRef , GenericParamDefKind , Ty , TyCtxt , TypeVisitableExt ,
43+ TypingMode , Upcast , fold_regions,
4344} ;
4445use rustc_middle:: { bug, span_bug} ;
4546use rustc_session:: lint:: builtin:: AMBIGUOUS_ASSOCIATED_ITEMS ;
4647use rustc_session:: parse:: feature_err;
4748use rustc_span:: { DUMMY_SP , Ident , Span , kw, sym} ;
4849use rustc_trait_selection:: infer:: InferCtxtExt ;
4950use rustc_trait_selection:: traits:: wf:: object_region_bounds;
50- use rustc_trait_selection:: traits:: { self , ObligationCtxt } ;
51+ use rustc_trait_selection:: traits:: { self , FulfillmentError } ;
5152use tracing:: { debug, instrument} ;
5253
5354use crate :: check:: check_abi_fn_ptr;
@@ -99,6 +100,13 @@ pub enum RegionInferReason<'a> {
99100 OutlivesBound ,
100101}
101102
103+ #[ derive( Copy , Clone , TypeFoldable , TypeVisitable , Debug ) ]
104+ pub struct InherentAssocCandidate {
105+ pub impl_ : DefId ,
106+ pub assoc_item : DefId ,
107+ pub scope : DefId ,
108+ }
109+
102110/// A context which can lower type-system entities from the [HIR][hir] to
103111/// the [`rustc_middle::ty`] representation.
104112///
@@ -148,6 +156,13 @@ pub trait HirTyLowerer<'tcx> {
148156 assoc_ident : Ident ,
149157 ) -> ty:: EarlyBinder < ' tcx , & ' tcx [ ( ty:: Clause < ' tcx > , Span ) ] > ;
150158
159+ fn select_inherent_assoc_candidates (
160+ & self ,
161+ span : Span ,
162+ self_ty : Ty < ' tcx > ,
163+ candidates : Vec < InherentAssocCandidate > ,
164+ ) -> ( Vec < InherentAssocCandidate > , Vec < FulfillmentError < ' tcx > > ) ;
165+
151166 /// Lower a path to an associated item (of a trait) to a projection.
152167 ///
153168 /// This method has to be defined by the concrete lowering context because
@@ -1449,48 +1464,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
14491464 . filter_map ( |& impl_| {
14501465 let ( item, scope) =
14511466 self . probe_assoc_item_unchecked ( name, assoc_tag, block, impl_) ?;
1452- Some ( ( impl_, ( item. def_id , scope) ) )
1467+ Some ( InherentAssocCandidate { impl_, assoc_item : item. def_id , scope } )
14531468 } )
14541469 . collect ( ) ;
14551470
1456- if candidates. is_empty ( ) {
1457- return Ok ( None ) ;
1458- }
1459-
1460- //
1461- // Select applicable inherent associated type candidates modulo regions.
1462- //
1463-
1464- // In contexts that have no inference context, just make a new one.
1465- // We do need a local variable to store it, though.
1466- let infcx = match self . infcx ( ) {
1467- Some ( infcx) => infcx,
1468- None => {
1469- assert ! ( !self_ty. has_infer( ) ) ;
1470- & tcx. infer_ctxt ( ) . ignoring_regions ( ) . build ( TypingMode :: non_body_analysis ( ) )
1471- }
1472- } ;
1471+ let ( applicable_candidates, fulfillment_errors) =
1472+ self . select_inherent_assoc_candidates ( span, self_ty, candidates. clone ( ) ) ;
14731473
1474- // FIXME(inherent_associated_types): Acquiring the ParamEnv this early leads to cycle errors
1475- // when inside of an ADT (#108491) or where clause.
1476- let param_env = tcx. param_env ( block. owner ) ;
1474+ let InherentAssocCandidate { impl_, assoc_item, scope : def_scope } =
1475+ match & applicable_candidates[ ..] {
1476+ & [ ] => Err ( self . report_unresolved_inherent_assoc_item (
1477+ name,
1478+ self_ty,
1479+ candidates,
1480+ fulfillment_errors,
1481+ span,
1482+ assoc_tag,
1483+ ) ) ,
14771484
1478- let mut universes = if self_ty. has_escaping_bound_vars ( ) {
1479- vec ! [ None ; self_ty. outer_exclusive_binder( ) . as_usize( ) ]
1480- } else {
1481- vec ! [ ]
1482- } ;
1485+ & [ applicable_candidate] => Ok ( applicable_candidate) ,
14831486
1484- let ( impl_, ( assoc_item, def_scope) ) = crate :: traits:: with_replaced_escaping_bound_vars (
1485- infcx,
1486- & mut universes,
1487- self_ty,
1488- |self_ty| {
1489- self . select_inherent_assoc_candidates (
1490- infcx, name, span, self_ty, param_env, candidates, assoc_tag,
1491- )
1492- } ,
1493- ) ?;
1487+ & [ _, ..] => Err ( self . report_ambiguous_inherent_assoc_item (
1488+ name,
1489+ candidates. into_iter ( ) . map ( |cand| cand. assoc_item ) . collect ( ) ,
1490+ span,
1491+ ) ) ,
1492+ } ?;
14941493
14951494 self . check_assoc_item ( assoc_item, name, def_scope, block, span) ;
14961495
@@ -1507,78 +1506,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
15071506 Ok ( Some ( ( assoc_item, args) ) )
15081507 }
15091508
1510- fn select_inherent_assoc_candidates (
1511- & self ,
1512- infcx : & InferCtxt < ' tcx > ,
1513- name : Ident ,
1514- span : Span ,
1515- self_ty : Ty < ' tcx > ,
1516- param_env : ParamEnv < ' tcx > ,
1517- candidates : Vec < ( DefId , ( DefId , DefId ) ) > ,
1518- assoc_tag : ty:: AssocTag ,
1519- ) -> Result < ( DefId , ( DefId , DefId ) ) , ErrorGuaranteed > {
1520- let tcx = self . tcx ( ) ;
1521- let mut fulfillment_errors = Vec :: new ( ) ;
1522-
1523- let applicable_candidates: Vec < _ > = candidates
1524- . iter ( )
1525- . copied ( )
1526- . filter ( |& ( impl_, _) | {
1527- infcx. probe ( |_| {
1528- let ocx = ObligationCtxt :: new_with_diagnostics ( infcx) ;
1529- let self_ty = ocx. normalize ( & ObligationCause :: dummy ( ) , param_env, self_ty) ;
1530-
1531- let impl_args = infcx. fresh_args_for_item ( span, impl_) ;
1532- let impl_ty = tcx. type_of ( impl_) . instantiate ( tcx, impl_args) ;
1533- let impl_ty = ocx. normalize ( & ObligationCause :: dummy ( ) , param_env, impl_ty) ;
1534-
1535- // Check that the self types can be related.
1536- if ocx. eq ( & ObligationCause :: dummy ( ) , param_env, impl_ty, self_ty) . is_err ( ) {
1537- return false ;
1538- }
1539-
1540- // Check whether the impl imposes obligations we have to worry about.
1541- let impl_bounds = tcx. predicates_of ( impl_) . instantiate ( tcx, impl_args) ;
1542- let impl_bounds =
1543- ocx. normalize ( & ObligationCause :: dummy ( ) , param_env, impl_bounds) ;
1544- let impl_obligations = traits:: predicates_for_generics (
1545- |_, _| ObligationCause :: dummy ( ) ,
1546- param_env,
1547- impl_bounds,
1548- ) ;
1549- ocx. register_obligations ( impl_obligations) ;
1550-
1551- let mut errors = ocx. select_where_possible ( ) ;
1552- if !errors. is_empty ( ) {
1553- fulfillment_errors. append ( & mut errors) ;
1554- return false ;
1555- }
1556-
1557- true
1558- } )
1559- } )
1560- . collect ( ) ;
1561-
1562- match & applicable_candidates[ ..] {
1563- & [ ] => Err ( self . report_unresolved_inherent_assoc_item (
1564- name,
1565- self_ty,
1566- candidates,
1567- fulfillment_errors,
1568- span,
1569- assoc_tag,
1570- ) ) ,
1571-
1572- & [ applicable_candidate] => Ok ( applicable_candidate) ,
1573-
1574- & [ _, ..] => Err ( self . report_ambiguous_inherent_assoc_item (
1575- name,
1576- applicable_candidates. into_iter ( ) . map ( |( _, ( candidate, _) ) | candidate) . collect ( ) ,
1577- span,
1578- ) ) ,
1579- }
1580- }
1581-
15821509 /// Given name and kind search for the assoc item in the provided scope and check if it's accessible[^1].
15831510 ///
15841511 /// [^1]: I.e., accessible in the provided scope wrt. visibility and stability.
0 commit comments