about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2023-11-13 17:05:08 +0000
committerEsteban Küber <esteban@kuber.com.ar>2023-11-13 19:57:15 +0000
commit5061c09c58948de2c09ea7d8f3b50b994608dd7e (patch)
tree630836b6662bfcd8850169bfd45c789d69c810d6
parent69634f2077bc4f223cca7dfb63e104ac1efa0752 (diff)
downloadrust-5061c09c58948de2c09ea7d8f3b50b994608dd7e.tar.gz
rust-5061c09c58948de2c09ea7d8f3b50b994608dd7e.zip
review comments: more targeted span setting approach
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs26
-rw-r--r--tests/ui/indexing/indexing-requires-a-uint.stderr2
-rw-r--r--tests/ui/suggestions/suggest-dereferencing-index.stderr2
3 files changed, 28 insertions, 2 deletions
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 7298e1e5702..f1987c29ddc 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -21,7 +21,7 @@ use crate::{
     TupleArgumentsFlag::DontTupleArguments,
 };
 use rustc_ast as ast;
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::{
     pluralize, struct_span_err, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder,
@@ -2877,7 +2877,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // two-phase not needed because index_ty is never mutable
                     self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No);
                     self.select_obligations_where_possible(|errors| {
-                        self.point_at_index(errors, idx.span)
+                        self.point_at_index(errors, idx.span);
                     });
                     element_ty
                 }
@@ -3037,7 +3037,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     fn point_at_index(&self, errors: &mut Vec<traits::FulfillmentError<'tcx>>, span: Span) {
+        let mut seen_preds = FxHashSet::default();
+        // We re-sort here so that the outer most root obligations comes first, as we have the
+        // subsequent weird logic to identify *every* relevant obligation for proper deduplication
+        // of diagnostics.
+        errors.sort_by_key(|error| error.root_obligation.recursion_depth);
         for error in errors {
+            match (
+                error.root_obligation.predicate.kind().skip_binder(),
+                error.obligation.predicate.kind().skip_binder(),
+            ) {
+                (ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)), _)
+                    if self.tcx.lang_items().index_trait() == Some(predicate.trait_ref.def_id) =>
+                {
+                    seen_preds.insert(error.obligation.predicate.kind().skip_binder());
+                }
+                (_, ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)))
+                    if self.tcx.is_diagnostic_item(sym::SliceIndex, predicate.trait_ref.def_id) =>
+                {
+                    seen_preds.insert(error.obligation.predicate.kind().skip_binder());
+                }
+                (root, pred) if seen_preds.contains(&pred) || seen_preds.contains(&root) => {}
+                _ => continue,
+            }
             error.obligation.cause.span = span;
         }
     }
diff --git a/tests/ui/indexing/indexing-requires-a-uint.stderr b/tests/ui/indexing/indexing-requires-a-uint.stderr
index 6ea6bb600e9..3041c2c99a1 100644
--- a/tests/ui/indexing/indexing-requires-a-uint.stderr
+++ b/tests/ui/indexing/indexing-requires-a-uint.stderr
@@ -8,6 +8,8 @@ LL |     [0][0u8];
    = help: the trait `SliceIndex<[{integer}]>` is implemented for `usize`
    = help: for that trait implementation, expected `usize`, found `u8`
    = note: required for `[{integer}]` to implement `Index<u8>`
+   = note: 1 redundant requirement hidden
+   = note: required for `[{integer}; 1]` to implement `Index<u8>`
 
 error[E0308]: mismatched types
   --> $DIR/indexing-requires-a-uint.rs:12:18
diff --git a/tests/ui/suggestions/suggest-dereferencing-index.stderr b/tests/ui/suggestions/suggest-dereferencing-index.stderr
index adf01339972..23f6657f092 100644
--- a/tests/ui/suggestions/suggest-dereferencing-index.stderr
+++ b/tests/ui/suggestions/suggest-dereferencing-index.stderr
@@ -8,6 +8,8 @@ LL |     let one_item_please: i32 = [1, 2, 3][i];
    = help: the trait `SliceIndex<[{integer}]>` is implemented for `usize`
    = help: for that trait implementation, expected `usize`, found `&usize`
    = note: required for `[{integer}]` to implement `Index<&usize>`
+   = note: 1 redundant requirement hidden
+   = note: required for `[{integer}; 3]` to implement `Index<&usize>`
 help: dereference this index
    |
 LL |     let one_item_please: i32 = [1, 2, 3][*i];