Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

request: improve string indexing error message #56740

Closed
steven807 opened this issue Dec 12, 2018 · 4 comments · Fixed by #57350
Closed

request: improve string indexing error message #56740

steven807 opened this issue Dec 12, 2018 · 4 comments · Fixed by #57350
Labels
A-diagnostics Area: Messages for errors, warnings, and lints E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-help-wanted Call for participation: Help is requested to fix this issue. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@steven807
Copy link
Contributor

The following buggy code:

fn f() {
    let s = "hello";
    let c = s[0];
}

produces the error:

error[E0277]: the type `str` cannot be indexed by `{integer}`
 --> src/main.rs:3:13
  |
3 |     let c = s[0];
  |             ^^^^ `str` cannot be indexed by `{integer}`
  |
  = help: the trait `std::ops::Index<{integer}>` is not implemented for `str`

This is usefully documented in TRPL (ch08-02-strings), but that is not easily discoverable from the error. Meanwhile, the error itself is a natural one that programmers from many languages (C, C++, etc) might run into. Speaking as someone who spent some time assuming that the issue was related to slices/references/usize (i.e. various new, Rust-specific concepts), not strings and UTF-8 encoding, I wonder whether a special case might be produced, replacing error E0277, when the types involved are specifically strings/strs and integers.

Meta

rustc --version --verbose:

rustc 1.32.0-nightly (4a45578bc 2018-12-07)
binary: rustc
commit-hash: 4a45578bc58ff262864f72680cc02e83f5d2f5b3
commit-date: 2018-12-07
host: x86_64-apple-darwin
release: 1.32.0-nightly
LLVM version: 8.0
@estebank estebank added A-diagnostics Area: Messages for errors, warnings, and lints A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. labels Dec 12, 2018
@estebank
Copy link
Contributor

We should add a note pointing to https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings in the following code

#[rustc_on_unimplemented(
message="the type `{Self}` cannot be indexed by `{Idx}`",
label="`{Self}` cannot be indexed by `{Idx}`",
)]
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(alias = "]")]
#[doc(alias = "[")]
#[doc(alias = "[]")]
pub trait Index<Idx: ?Sized> {
/// The returned type after indexing.
#[stable(feature = "rust1", since = "1.0.0")]
type Output: ?Sized;
/// Performs the indexing (`container[index]`) operation.
#[stable(feature = "rust1", since = "1.0.0")]
fn index(&self, index: Idx) -> &Self::Output;
}

rustc_on_unimplemented lets you customize the output of E0277 errors. The example has a similar case to this one, but the additional code should be something along the lines of

    on(
        _Self="&str",
        note="consider reading the appropriate chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
    ),
    on(
        _Self="str",
        note="consider reading the appropriate chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
    ),
    on(
        _Self="std::string::String",
        note="consider reading the appropriate chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
    ),

This will cause an extra note to be displayed for this case.

Beyond changing the code, you will also need to add a new test case with the repro case above and update all of the tests (running ./x.py test src/test/ui --stage 1 --bless and possibly updating the test comments for any remaining failing tests).

@estebank estebank added the E-help-wanted Call for participation: Help is requested to fix this issue. label Dec 12, 2018
@jromer94
Copy link

I would like to work on this.

@estebank
Copy link
Contributor

@jromer94 do not hesitate to reach out either here or on zulip if you need help!

@estebank
Copy link
Contributor

Possible proposed output from #57055:

error[EXXXX]: cannot index `String` or string slice (`str`)
 --> main.rs:2:24
  |
  |     let _value = "test"[0];
  |                        ^^^ cannot index here
  |
  |
  = help: consider using `.chars()` or `.to_bytes()

@steveklabnik steveklabnik added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools labels Dec 27, 2018
Centril added a commit to Centril/rust that referenced this issue Jan 18, 2019
Better error note on unimplemented Index trait for string

fixes rust-lang#56740

I've tried to compile suggestion from comments in the issue rust-lang#56740, but unsure of it. So I'm open to advice :)

Current output will be like this:
```rust
error[E0277]: the type `str` cannot be indexed by `{integer}`
  --> $DIR/str-idx.rs:3:17
   |
LL |     let c: u8 = s[4]; //~ ERROR the type `str` cannot be indexed by `{integer}`
   |                 ^^^^ `str` cannot be indexed by `{integer}`
   |
   = help: the trait `std::ops::Index<{integer}>` is not implemented for `str`
   = note: you can use `.chars().nth()` or `.bytes().nth()`
           see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
```

`x.py test src/test/ui` succeeded and I've also tested output manually by compiling the following code:
```rust
fn _f() {
    let s = std::string::String::from("hello");
    let _c = s[0];

    let s = std::string::String::from("hello");
    let mut _c = s[0];

    let s = "hello";
    let _c = s[0];

    let s = "hello";
    let mut _c = &s[0];
}
```

Not sure if some docs should be changed too. I will also fix error message in the [Book :: Indexing into Strings](https://github.com/rust-lang/book/blob/db53e2e3cdf77beac853df6f29db4b3b86ea598c/src/ch08-02-strings.md#indexing-into-strings) if that PR will get approved :)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-help-wanted Call for participation: Help is requested to fix this issue. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants