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
This commit is contained in:
commit
173b6e686b
@ -21,7 +21,7 @@ use crate::{
|
|||||||
TupleArgumentsFlag::DontTupleArguments,
|
TupleArgumentsFlag::DontTupleArguments,
|
||||||
};
|
};
|
||||||
use rustc_ast as ast;
|
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_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
pluralize, struct_span_err, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder,
|
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
|
// two-phase not needed because index_ty is never mutable
|
||||||
self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No);
|
self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No);
|
||||||
self.select_obligations_where_possible(|errors| {
|
self.select_obligations_where_possible(|errors| {
|
||||||
self.point_at_index_if_possible(errors, idx.span)
|
self.point_at_index(errors, idx.span);
|
||||||
});
|
});
|
||||||
element_ty
|
element_ty
|
||||||
}
|
}
|
||||||
@ -3036,16 +3036,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
.ok()
|
.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn point_at_index_if_possible(
|
fn point_at_index(&self, errors: &mut Vec<traits::FulfillmentError<'tcx>>, span: Span) {
|
||||||
&self,
|
let mut seen_preds = FxHashSet::default();
|
||||||
errors: &mut Vec<traits::FulfillmentError<'tcx>>,
|
// We re-sort here so that the outer most root obligations comes first, as we have the
|
||||||
span: Span,
|
// 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 {
|
for error in errors {
|
||||||
match error.obligation.predicate.kind().skip_binder() {
|
match (
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate))
|
error.root_obligation.predicate.kind().skip_binder(),
|
||||||
if self.tcx.is_diagnostic_item(sym::SliceIndex, predicate.trait_ref.def_id) => {
|
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,
|
_ => continue,
|
||||||
}
|
}
|
||||||
error.obligation.cause.span = span;
|
error.obligation.cause.span = span;
|
||||||
|
@ -8,6 +8,8 @@ LL | [0][0u8];
|
|||||||
= help: the trait `SliceIndex<[{integer}]>` is implemented for `usize`
|
= help: the trait `SliceIndex<[{integer}]>` is implemented for `usize`
|
||||||
= help: for that trait implementation, expected `usize`, found `u8`
|
= help: for that trait implementation, expected `usize`, found `u8`
|
||||||
= note: required for `[{integer}]` to implement `Index<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
|
error[E0308]: mismatched types
|
||||||
--> $DIR/indexing-requires-a-uint.rs:12:18
|
--> $DIR/indexing-requires-a-uint.rs:12:18
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
fn main() {
|
||||||
|
let a = std::collections::HashMap::<String,String>::new();
|
||||||
|
let s = "hello";
|
||||||
|
let _b = a[
|
||||||
|
&s //~ ERROR E0277
|
||||||
|
];
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
error[E0277]: the trait bound `String: Borrow<&str>` is not satisfied
|
||||||
|
--> $DIR/point-at-index-for-obligation-failure.rs:5:9
|
||||||
|
|
|
||||||
|
LL | &s
|
||||||
|
| ^^ the trait `Borrow<&str>` is not implemented for `String`
|
||||||
|
|
|
||||||
|
= help: the trait `Borrow<str>` is implemented for `String`
|
||||||
|
= help: for that trait implementation, expected `str`, found `&str`
|
||||||
|
= note: required for `HashMap<String, String>` to implement `Index<&&str>`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
@ -8,6 +8,8 @@ LL | let one_item_please: i32 = [1, 2, 3][i];
|
|||||||
= help: the trait `SliceIndex<[{integer}]>` is implemented for `usize`
|
= help: the trait `SliceIndex<[{integer}]>` is implemented for `usize`
|
||||||
= help: for that trait implementation, expected `usize`, found `&usize`
|
= help: for that trait implementation, expected `usize`, found `&usize`
|
||||||
= note: required for `[{integer}]` to implement `Index<&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
|
help: dereference this index
|
||||||
|
|
|
|
||||||
LL | let one_item_please: i32 = [1, 2, 3][*i];
|
LL | let one_item_please: i32 = [1, 2, 3][*i];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user