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

string-lit-as-bytes suggests an expression of a different type #4933

Closed
gendx opened this issue Dec 21, 2019 · 1 comment
Closed

string-lit-as-bytes suggests an expression of a different type #4933

gendx opened this issue Dec 21, 2019 · 1 comment

Comments

@gendx
Copy link
Contributor

gendx commented Dec 21, 2019

The string-lit-as-bytes lint suggests to replace "string literat".as_bytes() by a b"byte literal". However, these two expressions don't have the same type (&[u8] vs. &'static [u8; N]). In particular, some traits like std::io::BufRead are only implemented for the unsized slice, but not for the slice of known size.

I encountered this in the context of gendx/lzma-rs#23 (Clippy's lint: https://travis-ci.org/gendx/lzma-rs/jobs/628177518, Suggestion applied: https://travis-ci.org/gendx/lzma-rs/jobs/628178891).

Following is a reduced case where the suggestion causes a compilation error.

fn foo<R: std::io::BufRead>(_input: &mut R) {
    unimplemented!()
}

pub fn bar() {
    foo(&mut "".as_bytes()); // Clippy lints against this.
}

pub fn abc() {
    foo(&mut b""); // Clippy's suggestion.
}

Compilation error:

error[E0277]: the trait bound `&'static [u8; 0]: std::io::BufRead` is not satisfied
  --> src/lib.rs:10:9
   |
1  | fn foo<R: std::io::BufRead>(_input: &mut R) {
   |    ---    ---------------- required by this bound in `foo`
...
10 |     foo(&mut b"");
   |         ^^^^^^^^ the trait `std::io::BufRead` is not implemented for `&'static [u8; 0]`
   |
   = help: the following implementations were found:
             <&[u8] as std::io::BufRead>

It's not too hard to fix (&mut (b"" as &[u8])), and it seems a bit of a niche case to have the suggestion always cast to as &[u8], but I haven't seen this in the "known problems" for the lint. I also wonder how hard it would be for Clippy to detect when the as &[u8] conversion is needed.

Ultimately, const generics (rust-lang/rust#44580) should allow to implement traits in stdlib for all slice lengths - and/or hopefully make &[u8; N] -> &[u8] conversions automatic - but in the meantime this is still a possible issue with the lint.

@flip1995
Copy link
Member

Duplicate of #4494

@flip1995 flip1995 marked this as a duplicate of #4494 Dec 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants