diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index c17aae22ba5..68e096e3bd0 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2810,23 +2810,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "cannot index into a value of type `{base_t}`", ); // Try to give some advice about indexing tuples. - if let ty::Tuple(..) = base_t.kind() { + if let ty::Tuple(types) = base_t.kind() { let mut needs_note = true; // If the index is an integer, we can show the actual // fixed expression: - if let ExprKind::Lit(ref lit) = idx.kind { - if let ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) = lit.node { - let snip = self.tcx.sess.source_map().span_to_snippet(base.span); - if let Ok(snip) = snip { - err.span_suggestion( - expr.span, - "to access tuple elements, use", - format!("{snip}.{i}"), - Applicability::MachineApplicable, - ); - needs_note = false; - } + if let ExprKind::Lit(ref lit) = idx.kind + && let ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) = lit.node + && i < types.len().try_into().expect("expected tuple index to be < usize length") + { + let snip = self.tcx.sess.source_map().span_to_snippet(base.span); + if let Ok(snip) = snip { + err.span_suggestion( + expr.span, + "to access tuple elements, use", + format!("{snip}.{i}"), + Applicability::MachineApplicable, + ); + needs_note = false; } + } else if let ExprKind::Path(..) = idx.peel_borrows().kind { + err.span_label(idx.span, "cannot access tuple elements at a variable index"); } if needs_note { err.help( diff --git a/tests/ui/index_message.rs b/tests/ui/index_message.rs index 87e0cde5919..88b848d6f85 100644 --- a/tests/ui/index_message.rs +++ b/tests/ui/index_message.rs @@ -1,4 +1,4 @@ fn main() { - let z = (); - let _ = z[0]; //~ ERROR cannot index into a value of type `()` + let z = (10,); + let _ = z[0]; //~ ERROR cannot index into a value of type `({integer},)` } diff --git a/tests/ui/index_message.stderr b/tests/ui/index_message.stderr index 6c2b126734b..56d1d70809d 100644 --- a/tests/ui/index_message.stderr +++ b/tests/ui/index_message.stderr @@ -1,4 +1,4 @@ -error[E0608]: cannot index into a value of type `()` +error[E0608]: cannot index into a value of type `({integer},)` --> $DIR/index_message.rs:3:13 | LL | let _ = z[0]; diff --git a/tests/ui/issues/issue-27842.rs b/tests/ui/issues/issue-27842.rs index 3bcfa133070..060d3b34e09 100644 --- a/tests/ui/issues/issue-27842.rs +++ b/tests/ui/issues/issue-27842.rs @@ -8,4 +8,9 @@ fn main() { let i = 0_usize; let _ = tup[i]; //~^ ERROR cannot index into a value of type + + // the case where the index is out of bounds + let tup = (10,); + let _ = tup[3]; + //~^ ERROR cannot index into a value of type } diff --git a/tests/ui/issues/issue-27842.stderr b/tests/ui/issues/issue-27842.stderr index 784666a639e..83333aa0c47 100644 --- a/tests/ui/issues/issue-27842.stderr +++ b/tests/ui/issues/issue-27842.stderr @@ -8,10 +8,20 @@ error[E0608]: cannot index into a value of type `({integer}, {integer}, {integer --> $DIR/issue-27842.rs:9:13 | LL | let _ = tup[i]; + | ^^^^-^ + | | + | cannot access tuple elements at a variable index + | + = help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`) + +error[E0608]: cannot index into a value of type `({integer},)` + --> $DIR/issue-27842.rs:14:13 + | +LL | let _ = tup[3]; | ^^^^^^ | = help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`) -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0608`.