@@ -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 ( errors, idx. span )
2880
+ self . point_at_index ( errors, idx. span ) ;
2881
2881
} ) ;
2882
2882
element_ty
2883
2883
}
@@ -3037,7 +3037,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3037
3037
}
3038
3038
3039
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 ) ;
3040
3045
for error in errors {
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 ( ) ) ;
3059
+ }
3060
+ ( root, pred) if seen_preds. contains ( & pred) || seen_preds. contains ( & root) => { }
3061
+ _ => continue ,
3062
+ }
3041
3063
error. obligation . cause . span = span;
3042
3064
}
3043
3065
}
0 commit comments