@@ -33,21 +33,21 @@ 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 , 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,
43
43
} ;
44
44
use rustc_middle:: { bug, span_bug} ;
45
45
use rustc_session:: lint:: builtin:: AMBIGUOUS_ASSOCIATED_ITEMS ;
46
46
use rustc_session:: parse:: feature_err;
47
47
use rustc_span:: { DUMMY_SP , Ident , Span , kw, sym} ;
48
48
use rustc_trait_selection:: infer:: InferCtxtExt ;
49
49
use rustc_trait_selection:: traits:: wf:: object_region_bounds;
50
- use rustc_trait_selection:: traits:: { self , ObligationCtxt } ;
50
+ use rustc_trait_selection:: traits:: { self , FulfillmentError } ;
51
51
use tracing:: { debug, instrument} ;
52
52
53
53
use crate :: check:: check_abi_fn_ptr;
@@ -99,6 +99,13 @@ pub enum RegionInferReason<'a> {
99
99
OutlivesBound ,
100
100
}
101
101
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
+
102
109
/// A context which can lower type-system entities from the [HIR][hir] to
103
110
/// the [`rustc_middle::ty`] representation.
104
111
///
@@ -148,6 +155,13 @@ pub trait HirTyLowerer<'tcx> {
148
155
assoc_ident : Ident ,
149
156
) -> ty:: EarlyBinder < ' tcx , & ' tcx [ ( ty:: Clause < ' tcx > , Span ) ] > ;
150
157
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
+
151
165
/// Lower a path to an associated item (of a trait) to a projection.
152
166
///
153
167
/// This method has to be defined by the concrete lowering context because
@@ -1441,48 +1455,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1441
1455
. filter_map ( |& impl_| {
1442
1456
let ( item, scope) =
1443
1457
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 } )
1445
1459
} )
1446
1460
. collect ( ) ;
1447
1461
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) ;
1465
1464
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
+ ) ) ,
1469
1475
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) ,
1475
1477
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
+ } ?;
1486
1484
1487
1485
self . check_assoc_item ( assoc_item, name, def_scope, block, span) ;
1488
1486
@@ -1499,78 +1497,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1499
1497
Ok ( Some ( ( assoc_item, args) ) )
1500
1498
}
1501
1499
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
-
1574
1500
/// Given name and kind search for the assoc item in the provided scope and check if it's accessible[^1].
1575
1501
///
1576
1502
/// [^1]: I.e., accessible in the provided scope wrt. visibility and stability.
0 commit comments