Rollup merge of #99671 - TaKO8Ki:suggest-dereferencing-index, r=compiler-errors
Suggest dereferencing index when trying to use a reference of usize as index fixes #96678
This commit is contained in:
commit
4a44efae14
@ -531,6 +531,7 @@ fn report_selection_error(
|
||||
}
|
||||
|
||||
self.suggest_floating_point_literal(&obligation, &mut err, &trait_ref);
|
||||
self.suggest_dereferencing_index(&obligation, &mut err, trait_predicate);
|
||||
let mut suggested =
|
||||
self.suggest_dereferences(&obligation, &mut err, trait_predicate);
|
||||
suggested |= self.suggest_fn_call(&obligation, &mut err, trait_predicate);
|
||||
|
@ -320,6 +320,13 @@ fn suggest_derive(
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
);
|
||||
|
||||
fn suggest_dereferencing_index(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
);
|
||||
}
|
||||
|
||||
fn predicate_constraint(generics: &hir::Generics<'_>, pred: String) -> (Span, String) {
|
||||
@ -2895,6 +2902,27 @@ fn suggest_derive(
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_dereferencing_index(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) {
|
||||
if let ObligationCauseCode::ImplDerivedObligation(_) = obligation.cause.code()
|
||||
&& self.tcx.is_diagnostic_item(sym::SliceIndex, trait_pred.skip_binder().trait_ref.def_id)
|
||||
&& let ty::Slice(_) = trait_pred.skip_binder().trait_ref.substs.type_at(1).kind()
|
||||
&& let ty::Ref(_, inner_ty, _) = trait_pred.skip_binder().self_ty().kind()
|
||||
&& let ty::Uint(ty::UintTy::Usize) = inner_ty.kind()
|
||||
{
|
||||
err.span_suggestion_verbose(
|
||||
obligation.cause.span.shrink_to_lo(),
|
||||
"dereference this index",
|
||||
'*',
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Collect all the returned expressions within the input expression.
|
||||
|
@ -2648,6 +2648,9 @@ fn check_expr_index(
|
||||
Some((index_ty, element_ty)) => {
|
||||
// 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(false, |errors| {
|
||||
self.point_at_index_if_possible(errors, idx.span)
|
||||
});
|
||||
element_ty
|
||||
}
|
||||
None => {
|
||||
@ -2691,6 +2694,22 @@ fn check_expr_index(
|
||||
}
|
||||
}
|
||||
|
||||
fn point_at_index_if_possible(
|
||||
&self,
|
||||
errors: &mut Vec<traits::FulfillmentError<'tcx>>,
|
||||
span: Span,
|
||||
) {
|
||||
for error in errors {
|
||||
match error.obligation.predicate.kind().skip_binder() {
|
||||
ty::PredicateKind::Trait(predicate)
|
||||
if self.tcx.is_diagnostic_item(sym::SliceIndex, predicate.trait_ref.def_id) => {
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
error.obligation.cause.span = span;
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr_yield(
|
||||
&self,
|
||||
value: &'tcx hir::Expr<'tcx>,
|
||||
|
@ -1,8 +1,8 @@
|
||||
error[E0277]: the type `[{integer}]` cannot be indexed by `i32`
|
||||
--> $DIR/index-help.rs:3:5
|
||||
--> $DIR/index-help.rs:3:7
|
||||
|
|
||||
LL | x[0i32];
|
||||
| ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
| ^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
|
|
||||
= help: the trait `SliceIndex<[{integer}]>` is not implemented for `i32`
|
||||
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
|
||||
|
@ -1,8 +1,8 @@
|
||||
error[E0277]: the type `[{integer}]` cannot be indexed by `u8`
|
||||
--> $DIR/indexing-requires-a-uint.rs:6:5
|
||||
--> $DIR/indexing-requires-a-uint.rs:6:9
|
||||
|
|
||||
LL | [0][0u8];
|
||||
| ^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
| ^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
|
|
||||
= help: the trait `SliceIndex<[{integer}]>` is not implemented for `u8`
|
||||
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
|
||||
|
@ -1,78 +1,78 @@
|
||||
error[E0277]: the type `[isize]` cannot be indexed by `u8`
|
||||
--> $DIR/integral-indexing.rs:6:5
|
||||
--> $DIR/integral-indexing.rs:6:7
|
||||
|
|
||||
LL | v[3u8];
|
||||
| ^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
| ^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
|
|
||||
= help: the trait `SliceIndex<[isize]>` is not implemented for `u8`
|
||||
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
|
||||
= note: required because of the requirements on the impl of `Index<u8>` for `Vec<isize>`
|
||||
|
||||
error[E0277]: the type `[isize]` cannot be indexed by `i8`
|
||||
--> $DIR/integral-indexing.rs:7:5
|
||||
--> $DIR/integral-indexing.rs:7:7
|
||||
|
|
||||
LL | v[3i8];
|
||||
| ^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
| ^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
|
|
||||
= help: the trait `SliceIndex<[isize]>` is not implemented for `i8`
|
||||
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
|
||||
= note: required because of the requirements on the impl of `Index<i8>` for `Vec<isize>`
|
||||
|
||||
error[E0277]: the type `[isize]` cannot be indexed by `u32`
|
||||
--> $DIR/integral-indexing.rs:8:5
|
||||
--> $DIR/integral-indexing.rs:8:7
|
||||
|
|
||||
LL | v[3u32];
|
||||
| ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
| ^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
|
|
||||
= help: the trait `SliceIndex<[isize]>` is not implemented for `u32`
|
||||
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
|
||||
= note: required because of the requirements on the impl of `Index<u32>` for `Vec<isize>`
|
||||
|
||||
error[E0277]: the type `[isize]` cannot be indexed by `i32`
|
||||
--> $DIR/integral-indexing.rs:9:5
|
||||
--> $DIR/integral-indexing.rs:9:7
|
||||
|
|
||||
LL | v[3i32];
|
||||
| ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
| ^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
|
|
||||
= help: the trait `SliceIndex<[isize]>` is not implemented for `i32`
|
||||
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
|
||||
= note: required because of the requirements on the impl of `Index<i32>` for `Vec<isize>`
|
||||
|
||||
error[E0277]: the type `[u8]` cannot be indexed by `u8`
|
||||
--> $DIR/integral-indexing.rs:12:5
|
||||
--> $DIR/integral-indexing.rs:12:18
|
||||
|
|
||||
LL | s.as_bytes()[3u8];
|
||||
| ^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
| ^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
|
|
||||
= help: the trait `SliceIndex<[u8]>` is not implemented for `u8`
|
||||
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
|
||||
= note: required because of the requirements on the impl of `Index<u8>` for `[u8]`
|
||||
|
||||
error[E0277]: the type `[u8]` cannot be indexed by `i8`
|
||||
--> $DIR/integral-indexing.rs:13:5
|
||||
--> $DIR/integral-indexing.rs:13:18
|
||||
|
|
||||
LL | s.as_bytes()[3i8];
|
||||
| ^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
| ^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
|
|
||||
= help: the trait `SliceIndex<[u8]>` is not implemented for `i8`
|
||||
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
|
||||
= note: required because of the requirements on the impl of `Index<i8>` for `[u8]`
|
||||
|
||||
error[E0277]: the type `[u8]` cannot be indexed by `u32`
|
||||
--> $DIR/integral-indexing.rs:14:5
|
||||
--> $DIR/integral-indexing.rs:14:18
|
||||
|
|
||||
LL | s.as_bytes()[3u32];
|
||||
| ^^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
| ^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
|
|
||||
= help: the trait `SliceIndex<[u8]>` is not implemented for `u32`
|
||||
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
|
||||
= note: required because of the requirements on the impl of `Index<u32>` for `[u8]`
|
||||
|
||||
error[E0277]: the type `[u8]` cannot be indexed by `i32`
|
||||
--> $DIR/integral-indexing.rs:15:5
|
||||
--> $DIR/integral-indexing.rs:15:18
|
||||
|
|
||||
LL | s.as_bytes()[3i32];
|
||||
| ^^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
| ^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
|
|
||||
= help: the trait `SliceIndex<[u8]>` is not implemented for `i32`
|
||||
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
|
||||
|
@ -1,18 +1,18 @@
|
||||
error[E0277]: the type `[i32]` cannot be indexed by `i32`
|
||||
--> $DIR/slice-index.rs:8:5
|
||||
--> $DIR/slice-index.rs:8:7
|
||||
|
|
||||
LL | x[1i32];
|
||||
| ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
| ^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
|
|
||||
= help: the trait `SliceIndex<[i32]>` is not implemented for `i32`
|
||||
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
|
||||
= note: required because of the requirements on the impl of `Index<i32>` for `[i32]`
|
||||
|
||||
error[E0277]: the type `[i32]` cannot be indexed by `RangeTo<i32>`
|
||||
--> $DIR/slice-index.rs:9:5
|
||||
--> $DIR/slice-index.rs:9:7
|
||||
|
|
||||
LL | x[..1i32];
|
||||
| ^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
| ^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
|
|
||||
= help: the trait `SliceIndex<[i32]>` is not implemented for `RangeTo<i32>`
|
||||
= help: the following other types implement trait `SliceIndex<T>`:
|
||||
|
@ -1,8 +1,8 @@
|
||||
error[E0277]: the type `str` cannot be indexed by `{integer}`
|
||||
--> $DIR/str-idx.rs:3:17
|
||||
--> $DIR/str-idx.rs:3:19
|
||||
|
|
||||
LL | let _: u8 = s[4];
|
||||
| ^^^^ string indices are ranges of `usize`
|
||||
| ^ string indices are ranges of `usize`
|
||||
|
|
||||
= help: the trait `SliceIndex<str>` is not implemented for `{integer}`
|
||||
= note: you can use `.chars().nth()` or `.bytes().nth()`
|
||||
@ -47,10 +47,10 @@ LL | pub const unsafe fn get_unchecked<I: ~const SliceIndex<str>>(&self, i:
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::<impl str>::get_unchecked`
|
||||
|
||||
error[E0277]: the type `str` cannot be indexed by `char`
|
||||
--> $DIR/str-idx.rs:6:17
|
||||
--> $DIR/str-idx.rs:6:19
|
||||
|
|
||||
LL | let _: u8 = s['c'];
|
||||
| ^^^^^^ string indices are ranges of `usize`
|
||||
| ^^^ string indices are ranges of `usize`
|
||||
|
|
||||
= help: the trait `SliceIndex<str>` is not implemented for `char`
|
||||
= note: required because of the requirements on the impl of `Index<char>` for `str`
|
||||
|
@ -25,10 +25,10 @@ LL | s[1..2] = bot();
|
||||
= note: the left-hand-side of an assignment must have a statically known size
|
||||
|
||||
error[E0277]: the type `str` cannot be indexed by `usize`
|
||||
--> $DIR/str-mut-idx.rs:7:5
|
||||
--> $DIR/str-mut-idx.rs:7:7
|
||||
|
|
||||
LL | s[1usize] = bot();
|
||||
| ^^^^^^^^^ string indices are ranges of `usize`
|
||||
| ^^^^^^ string indices are ranges of `usize`
|
||||
|
|
||||
= help: the trait `SliceIndex<str>` is not implemented for `usize`
|
||||
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
|
||||
@ -71,10 +71,10 @@ LL | pub const unsafe fn get_unchecked_mut<I: ~const SliceIndex<str>>(
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::<impl str>::get_unchecked_mut`
|
||||
|
||||
error[E0277]: the type `str` cannot be indexed by `char`
|
||||
--> $DIR/str-mut-idx.rs:13:5
|
||||
--> $DIR/str-mut-idx.rs:13:7
|
||||
|
|
||||
LL | s['c'];
|
||||
| ^^^^^^ string indices are ranges of `usize`
|
||||
| ^^^ string indices are ranges of `usize`
|
||||
|
|
||||
= help: the trait `SliceIndex<str>` is not implemented for `char`
|
||||
= note: required because of the requirements on the impl of `Index<char>` for `str`
|
||||
|
@ -0,0 +1,7 @@
|
||||
// run-rustfix
|
||||
#![allow(unused_variables)]
|
||||
|
||||
fn main() {
|
||||
let i: &usize = &1;
|
||||
let one_item_please: i32 = [1, 2, 3][*i]; //~ ERROR the type `[{integer}]` cannot be indexed by `&usize`
|
||||
}
|
7
src/test/ui/suggestions/suggest-dereferencing-index.rs
Normal file
7
src/test/ui/suggestions/suggest-dereferencing-index.rs
Normal file
@ -0,0 +1,7 @@
|
||||
// run-rustfix
|
||||
#![allow(unused_variables)]
|
||||
|
||||
fn main() {
|
||||
let i: &usize = &1;
|
||||
let one_item_please: i32 = [1, 2, 3][i]; //~ ERROR the type `[{integer}]` cannot be indexed by `&usize`
|
||||
}
|
17
src/test/ui/suggestions/suggest-dereferencing-index.stderr
Normal file
17
src/test/ui/suggestions/suggest-dereferencing-index.stderr
Normal file
@ -0,0 +1,17 @@
|
||||
error[E0277]: the type `[{integer}]` cannot be indexed by `&usize`
|
||||
--> $DIR/suggest-dereferencing-index.rs:6:42
|
||||
|
|
||||
LL | let one_item_please: i32 = [1, 2, 3][i];
|
||||
| ^ slice indices are of type `usize` or ranges of `usize`
|
||||
|
|
||||
= help: the trait `SliceIndex<[{integer}]>` is not implemented for `&usize`
|
||||
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
|
||||
= note: required because of the requirements on the impl of `Index<&usize>` for `[{integer}]`
|
||||
help: dereference this index
|
||||
|
|
||||
LL | let one_item_please: i32 = [1, 2, 3][*i];
|
||||
| +
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Reference in New Issue
Block a user