@@ -21,7 +21,7 @@ use crate::{
21
21
TupleArgumentsFlag :: DontTupleArguments ,
22
22
} ;
23
23
use rustc_ast as ast;
24
- use rustc_data_structures:: fx:: FxHashMap ;
24
+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
25
25
use rustc_data_structures:: stack:: ensure_sufficient_stack;
26
26
use rustc_errors:: {
27
27
pluralize, struct_span_err, AddToDiagnostic , Applicability , Diagnostic , DiagnosticBuilder ,
@@ -2877,7 +2877,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2877
2877
// two-phase not needed because index_ty is never mutable
2878
2878
self . demand_coerce ( idx, idx_t, index_ty, None , AllowTwoPhase :: No ) ;
2879
2879
self . select_obligations_where_possible ( |errors| {
2880
- self . point_at_index_if_possible ( errors, idx. span )
2880
+ self . point_at_index ( errors, idx. span ) ;
2881
2881
} ) ;
2882
2882
element_ty
2883
2883
}
@@ -3036,16 +3036,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3036
3036
. ok ( )
3037
3037
}
3038
3038
3039
- fn point_at_index_if_possible (
3040
- & self ,
3041
- errors : & mut Vec < traits:: FulfillmentError < ' tcx > > ,
3042
- span : Span ,
3043
- ) {
3039
+ fn point_at_index ( & self , errors : & mut Vec < traits:: FulfillmentError < ' tcx > > , span : Span ) {
3040
+ let mut seen_preds = FxHashSet :: default ( ) ;
3041
+ // We re-sort here so that the outer most root obligations comes first, as we have the
3042
+ // subsequent weird logic to identify *every* relevant obligation for proper deduplication
3043
+ // of diagnostics.
3044
+ errors. sort_by_key ( |error| error. root_obligation . recursion_depth ) ;
3044
3045
for error in errors {
3045
- match error. obligation . predicate . kind ( ) . skip_binder ( ) {
3046
- ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( predicate) )
3047
- if self . tcx . is_diagnostic_item ( sym:: SliceIndex , predicate. trait_ref . def_id ) => {
3046
+ match (
3047
+ error. root_obligation . predicate . kind ( ) . skip_binder ( ) ,
3048
+ error. obligation . predicate . kind ( ) . skip_binder ( ) ,
3049
+ ) {
3050
+ ( ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( predicate) ) , _)
3051
+ if self . tcx . lang_items ( ) . index_trait ( ) == Some ( predicate. trait_ref . def_id ) =>
3052
+ {
3053
+ seen_preds. insert ( error. obligation . predicate . kind ( ) . skip_binder ( ) ) ;
3054
+ }
3055
+ ( _, ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( predicate) ) )
3056
+ if self . tcx . is_diagnostic_item ( sym:: SliceIndex , predicate. trait_ref . def_id ) =>
3057
+ {
3058
+ seen_preds. insert ( error. obligation . predicate . kind ( ) . skip_binder ( ) ) ;
3048
3059
}
3060
+ ( root, pred) if seen_preds. contains ( & pred) || seen_preds. contains ( & root) => { }
3049
3061
_ => continue ,
3050
3062
}
3051
3063
error. obligation . cause . span = span;
0 commit comments