I've been trying to do something along the lines of:
fn foo<T> (buffer: &[u8]) {
let foo: T = SomeTValue();
&[0..foo as usize]
}
And discovered that as won't work there and there seems to be no way to add a 'where' bound to the T type to make sure the compiler accepts "as" here knowing that it'll work because it cannot infer that T is a primitive type.
Having a trait that allows
I doubt Primitive would be specific enough for this use case since u128: Primitve, but this works:
fn foo<T: Into<usize>> (buffer: &[u8]) {
&[0..SomeTValue::<T>().into()]
}
I think the search for the ideal numeric traits arrangement is ongoing.
That certainly doesn't work as you get something like this when you try to use it on u16/u32/u64:
236 | return get_value_slice_for_size::<u64> (buffer, index);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<u64>` is not implemented for `usize`
You make a good point about about Fundamental not being enough in this particular case (f64 being prolly a better example than u128 as a 128 architecture might actually exist as a target), perhaps my particular suggestion is not a good one, but certainly there is something here that needs fixing as "as" is something the compiler accepts for all these types. At the moment I find myself doing this ugly approach to satisfy the compiler:
let lower_bound = match mem::size_of::<T> () {
1 => { <u8>::from_gvariant(buffer, lower_index) as usize }
2 => { <u16>::from_gvariant(buffer, lower_index) as usize }
4 => { <u32>::from_gvariant(buffer, lower_index) as usize }
8 => { <u64>::from_gvariant(buffer, lower_index) as usize }
_ => { panic!("pointer size bigger than 64 bit not supported"); }
};
Would TryInto<usize> work for you?
It's odd that usize: From<u8> but not From<u16> or From<u32>. We cannot have usize: From<u64> anyways due to 32 bit platforms. Anyways .try_into().expect("excessed pointer size") works.
try_into doesn't cut it either
error: use of unstable library feature 'try_from' (see issue #33417)
--> src/main.rs:3:5
|
3 | use std::convert::TryInto;
| ^^^^^^^^^^^^^^^^^^^^^
error: use of unstable library feature 'try_from' (see issue #33417)
--> src/main.rs:219:72
|
219 | let upper_bound: usize = <T>::from_gvariant(buffer, upper_index).try_into().expect("pointer size not supported");
| ^^^^^^^^
error: use of unstable library feature 'try_from' (see issue #33417)
--> src/main.rs:220:72
|
220 | let lower_bound: usize = <T>::from_gvariant(buffer, lower_index).try_into().expect("pointer size not supported");
| ^^^^^^^^
error[E0277]: the trait bound `usize: std::convert::From<u16>` is not satisfied
--> src/main.rs:231:12
|
231 | return get_value_slice_for_size::<u16> (buffer, index);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<u16>` is not implemented for `usize`
|
= help: the following implementations were found:
<usize as std::convert::From<u8>>
= note: required by `get_value_slice_for_size`
error[E0277]: the trait bound `usize: std::convert::From<u32>` is not satisfied
--> src/main.rs:234:12
|
234 | return get_value_slice_for_size::<u32> (buffer, index);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<u32>` is not implemented for `usize`
|
= help: the following implementations were found:
<usize as std::convert::From<u8>>
= note: required by `get_value_slice_for_size`
error[E0277]: the trait bound `usize: std::convert::From<u64>` is not satisfied
--> src/main.rs:237:12
|
237 | return get_value_slice_for_size::<u64> (buffer, index);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<u64>` is not implemented for `usize`
|
= help: the following implementations were found:
<usize as std::convert::From<u8>>
= note: required by `get_value_slice_for_size`
error: aborting due to 6 previous errors
You need nightly and #![feature(try_from)] ala https://play.rust-lang.org/?gist=63fecbf261f138d05af7e99e649d7508&version=nightly
Num has added a trait that fits the use case described: https://github.com/rust-num/num-traits/pull/17, if you're really looking for the as conversion operator.
I thought of something similar, here is my idea:
Permit to use the as keyword on every type that implement From<T>.
This could be like the +, -, * and *(for deref) operators for example.
The From trait is in the core so this doesn't seem to be a problem at this level.
What do you think ?
Most helpful comment
try_into doesn't cut it either