diff options
| author | bors <bors@rust-lang.org> | 2023-11-14 06:20:25 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-11-14 06:20:25 +0000 |
| commit | 173b6e686b158dbad7d072c64bef3ced2052312b (patch) | |
| tree | 4835402fe44089ab2440bd3003d9df834c39b0f4 /compiler | |
| parent | 5777f2c6bdea7e6406d355c3dd4527bd6e368833 (diff) | |
| parent | 5061c09c58948de2c09ea7d8f3b50b994608dd7e (diff) | |
Auto merge of #117856 - estebank:issue-66023, r=compiler-errors
Always point at index span on index obligation failure Use more targetted span for index obligation failures by rewriting the obligation cause span. CC #66023
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_hir_typeck/src/expr.rs | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 811d8a4b94e..a6f78dc8ab5 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_if_possible(errors, idx.span) + self.point_at_index(errors, idx.span); }); element_ty } @@ -3036,16 +3036,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .ok() } - fn point_at_index_if_possible( - &self, - errors: &mut Vec<traits::FulfillmentError<'tcx>>, - span: Span, - ) { + 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.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) => { + 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; |
