about summary refs log tree commit diff
path: root/tests/ui/indexing
diff options
context:
space:
mode:
authorNilstrieb <48135649+Nilstrieb@users.noreply.github.com>2023-08-03 21:43:17 +0200
committerNilstrieb <48135649+Nilstrieb@users.noreply.github.com>2023-08-04 13:17:39 +0200
commit5706be1854db74d0aafcc4658423884689f139e9 (patch)
tree5e4a3543de6a955d72ece8459d3e3353a05cc906 /tests/ui/indexing
parentfcf3006e0133365ecd26894689c086387edcbecb (diff)
downloadrust-5706be1854db74d0aafcc4658423884689f139e9.tar.gz
rust-5706be1854db74d0aafcc4658423884689f139e9.zip
Improve spans for indexing expressions
Indexing is similar to method calls in having an arbitrary
left-hand-side and then something on the right, which is the main part
of the expression. Method calls already have a span for that right part,
but indexing does not. This means that long method chains that use
indexing have really bad spans, especially when the indexing panics and
that span in coverted into a panic location.

This does the same thing as method calls for the AST and HIR, storing an
extra span which is then put into the `fn_span` field in THIR.
Diffstat (limited to 'tests/ui/indexing')
-rw-r--r--tests/ui/indexing/index-bot.rs3
-rw-r--r--tests/ui/indexing/index-bot.stderr9
-rw-r--r--tests/ui/indexing/index-help.rs4
-rw-r--r--tests/ui/indexing/index-help.stderr13
-rw-r--r--tests/ui/indexing/index_message.rs4
-rw-r--r--tests/ui/indexing/index_message.stderr9
-rw-r--r--tests/ui/indexing/indexing-requires-a-uint.rs14
-rw-r--r--tests/ui/indexing/indexing-requires-a-uint.stderr32
-rw-r--r--tests/ui/indexing/indexing-spans-caller-location.rs27
9 files changed, 115 insertions, 0 deletions
diff --git a/tests/ui/indexing/index-bot.rs b/tests/ui/indexing/index-bot.rs
new file mode 100644
index 00000000000..e69c4019f61
--- /dev/null
+++ b/tests/ui/indexing/index-bot.rs
@@ -0,0 +1,3 @@
+fn main() {
+    (return)[0]; //~ ERROR cannot index into a value of type `!`
+}
diff --git a/tests/ui/indexing/index-bot.stderr b/tests/ui/indexing/index-bot.stderr
new file mode 100644
index 00000000000..bf231c92cad
--- /dev/null
+++ b/tests/ui/indexing/index-bot.stderr
@@ -0,0 +1,9 @@
+error[E0608]: cannot index into a value of type `!`
+  --> $DIR/index-bot.rs:2:13
+   |
+LL |     (return)[0];
+   |             ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0608`.
diff --git a/tests/ui/indexing/index-help.rs b/tests/ui/indexing/index-help.rs
new file mode 100644
index 00000000000..66571ec41a0
--- /dev/null
+++ b/tests/ui/indexing/index-help.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let x = vec![1];
+    x[0i32]; //~ ERROR E0277
+}
diff --git a/tests/ui/indexing/index-help.stderr b/tests/ui/indexing/index-help.stderr
new file mode 100644
index 00000000000..e020d029875
--- /dev/null
+++ b/tests/ui/indexing/index-help.stderr
@@ -0,0 +1,13 @@
+error[E0277]: the type `[{integer}]` cannot be indexed by `i32`
+  --> $DIR/index-help.rs:3:7
+   |
+LL |     x[0i32];
+   |       ^^^^ 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`
+   = note: required for `Vec<{integer}>` to implement `Index<i32>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/indexing/index_message.rs b/tests/ui/indexing/index_message.rs
new file mode 100644
index 00000000000..88b848d6f85
--- /dev/null
+++ b/tests/ui/indexing/index_message.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let z = (10,);
+    let _ = z[0]; //~ ERROR cannot index into a value of type `({integer},)`
+}
diff --git a/tests/ui/indexing/index_message.stderr b/tests/ui/indexing/index_message.stderr
new file mode 100644
index 00000000000..80f2bd52314
--- /dev/null
+++ b/tests/ui/indexing/index_message.stderr
@@ -0,0 +1,9 @@
+error[E0608]: cannot index into a value of type `({integer},)`
+  --> $DIR/index_message.rs:3:14
+   |
+LL |     let _ = z[0];
+   |              ^^^ help: to access tuple elements, use: `.0`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0608`.
diff --git a/tests/ui/indexing/indexing-requires-a-uint.rs b/tests/ui/indexing/indexing-requires-a-uint.rs
new file mode 100644
index 00000000000..dbe9b44a138
--- /dev/null
+++ b/tests/ui/indexing/indexing-requires-a-uint.rs
@@ -0,0 +1,14 @@
+// Make sure that indexing an array is only valid with a `usize`, not any other
+// integral type.
+
+fn main() {
+    fn bar<T>(_: T) {}
+    [0][0u8]; //~ ERROR: the type `[{integer}]` cannot be indexed by `u8`
+
+    [0][0]; // should infer to be a usize
+
+    let i = 0;      // i is an IntVar
+    [0][i];         // i should be locked to usize
+    bar::<isize>(i);  // i should not be re-coerced back to an isize
+    //~^ ERROR: mismatched types
+}
diff --git a/tests/ui/indexing/indexing-requires-a-uint.stderr b/tests/ui/indexing/indexing-requires-a-uint.stderr
new file mode 100644
index 00000000000..7a741cfc7de
--- /dev/null
+++ b/tests/ui/indexing/indexing-requires-a-uint.stderr
@@ -0,0 +1,32 @@
+error[E0277]: the type `[{integer}]` cannot be indexed by `u8`
+  --> $DIR/indexing-requires-a-uint.rs:6:9
+   |
+LL |     [0][0u8];
+   |         ^^^ 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`
+   = note: required for `[{integer}]` to implement `Index<u8>`
+
+error[E0308]: mismatched types
+  --> $DIR/indexing-requires-a-uint.rs:12:18
+   |
+LL |     bar::<isize>(i);  // i should not be re-coerced back to an isize
+   |     ------------ ^ expected `isize`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/indexing-requires-a-uint.rs:5:8
+   |
+LL |     fn bar<T>(_: T) {}
+   |        ^^^    ----
+help: you can convert a `usize` to an `isize` and panic if the converted value doesn't fit
+   |
+LL |     bar::<isize>(i.try_into().unwrap());  // i should not be re-coerced back to an isize
+   |                   ++++++++++++++++++++
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/indexing/indexing-spans-caller-location.rs b/tests/ui/indexing/indexing-spans-caller-location.rs
new file mode 100644
index 00000000000..2652f00211d
--- /dev/null
+++ b/tests/ui/indexing/indexing-spans-caller-location.rs
@@ -0,0 +1,27 @@
+// run-pass
+
+// Regression test for https://github.com/rust-lang/rust/issues/114388
+
+#[track_caller]
+fn caller_line() -> u32 {
+    std::panic::Location::caller().line()
+}
+
+fn main() {
+    let prev_line = caller_line(); // first line
+    (A { prev_line }) // second line
+    [0]; // third line
+}
+
+struct A {
+    prev_line: u32,
+}
+impl std::ops::Index<usize> for A {
+    type Output = ();
+
+    fn index(&self, _idx: usize) -> &() {
+        // Use the relative number to make it resistent to header changes.
+        assert_eq!(caller_line(), self.prev_line + 2);
+        &()
+    }
+}