@@ -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_if_possible ( errors, idx. span )
2880+ self . point_at_index ( errors, idx. span ) ;
28812881 } ) ;
28822882 element_ty
28832883 }
@@ -3036,16 +3036,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30363036 . ok ( )
30373037 }
30383038
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 ) ;
30443045 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 ( ) ) ;
30483059 }
3060+ ( root, pred) if seen_preds. contains ( & pred) || seen_preds. contains ( & root) => { }
30493061 _ => continue ,
30503062 }
30513063 error. obligation . cause . span = span;
0 commit comments