@@ -33,13 +33,13 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
33
33
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
34
34
use rustc_hir:: { self as hir, AnonConst , GenericArg , GenericArgs , HirId } ;
35
35
use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
36
- use rustc_infer :: traits :: ObligationCause ;
36
+ use rustc_macros :: { TypeFoldable , TypeVisitable } ;
37
37
use rustc_middle:: middle:: stability:: AllowUnstable ;
38
38
use rustc_middle:: mir:: interpret:: LitToConstInput ;
39
39
use rustc_middle:: ty:: print:: PrintPolyTraitRefExt as _;
40
40
use 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,
43
43
} ;
44
44
use rustc_middle:: { bug, span_bug} ;
45
45
use rustc_session:: lint:: builtin:: AMBIGUOUS_ASSOCIATED_ITEMS ;
@@ -48,7 +48,7 @@ use rustc_span::edit_distance::find_best_match_for_name;
48
48
use rustc_span:: { DUMMY_SP , Ident , Span , Symbol , kw, sym} ;
49
49
use rustc_trait_selection:: infer:: InferCtxtExt ;
50
50
use rustc_trait_selection:: traits:: wf:: object_region_bounds;
51
- use rustc_trait_selection:: traits:: { self , ObligationCtxt } ;
51
+ use rustc_trait_selection:: traits:: { self , FulfillmentError } ;
52
52
use tracing:: { debug, instrument} ;
53
53
54
54
use self :: errors:: assoc_tag_str;
@@ -101,6 +101,13 @@ pub enum RegionInferReason<'a> {
101
101
OutlivesBound ,
102
102
}
103
103
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
+
104
111
/// A context which can lower type-system entities from the [HIR][hir] to
105
112
/// the [`rustc_middle::ty`] representation.
106
113
///
@@ -150,6 +157,13 @@ pub trait HirTyLowerer<'tcx> {
150
157
assoc_ident : Ident ,
151
158
) -> ty:: EarlyBinder < ' tcx , & ' tcx [ ( ty:: Clause < ' tcx > , Span ) ] > ;
152
159
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
+
153
167
/// Lower an associated type/const (from a trait) to a projection.
154
168
///
155
169
/// This method has to be defined by the concrete lowering context because
@@ -1513,48 +1527,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1513
1527
. filter_map ( |& impl_| {
1514
1528
let ( item, scope) =
1515
1529
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 } )
1517
1531
} )
1518
1532
. collect ( ) ;
1519
1533
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) ;
1537
1536
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
+ ) ) ,
1541
1547
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) ,
1547
1549
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
+ } ?;
1558
1556
1559
1557
self . check_assoc_item ( assoc_item, name, def_scope, block, span) ;
1560
1558
@@ -1571,78 +1569,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1571
1569
Ok ( Some ( ( assoc_item, args) ) )
1572
1570
}
1573
1571
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
-
1646
1572
/// Given name and kind search for the assoc item in the provided scope and check if it's accessible[^1].
1647
1573
///
1648
1574
/// [^1]: I.e., accessible in the provided scope wrt. visibility and stability.
0 commit comments