Skip to content

Suggest &string[6..11] for str::from_utf8(string.as_bytes()[6..11]).unwrap() #5487

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

Closed
Luro02 opened this issue Apr 19, 2020 · 4 comments · Fixed by #6134
Closed

Suggest &string[6..11] for str::from_utf8(string.as_bytes()[6..11]).unwrap() #5487

Luro02 opened this issue Apr 19, 2020 · 4 comments · Fixed by #6134
Labels
A-lint Area: New lints good-first-issue These issues are a good way to get started with Clippy L-complexity Lint: Belongs in the complexity lint group L-suggestion Lint: Improving, adding or fixing lint suggestions

Comments

@Luro02
Copy link

Luro02 commented Apr 19, 2020

This

use std::str;

let string = "Hello World!";
assert_eq!(str::from_utf8(string.as_bytes()[6..11]).unwrap(), "World");

could be written as

let string = "Hello World!";
assert_eq!(&string[6..11], "World");
@flip1995 flip1995 added L-complexity Lint: Belongs in the complexity lint group L-suggestion Lint: Improving, adding or fixing lint suggestions good-first-issue These issues are a good way to get started with Clippy A-lint Area: New lints labels Apr 19, 2020
@l0calh05t
Copy link

l0calh05t commented Apr 24, 2020

assert_eq!(str::from_utf8(string.as_bytes()[6..11]).unwrap(), "World");

should be

assert_eq!(str::from_utf8(&string.as_bytes()[6..11]).unwrap(), "World");

@illicitonion
Copy link
Contributor

illicitonion commented May 9, 2020

I believe these are only equivalent if string is only made of single-byte characters. Counter-example:

let string = "🐈ello World!";
assert_eq!(::std::str::from_utf8(&string.as_bytes()[6..11]).unwrap(), "World");

^^ This assert fails

@Luro02
Copy link
Author

Luro02 commented May 10, 2020

Well of course your example fails. Neither string[6..11] nor ::std::str::from_utf8(&string.as_bytes()[6..11]).unwrap() are equal to "World".

The indexing works with bytes and not chars, which is why your example is not working as expected, because the emoji ("🐈".len()) is 4 bytes in length.

For example

let string = "🐈ello World!";

dbg!(&string[1..11]);

will fail with

thread 'main' panicked at 'byte index 1 is not a char boundary; it is inside '🐈' (bytes 0..4) of `🐈ello World!`', src/libcore/str/mod.rs:2219:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

This is your example working correctly:

use std::str;

fn main() {
    let string = "🐈ello World!";

    assert_eq!(&string[6..11], "lo Wo");

    assert_eq!(
        str::from_utf8(&string.as_bytes()[6..11]).unwrap(),
        &string[6..11]
    );
}

playground

The above code succeeds, which means that str::from_utf8(&string.as_bytes()[6..11]).unwrap() and &string[6..11] are equal, so the lint is also valid for utf8 strings.

@illicitonion
Copy link
Contributor

Well of course your example fails. Neither string[6..11] nor ::std::str::from_utf8(&string.as_bytes()[6..11]).unwrap() are equal to "World".

The indexing works with bytes and not chars, which is why your example is not working as expected, because the emoji ("🐈".len()) is 4 bytes in length.

Apologies, of course you're right - for some reason I was thinking slicing strings worked on chars and as you've shown I put together a really poor example to try to show that! Thanks for taking the time to make a better one which shows the truth :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: New lints good-first-issue These issues are a good way to get started with Clippy L-complexity Lint: Belongs in the complexity lint group L-suggestion Lint: Improving, adding or fixing lint suggestions
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants