@@ -21,7 +21,7 @@ use crate::{
2121 TupleArgumentsFlag :: DontTupleArguments ,
2222} ;
2323use rustc_ast as ast;
24- use rustc_data_structures:: fx:: FxHashMap ;
24+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
2525use rustc_data_structures:: stack:: ensure_sufficient_stack;
2626use rustc_errors:: {
2727 pluralize, struct_span_err, AddToDiagnostic , Applicability , Diagnostic , DiagnosticBuilder ,
@@ -2877,7 +2877,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
28772877 // two-phase not needed because index_ty is never mutable
28782878 self . demand_coerce ( idx, idx_t, index_ty, None , AllowTwoPhase :: No ) ;
28792879 self . select_obligations_where_possible ( |errors| {
2880- self . point_at_index ( errors, idx. span )
2880+ self . point_at_index ( errors, idx. span ) ;
28812881 } ) ;
28822882 element_ty
28832883 }
@@ -3037,7 +3037,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30373037 }
30383038
30393039 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 ) ;
30403045 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+ }
30413063 error. obligation . cause . span = span;
30423064 }
30433065 }
0 commit comments