about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-04-08 21:32:36 +0000
committerMichael Goulet <michael@errs.io>2023-04-08 21:32:55 +0000
commitfbc3457d3582c44882ed20c5b11c6ba589163ab1 (patch)
treebf532c812e370500820cb9089a982d8b89fa26fa
parentdd2b19539ea4d62a150cf13d45942e58b6b44e54 (diff)
downloadrust-fbc3457d3582c44882ed20c5b11c6ba589163ab1.tar.gz
rust-fbc3457d3582c44882ed20c5b11c6ba589163ab1.zip
Tweak tuple indexing suggestion
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs29
-rw-r--r--tests/ui/index_message.rs4
-rw-r--r--tests/ui/index_message.stderr2
-rw-r--r--tests/ui/issues/issue-27842.rs5
-rw-r--r--tests/ui/issues/issue-27842.stderr12
5 files changed, 35 insertions, 17 deletions
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`.