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:
Yuki Okushi 2022-07-30 07:39:50 +09:00 committed by GitHub
commit 4a44efae14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 111 additions and 32 deletions

View File

@ -531,6 +531,7 @@ fn report_selection_error(
} }
self.suggest_floating_point_literal(&obligation, &mut err, &trait_ref); self.suggest_floating_point_literal(&obligation, &mut err, &trait_ref);
self.suggest_dereferencing_index(&obligation, &mut err, trait_predicate);
let mut suggested = let mut suggested =
self.suggest_dereferences(&obligation, &mut err, trait_predicate); self.suggest_dereferences(&obligation, &mut err, trait_predicate);
suggested |= self.suggest_fn_call(&obligation, &mut err, trait_predicate); suggested |= self.suggest_fn_call(&obligation, &mut err, trait_predicate);

View File

@ -320,6 +320,13 @@ fn suggest_derive(
err: &mut Diagnostic, err: &mut Diagnostic,
trait_pred: ty::PolyTraitPredicate<'tcx>, 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) { 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. /// Collect all the returned expressions within the input expression.

View File

@ -2648,6 +2648,9 @@ fn check_expr_index(
Some((index_ty, element_ty)) => { Some((index_ty, element_ty)) => {
// 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(false, |errors| {
self.point_at_index_if_possible(errors, idx.span)
});
element_ty element_ty
} }
None => { 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( fn check_expr_yield(
&self, &self,
value: &'tcx hir::Expr<'tcx>, value: &'tcx hir::Expr<'tcx>,

View File

@ -1,8 +1,8 @@
error[E0277]: the type `[{integer}]` cannot be indexed by `i32` 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]; 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<[{integer}]>` is not implemented for `i32`
= help: the trait `SliceIndex<[T]>` is implemented for `usize` = help: the trait `SliceIndex<[T]>` is implemented for `usize`

View File

@ -1,8 +1,8 @@
error[E0277]: the type `[{integer}]` cannot be indexed by `u8` 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]; 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<[{integer}]>` is not implemented for `u8`
= help: the trait `SliceIndex<[T]>` is implemented for `usize` = help: the trait `SliceIndex<[T]>` is implemented for `usize`

View File

@ -1,78 +1,78 @@
error[E0277]: the type `[isize]` cannot be indexed by `u8` 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]; 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<[isize]>` is not implemented for `u8`
= help: the trait `SliceIndex<[T]>` is implemented for `usize` = help: the trait `SliceIndex<[T]>` is implemented for `usize`
= note: required because of the requirements on the impl of `Index<u8>` for `Vec<isize>` = 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` 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]; 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<[isize]>` is not implemented for `i8`
= help: the trait `SliceIndex<[T]>` is implemented for `usize` = help: the trait `SliceIndex<[T]>` is implemented for `usize`
= note: required because of the requirements on the impl of `Index<i8>` for `Vec<isize>` = 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` 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]; 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<[isize]>` is not implemented for `u32`
= help: the trait `SliceIndex<[T]>` is implemented for `usize` = help: the trait `SliceIndex<[T]>` is implemented for `usize`
= note: required because of the requirements on the impl of `Index<u32>` for `Vec<isize>` = 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` 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]; 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<[isize]>` is not implemented for `i32`
= help: the trait `SliceIndex<[T]>` is implemented for `usize` = help: the trait `SliceIndex<[T]>` is implemented for `usize`
= note: required because of the requirements on the impl of `Index<i32>` for `Vec<isize>` = 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` 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]; 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<[u8]>` is not implemented for `u8`
= help: the trait `SliceIndex<[T]>` is implemented for `usize` = help: the trait `SliceIndex<[T]>` is implemented for `usize`
= note: required because of the requirements on the impl of `Index<u8>` for `[u8]` = note: required because of the requirements on the impl of `Index<u8>` for `[u8]`
error[E0277]: the type `[u8]` cannot be indexed by `i8` 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]; 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<[u8]>` is not implemented for `i8`
= help: the trait `SliceIndex<[T]>` is implemented for `usize` = help: the trait `SliceIndex<[T]>` is implemented for `usize`
= note: required because of the requirements on the impl of `Index<i8>` for `[u8]` = note: required because of the requirements on the impl of `Index<i8>` for `[u8]`
error[E0277]: the type `[u8]` cannot be indexed by `u32` 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]; 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<[u8]>` is not implemented for `u32`
= help: the trait `SliceIndex<[T]>` is implemented for `usize` = help: the trait `SliceIndex<[T]>` is implemented for `usize`
= note: required because of the requirements on the impl of `Index<u32>` for `[u8]` = note: required because of the requirements on the impl of `Index<u32>` for `[u8]`
error[E0277]: the type `[u8]` cannot be indexed by `i32` 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]; 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<[u8]>` is not implemented for `i32`
= help: the trait `SliceIndex<[T]>` is implemented for `usize` = help: the trait `SliceIndex<[T]>` is implemented for `usize`

View File

@ -1,18 +1,18 @@
error[E0277]: the type `[i32]` cannot be indexed by `i32` 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]; 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<[i32]>` is not implemented for `i32`
= help: the trait `SliceIndex<[T]>` is implemented for `usize` = help: the trait `SliceIndex<[T]>` is implemented for `usize`
= note: required because of the requirements on the impl of `Index<i32>` for `[i32]` = 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>` 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]; 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 trait `SliceIndex<[i32]>` is not implemented for `RangeTo<i32>`
= help: the following other types implement trait `SliceIndex<T>`: = help: the following other types implement trait `SliceIndex<T>`:

View File

@ -1,8 +1,8 @@
error[E0277]: the type `str` cannot be indexed by `{integer}` 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]; 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}` = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
= note: you can use `.chars().nth()` or `.bytes().nth()` = 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` | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::<impl str>::get_unchecked`
error[E0277]: the type `str` cannot be indexed by `char` 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']; 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` = help: the trait `SliceIndex<str>` is not implemented for `char`
= note: required because of the requirements on the impl of `Index<char>` for `str` = note: required because of the requirements on the impl of `Index<char>` for `str`

View File

@ -25,10 +25,10 @@ LL | s[1..2] = bot();
= note: the left-hand-side of an assignment must have a statically known size = note: the left-hand-side of an assignment must have a statically known size
error[E0277]: the type `str` cannot be indexed by `usize` 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(); 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<str>` is not implemented for `usize`
= help: the trait `SliceIndex<[T]>` is 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` | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::<impl str>::get_unchecked_mut`
error[E0277]: the type `str` cannot be indexed by `char` 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']; 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` = help: the trait `SliceIndex<str>` is not implemented for `char`
= note: required because of the requirements on the impl of `Index<char>` for `str` = note: required because of the requirements on the impl of `Index<char>` for `str`

View 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`
}

View 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`
}

View 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`.