Skip to content

Commit 4a44efa

Browse files
authored
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
2 parents 955091b + 3ae669d commit 4a44efa

File tree

12 files changed

+111
-32
lines changed

12 files changed

+111
-32
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
531531
}
532532

533533
self.suggest_floating_point_literal(&obligation, &mut err, &trait_ref);
534+
self.suggest_dereferencing_index(&obligation, &mut err, trait_predicate);
534535
let mut suggested =
535536
self.suggest_dereferences(&obligation, &mut err, trait_predicate);
536537
suggested |= self.suggest_fn_call(&obligation, &mut err, trait_predicate);

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+28
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,13 @@ pub trait InferCtxtExt<'tcx> {
320320
err: &mut Diagnostic,
321321
trait_pred: ty::PolyTraitPredicate<'tcx>,
322322
);
323+
324+
fn suggest_dereferencing_index(
325+
&self,
326+
obligation: &PredicateObligation<'tcx>,
327+
err: &mut Diagnostic,
328+
trait_pred: ty::PolyTraitPredicate<'tcx>,
329+
);
323330
}
324331

325332
fn predicate_constraint(generics: &hir::Generics<'_>, pred: String) -> (Span, String) {
@@ -2895,6 +2902,27 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
28952902
);
28962903
}
28972904
}
2905+
2906+
fn suggest_dereferencing_index(
2907+
&self,
2908+
obligation: &PredicateObligation<'tcx>,
2909+
err: &mut Diagnostic,
2910+
trait_pred: ty::PolyTraitPredicate<'tcx>,
2911+
) {
2912+
if let ObligationCauseCode::ImplDerivedObligation(_) = obligation.cause.code()
2913+
&& self.tcx.is_diagnostic_item(sym::SliceIndex, trait_pred.skip_binder().trait_ref.def_id)
2914+
&& let ty::Slice(_) = trait_pred.skip_binder().trait_ref.substs.type_at(1).kind()
2915+
&& let ty::Ref(_, inner_ty, _) = trait_pred.skip_binder().self_ty().kind()
2916+
&& let ty::Uint(ty::UintTy::Usize) = inner_ty.kind()
2917+
{
2918+
err.span_suggestion_verbose(
2919+
obligation.cause.span.shrink_to_lo(),
2920+
"dereference this index",
2921+
'*',
2922+
Applicability::MachineApplicable,
2923+
);
2924+
}
2925+
}
28982926
}
28992927

29002928
/// Collect all the returned expressions within the input expression.

compiler/rustc_typeck/src/check/expr.rs

+19
Original file line numberDiff line numberDiff line change
@@ -2648,6 +2648,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26482648
Some((index_ty, element_ty)) => {
26492649
// two-phase not needed because index_ty is never mutable
26502650
self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No);
2651+
self.select_obligations_where_possible(false, |errors| {
2652+
self.point_at_index_if_possible(errors, idx.span)
2653+
});
26512654
element_ty
26522655
}
26532656
None => {
@@ -2691,6 +2694,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26912694
}
26922695
}
26932696

2697+
fn point_at_index_if_possible(
2698+
&self,
2699+
errors: &mut Vec<traits::FulfillmentError<'tcx>>,
2700+
span: Span,
2701+
) {
2702+
for error in errors {
2703+
match error.obligation.predicate.kind().skip_binder() {
2704+
ty::PredicateKind::Trait(predicate)
2705+
if self.tcx.is_diagnostic_item(sym::SliceIndex, predicate.trait_ref.def_id) => {
2706+
}
2707+
_ => continue,
2708+
}
2709+
error.obligation.cause.span = span;
2710+
}
2711+
}
2712+
26942713
fn check_expr_yield(
26952714
&self,
26962715
value: &'tcx hir::Expr<'tcx>,

src/test/ui/index-help.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the type `[{integer}]` cannot be indexed by `i32`
2-
--> $DIR/index-help.rs:3:5
2+
--> $DIR/index-help.rs:3:7
33
|
44
LL | x[0i32];
5-
| ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
5+
| ^^^^ slice indices are of type `usize` or ranges of `usize`
66
|
77
= help: the trait `SliceIndex<[{integer}]>` is not implemented for `i32`
88
= help: the trait `SliceIndex<[T]>` is implemented for `usize`

src/test/ui/indexing-requires-a-uint.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the type `[{integer}]` cannot be indexed by `u8`
2-
--> $DIR/indexing-requires-a-uint.rs:6:5
2+
--> $DIR/indexing-requires-a-uint.rs:6:9
33
|
44
LL | [0][0u8];
5-
| ^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
5+
| ^^^ slice indices are of type `usize` or ranges of `usize`
66
|
77
= help: the trait `SliceIndex<[{integer}]>` is not implemented for `u8`
88
= help: the trait `SliceIndex<[T]>` is implemented for `usize`

src/test/ui/integral-indexing.stderr

+16-16
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,78 @@
11
error[E0277]: the type `[isize]` cannot be indexed by `u8`
2-
--> $DIR/integral-indexing.rs:6:5
2+
--> $DIR/integral-indexing.rs:6:7
33
|
44
LL | v[3u8];
5-
| ^^^^^^ slice indices are of type `usize` or ranges of `usize`
5+
| ^^^ slice indices are of type `usize` or ranges of `usize`
66
|
77
= help: the trait `SliceIndex<[isize]>` is not implemented for `u8`
88
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
99
= note: required because of the requirements on the impl of `Index<u8>` for `Vec<isize>`
1010

1111
error[E0277]: the type `[isize]` cannot be indexed by `i8`
12-
--> $DIR/integral-indexing.rs:7:5
12+
--> $DIR/integral-indexing.rs:7:7
1313
|
1414
LL | v[3i8];
15-
| ^^^^^^ slice indices are of type `usize` or ranges of `usize`
15+
| ^^^ slice indices are of type `usize` or ranges of `usize`
1616
|
1717
= help: the trait `SliceIndex<[isize]>` is not implemented for `i8`
1818
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
1919
= note: required because of the requirements on the impl of `Index<i8>` for `Vec<isize>`
2020

2121
error[E0277]: the type `[isize]` cannot be indexed by `u32`
22-
--> $DIR/integral-indexing.rs:8:5
22+
--> $DIR/integral-indexing.rs:8:7
2323
|
2424
LL | v[3u32];
25-
| ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
25+
| ^^^^ slice indices are of type `usize` or ranges of `usize`
2626
|
2727
= help: the trait `SliceIndex<[isize]>` is not implemented for `u32`
2828
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
2929
= note: required because of the requirements on the impl of `Index<u32>` for `Vec<isize>`
3030

3131
error[E0277]: the type `[isize]` cannot be indexed by `i32`
32-
--> $DIR/integral-indexing.rs:9:5
32+
--> $DIR/integral-indexing.rs:9:7
3333
|
3434
LL | v[3i32];
35-
| ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
35+
| ^^^^ slice indices are of type `usize` or ranges of `usize`
3636
|
3737
= help: the trait `SliceIndex<[isize]>` is not implemented for `i32`
3838
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
3939
= note: required because of the requirements on the impl of `Index<i32>` for `Vec<isize>`
4040

4141
error[E0277]: the type `[u8]` cannot be indexed by `u8`
42-
--> $DIR/integral-indexing.rs:12:5
42+
--> $DIR/integral-indexing.rs:12:18
4343
|
4444
LL | s.as_bytes()[3u8];
45-
| ^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
45+
| ^^^ slice indices are of type `usize` or ranges of `usize`
4646
|
4747
= help: the trait `SliceIndex<[u8]>` is not implemented for `u8`
4848
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
4949
= note: required because of the requirements on the impl of `Index<u8>` for `[u8]`
5050

5151
error[E0277]: the type `[u8]` cannot be indexed by `i8`
52-
--> $DIR/integral-indexing.rs:13:5
52+
--> $DIR/integral-indexing.rs:13:18
5353
|
5454
LL | s.as_bytes()[3i8];
55-
| ^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
55+
| ^^^ slice indices are of type `usize` or ranges of `usize`
5656
|
5757
= help: the trait `SliceIndex<[u8]>` is not implemented for `i8`
5858
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
5959
= note: required because of the requirements on the impl of `Index<i8>` for `[u8]`
6060

6161
error[E0277]: the type `[u8]` cannot be indexed by `u32`
62-
--> $DIR/integral-indexing.rs:14:5
62+
--> $DIR/integral-indexing.rs:14:18
6363
|
6464
LL | s.as_bytes()[3u32];
65-
| ^^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
65+
| ^^^^ slice indices are of type `usize` or ranges of `usize`
6666
|
6767
= help: the trait `SliceIndex<[u8]>` is not implemented for `u32`
6868
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
6969
= note: required because of the requirements on the impl of `Index<u32>` for `[u8]`
7070

7171
error[E0277]: the type `[u8]` cannot be indexed by `i32`
72-
--> $DIR/integral-indexing.rs:15:5
72+
--> $DIR/integral-indexing.rs:15:18
7373
|
7474
LL | s.as_bytes()[3i32];
75-
| ^^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
75+
| ^^^^ slice indices are of type `usize` or ranges of `usize`
7676
|
7777
= help: the trait `SliceIndex<[u8]>` is not implemented for `i32`
7878
= help: the trait `SliceIndex<[T]>` is implemented for `usize`

src/test/ui/on-unimplemented/slice-index.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
error[E0277]: the type `[i32]` cannot be indexed by `i32`
2-
--> $DIR/slice-index.rs:8:5
2+
--> $DIR/slice-index.rs:8:7
33
|
44
LL | x[1i32];
5-
| ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
5+
| ^^^^ slice indices are of type `usize` or ranges of `usize`
66
|
77
= help: the trait `SliceIndex<[i32]>` is not implemented for `i32`
88
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
99
= note: required because of the requirements on the impl of `Index<i32>` for `[i32]`
1010

1111
error[E0277]: the type `[i32]` cannot be indexed by `RangeTo<i32>`
12-
--> $DIR/slice-index.rs:9:5
12+
--> $DIR/slice-index.rs:9:7
1313
|
1414
LL | x[..1i32];
15-
| ^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
15+
| ^^^^^^ slice indices are of type `usize` or ranges of `usize`
1616
|
1717
= help: the trait `SliceIndex<[i32]>` is not implemented for `RangeTo<i32>`
1818
= help: the following other types implement trait `SliceIndex<T>`:

src/test/ui/str/str-idx.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the type `str` cannot be indexed by `{integer}`
2-
--> $DIR/str-idx.rs:3:17
2+
--> $DIR/str-idx.rs:3:19
33
|
44
LL | let _: u8 = s[4];
5-
| ^^^^ string indices are ranges of `usize`
5+
| ^ string indices are ranges of `usize`
66
|
77
= help: the trait `SliceIndex<str>` is not implemented for `{integer}`
88
= 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:
4747
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::<impl str>::get_unchecked`
4848

4949
error[E0277]: the type `str` cannot be indexed by `char`
50-
--> $DIR/str-idx.rs:6:17
50+
--> $DIR/str-idx.rs:6:19
5151
|
5252
LL | let _: u8 = s['c'];
53-
| ^^^^^^ string indices are ranges of `usize`
53+
| ^^^ string indices are ranges of `usize`
5454
|
5555
= help: the trait `SliceIndex<str>` is not implemented for `char`
5656
= note: required because of the requirements on the impl of `Index<char>` for `str`

src/test/ui/str/str-mut-idx.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ LL | s[1..2] = bot();
2525
= note: the left-hand-side of an assignment must have a statically known size
2626

2727
error[E0277]: the type `str` cannot be indexed by `usize`
28-
--> $DIR/str-mut-idx.rs:7:5
28+
--> $DIR/str-mut-idx.rs:7:7
2929
|
3030
LL | s[1usize] = bot();
31-
| ^^^^^^^^^ string indices are ranges of `usize`
31+
| ^^^^^^ string indices are ranges of `usize`
3232
|
3333
= help: the trait `SliceIndex<str>` is not implemented for `usize`
3434
= 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>>(
7171
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::<impl str>::get_unchecked_mut`
7272

7373
error[E0277]: the type `str` cannot be indexed by `char`
74-
--> $DIR/str-mut-idx.rs:13:5
74+
--> $DIR/str-mut-idx.rs:13:7
7575
|
7676
LL | s['c'];
77-
| ^^^^^^ string indices are ranges of `usize`
77+
| ^^^ string indices are ranges of `usize`
7878
|
7979
= help: the trait `SliceIndex<str>` is not implemented for `char`
8080
= note: required because of the requirements on the impl of `Index<char>` for `str`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// run-rustfix
2+
#![allow(unused_variables)]
3+
4+
fn main() {
5+
let i: &usize = &1;
6+
let one_item_please: i32 = [1, 2, 3][*i]; //~ ERROR the type `[{integer}]` cannot be indexed by `&usize`
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// run-rustfix
2+
#![allow(unused_variables)]
3+
4+
fn main() {
5+
let i: &usize = &1;
6+
let one_item_please: i32 = [1, 2, 3][i]; //~ ERROR the type `[{integer}]` cannot be indexed by `&usize`
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0277]: the type `[{integer}]` cannot be indexed by `&usize`
2+
--> $DIR/suggest-dereferencing-index.rs:6:42
3+
|
4+
LL | let one_item_please: i32 = [1, 2, 3][i];
5+
| ^ slice indices are of type `usize` or ranges of `usize`
6+
|
7+
= help: the trait `SliceIndex<[{integer}]>` is not implemented for `&usize`
8+
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
9+
= note: required because of the requirements on the impl of `Index<&usize>` for `[{integer}]`
10+
help: dereference this index
11+
|
12+
LL | let one_item_please: i32 = [1, 2, 3][*i];
13+
| +
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)