Ergonomic regression in byte strings / vector borrowing?


#1

So some code that used to work broke a couple of days ago. I’m wondering if this is a. by design, b. if someone can point me to the “new rules” on this…

See here:

// Storing and looking up byte strings (e.g. for HTTP)
use std::collections::hash_map::HashMap;
fn main() {
    let b: HashMap<Vec<u8>, Vec<u8>> = HashMap::new();
    //b.contains_key(b"test");  // ERROR, Used to work fine
    //b.contains_key(&b"test");  // ERROR
    //b.contains_key(&b"test"[]);  // LEGACY WARNING
    //b.contains_key(b"test".as_slice());  // LEGACY WARNING
    b.contains_key(&b"test"[..]);  // OK?
}

#2

This is the relevant change:

commit 46f649c479ce40f3b4590590dda6c2895e8d60f6
Author:     bors <bors@rust-lang.org>
AuthorDate: Wed Mar 18 08:27:22 2015 +0000

    Auto merge of #22838 - petrochenkov:bytelit, r=alexcrichton
    
    This patch changes the type of byte string literals from `&[u8]` to `&[u8; N]`.
    It also implements some necessary traits (`IntoBytes`, `Seek`, `Read`, `BufRead`) for fixed-size arrays (also related to #21725) and adds test for #17233, which seems to be resolved.
    
    Fixes #18465
    [breaking-change]

So byte string literals are now fixed-size arrays. In lots of contexts they coerce so they end up behaving just like they did as borrowed slices before, but you have a good counterexample. Maybe someone knows if the inference/coercion is likely to improve heere?


#3

Have you tried &*b"test"? I think that should work.


#4

I should have tried that, but it (&*b"test") doesn’t work either.

b.rs:9:7: 9:30 error: *the trait `collections::borrow::Borrow<[u8; 4]>`

is not implemented for the type collections::vec::Vec<u8>* [E0277]


#5

Try &b"test"[..].