japaric / cast.rs

Machine scalar casting that meets your expectations
Apache License 2.0
73 stars 14 forks source link

Nightly no u8 -> u16 conversion #46

Open mobergmann opened 3 months ago

mobergmann commented 3 months ago

I am compiling an embedded program for the Arduino, requiring the rust nightly version. It seems, that this crate cannot convert u8 to u16 on the nightly version.

[nix-shell:~/Source/Bachelorarbeit/Code/experiments]$ cargo --version
cargo 1.79.0-nightly (d438c80c4 2024-03-19)

[nix-shell:~/Source/Bachelorarbeit/Code/experiments]$ rustc --version
rustc 1.79.0-nightly (0ad927c0c 2024-03-21)

My code, basically the example from the readme with all necessary steps for the embedded code.

#![no_std]
#![no_main]

extern crate cast;

use panic_halt as _;

// `u8` and `u16` are checked cast functions, use them to cast from any numeric
// primitive to `u8`/`u16` respectively
use cast::u16;

#[arduino_hal::entry]
fn main() -> ! {    
    loop {
        // cast with `as`
        assert_eq!(u16(0u8), 0u16);
    }
}

Compilation error:

   Compiling experiments v0.1.0 (/home/mobergmann/Source/Bachelorarbeit/Code/experiments)
error[E0277]: the trait bound `u16: cast::From<u8>` is not satisfied
   --> src/main.rs:16:24
    |
16  |         assert_eq!(u16(0u8), 0u16);
    |                    --- ^^^ the trait `cast::From<u8>` is not implemented for `u16`
    |                    |
    |                    required by a bound introduced by this call
    |
    = help: the following other types implement trait `cast::From<Src>`:
              <u16 as cast::From<i128>>
              <u16 as cast::From<u128>>
note: required by a bound in `u16`
   --> /home/mobergmann/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cast-0.3.0/src/lib.rs:172:1
    |
172 | fns!(f32, f64, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^^^^^^^^^^^^^^^^^^
    | |                                            |
    | |                                            required by a bound in this function
    | required by this bound in `u16`
    = note: this error originates in the macro `fns` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `u16: cast::From<u8>` is not satisfied
  --> src/main.rs:16:20
   |
16 |         assert_eq!(u16(0u8), 0u16);
   |                    ^^^^^^^^ the trait `cast::From<u8>` is not implemented for `u16`
   |
   = help: the following other types implement trait `cast::From<Src>`:
             <u16 as cast::From<i128>>
             <u16 as cast::From<u128>>

For more information about this error, try `rustc --explain E0277`.
error: could not compile `experiments` (bin "experiments") due to 2 previous errors

I believe the error is appropriate in this repo. If i am wrong, please inform me.

d2weber commented 1 month ago

I believe this is not a matter of compiling with nightly, rather that you're compiling for a target with "target-pointer-width": "16". At least that was the reason why I got the error.

The reason is that the necessary traits are only implemented for 32 bit and 64 bit, see here https://github.com/japaric/cast.rs/blob/052288097de1846b938e854e27845a93a6f4b59d/src/lib.rs#L354-L468

You might want to implement the 16 bit equivalent. I just opted not using this crate but plain old conversions usize::from(..) or u16::try_from(..).unwrap()