Skip to content

Commit 173b6e6

Browse files
committed
Auto merge of rust-lang#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 rust-lang#66023
2 parents 5777f2c + 5061c09 commit 173b6e6

File tree

5 files changed

+46
-10
lines changed

5 files changed

+46
-10
lines changed

compiler/rustc_hir_typeck/src/expr.rs

+22-10
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::{
2121
TupleArgumentsFlag::DontTupleArguments,
2222
};
2323
use rustc_ast as ast;
24-
use rustc_data_structures::fx::FxHashMap;
24+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
2525
use rustc_data_structures::stack::ensure_sufficient_stack;
2626
use 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;

tests/ui/indexing/indexing-requires-a-uint.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ LL | [0][0u8];
88
= help: the trait `SliceIndex<[{integer}]>` is implemented for `usize`
99
= help: for that trait implementation, expected `usize`, found `u8`
1010
= note: required for `[{integer}]` to implement `Index<u8>`
11+
= note: 1 redundant requirement hidden
12+
= note: required for `[{integer}; 1]` to implement `Index<u8>`
1113

1214
error[E0308]: mismatched types
1315
--> $DIR/indexing-requires-a-uint.rs:12:18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn main() {
2+
let a = std::collections::HashMap::<String,String>::new();
3+
let s = "hello";
4+
let _b = a[
5+
&s //~ ERROR E0277
6+
];
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0277]: the trait bound `String: Borrow<&str>` is not satisfied
2+
--> $DIR/point-at-index-for-obligation-failure.rs:5:9
3+
|
4+
LL | &s
5+
| ^^ the trait `Borrow<&str>` is not implemented for `String`
6+
|
7+
= help: the trait `Borrow<str>` is implemented for `String`
8+
= help: for that trait implementation, expected `str`, found `&str`
9+
= note: required for `HashMap<String, String>` to implement `Index<&&str>`
10+
11+
error: aborting due to previous error
12+
13+
For more information about this error, try `rustc --explain E0277`.

tests/ui/suggestions/suggest-dereferencing-index.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ LL | let one_item_please: i32 = [1, 2, 3][i];
88
= help: the trait `SliceIndex<[{integer}]>` is implemented for `usize`
99
= help: for that trait implementation, expected `usize`, found `&usize`
1010
= note: required for `[{integer}]` to implement `Index<&usize>`
11+
= note: 1 redundant requirement hidden
12+
= note: required for `[{integer}; 3]` to implement `Index<&usize>`
1113
help: dereference this index
1214
|
1315
LL | let one_item_please: i32 = [1, 2, 3][*i];

0 commit comments

Comments
 (0)