@@ -15,6 +15,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
15
15
use rustc_hir:: intravisit:: Visitor ;
16
16
use rustc_hir:: { self as hir, LangItem , Node } ;
17
17
use rustc_infer:: infer:: { InferOk , TypeTrace } ;
18
+ use rustc_infer:: traits:: ImplSource ;
18
19
use rustc_infer:: traits:: solve:: Goal ;
19
20
use rustc_middle:: traits:: SignatureMismatchData ;
20
21
use rustc_middle:: traits:: select:: OverflowError ;
@@ -48,8 +49,8 @@ use crate::infer::{self, InferCtxt, InferCtxtExt as _};
48
49
use crate :: traits:: query:: evaluate_obligation:: InferCtxtExt as _;
49
50
use crate :: traits:: {
50
51
MismatchedProjectionTypes , NormalizeExt , Obligation , ObligationCause , ObligationCauseCode ,
51
- ObligationCtxt , Overflow , PredicateObligation , SelectionError , SignatureMismatch ,
52
- TraitDynIncompatible , elaborate,
52
+ ObligationCtxt , Overflow , PredicateObligation , SelectionContext , SelectionError ,
53
+ SignatureMismatch , TraitDynIncompatible , elaborate, specialization_graph ,
53
54
} ;
54
55
55
56
impl < ' a , ' tcx > TypeErrCtxt < ' a , ' tcx > {
@@ -1495,32 +1496,35 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
1495
1496
}
1496
1497
}
1497
1498
1498
- let secondary_span = ( | | {
1499
+ let secondary_span = self . probe ( |_ | {
1499
1500
let ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Projection ( proj) ) =
1500
1501
predicate. kind ( ) . skip_binder ( )
1501
1502
else {
1502
1503
return None ;
1503
1504
} ;
1504
1505
1505
- let mut associated_items = vec ! [ ] ;
1506
- self . tcx . for_each_relevant_impl (
1507
- self . tcx . trait_of_item ( proj. projection_term . def_id ) ?,
1508
- proj. projection_term . self_ty ( ) ,
1509
- |impl_def_id| {
1510
- associated_items. extend (
1511
- self . tcx . associated_items ( impl_def_id) . in_definition_order ( ) . find (
1512
- |assoc| {
1513
- assoc. trait_item_def_id == Some ( proj. projection_term . def_id )
1514
- } ,
1515
- ) ,
1516
- ) ;
1517
- } ,
1518
- ) ;
1506
+ let Ok ( Some ( ImplSource :: UserDefined ( impl_data) ) ) = SelectionContext :: new ( self )
1507
+ . poly_select (
1508
+ & obligation. with (
1509
+ self . tcx ,
1510
+ predicate. kind ( ) . rebind ( proj. projection_term . trait_ref ( self . tcx ) ) ,
1511
+ ) ,
1512
+ )
1513
+ else {
1514
+ return None ;
1515
+ } ;
1519
1516
1520
- let [ associated_item] : & [ ty:: AssocItem ] = & associated_items[ ..] else {
1517
+ let Ok ( node) =
1518
+ specialization_graph:: assoc_def ( self . tcx , impl_data. impl_def_id , proj. def_id ( ) )
1519
+ else {
1521
1520
return None ;
1522
1521
} ;
1523
- match self . tcx . hir_get_if_local ( associated_item. def_id ) {
1522
+
1523
+ if !node. is_final ( ) {
1524
+ return None ;
1525
+ }
1526
+
1527
+ match self . tcx . hir_get_if_local ( node. item . def_id ) {
1524
1528
Some (
1525
1529
hir:: Node :: TraitItem ( hir:: TraitItem {
1526
1530
kind : hir:: TraitItemKind :: Type ( _, Some ( ty) ) ,
@@ -1543,7 +1547,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
1543
1547
) ) ,
1544
1548
_ => None ,
1545
1549
}
1546
- } ) ( ) ;
1550
+ } ) ;
1547
1551
1548
1552
self . note_type_err (
1549
1553
& mut diag,
0 commit comments