Search code examples
rust

What is the exact type of b-like defined values in Rust?


I am considering the definition:

let x = b"qwe";

In many sources they say that the type is &[u8] but if I try to check it with std::any::TypeId, it fails.

fn f<T: std::any::Any>(x: T) {
    println!(
        "{}", 
        std::any::TypeId::of::<T>() == std::any::TypeId::of::<&[u8]>()
    );
}

f(b"qwe");  // prints `false` so the type of b"qwe" is not &[u8]
f(b"qwe" as &[u8]);  // prints `true` so b"qwe" can be natively converted into &[u8]

So what is the exact type of b"qwe"?


Solution

  • You can check what is the type of the variable, by causing a compilation error, when you assign value to variable with different type. For example, we know that type of x is definitely not (). Therefore following code fails to compile:

    fn main() {
        let x: () = b"foo";
    }
    

    with the following error:

       Compiling playground v0.0.1 (/playground)
    error[E0308]: mismatched types
     --> src/main.rs:2:17
      |
    2 |     let x: () = b"foo";
      |            --   ^^^^^^ expected `()`, found `&[u8; 3]`
      |            |
      |            expected due to this
    
    For more information about this error, try `rustc --explain E0308`.
    error: could not compile `playground` (bin "playground") due to 1 previous error
    

    The compiler is telling you, that it expects an unit, but you tried to assign a &[u8; 3], which is a reference to a 3-element u8-array.

    Note, that it can be automatically coerced into &[u8]. The following code works:

    fn main() {
        let x: &[u8] = b"foo";
    }