@@ -33,21 +33,22 @@ 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:: { DynCompatibilityViolation , ObligationCause } ;
36
+ use rustc_infer:: traits:: DynCompatibilityViolation ;
37
+ use rustc_macros:: { TypeFoldable , TypeVisitable } ;
37
38
use rustc_middle:: middle:: stability:: AllowUnstable ;
38
39
use rustc_middle:: mir:: interpret:: LitToConstInput ;
39
40
use rustc_middle:: ty:: print:: PrintPolyTraitRefExt as _;
40
41
use 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,
43
44
} ;
44
45
use rustc_middle:: { bug, span_bug} ;
45
46
use rustc_session:: lint:: builtin:: AMBIGUOUS_ASSOCIATED_ITEMS ;
46
47
use rustc_session:: parse:: feature_err;
47
48
use rustc_span:: { DUMMY_SP , Ident , Span , kw, sym} ;
48
49
use rustc_trait_selection:: infer:: InferCtxtExt ;
49
50
use rustc_trait_selection:: traits:: wf:: object_region_bounds;
50
- use rustc_trait_selection:: traits:: { self , ObligationCtxt } ;
51
+ use rustc_trait_selection:: traits:: { self , FulfillmentError } ;
51
52
use tracing:: { debug, instrument} ;
52
53
53
54
use crate :: check:: check_abi_fn_ptr;
@@ -99,6 +100,13 @@ pub enum RegionInferReason<'a> {
99
100
OutlivesBound ,
100
101
}
101
102
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
+
102
110
/// A context which can lower type-system entities from the [HIR][hir] to
103
111
/// the [`rustc_middle::ty`] representation.
104
112
///
@@ -148,6 +156,13 @@ pub trait HirTyLowerer<'tcx> {
148
156
assoc_ident : Ident ,
149
157
) -> ty:: EarlyBinder < ' tcx , & ' tcx [ ( ty:: Clause < ' tcx > , Span ) ] > ;
150
158
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
+
151
166
/// Lower a path to an associated item (of a trait) to a projection.
152
167
///
153
168
/// This method has to be defined by the concrete lowering context because
@@ -1449,48 +1464,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1449
1464
. filter_map ( |& impl_| {
1450
1465
let ( item, scope) =
1451
1466
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 } )
1453
1468
} )
1454
1469
. collect ( ) ;
1455
1470
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 ( ) ) ;
1473
1473
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
+ ) ) ,
1477
1484
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) ,
1483
1486
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
+ } ?;
1494
1493
1495
1494
self . check_assoc_item ( assoc_item, name, def_scope, block, span) ;
1496
1495
@@ -1507,78 +1506,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1507
1506
Ok ( Some ( ( assoc_item, args) ) )
1508
1507
}
1509
1508
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
-
1582
1509
/// Given name and kind search for the assoc item in the provided scope and check if it's accessible[^1].
1583
1510
///
1584
1511
/// [^1]: I.e., accessible in the provided scope wrt. visibility and stability.
0 commit comments