Open xplorld opened 5 years ago
The idea is that this trait is only meant to be used for true primitives, with cheap as
conversions, and perhaps for wrappers thereof. The Copy + 'static
requirement doesn't fully guarantee this, but it's a decent marker.
It would be a breaking change to remove those requirements, because other code can implicitly make use of those as supertraits of AsPrimitive
.
Can you give an example of how this causes lifetime issues for you?
I am writing a wrapper which takes a u32, as-cast it into i32, doing transformation (i32 -> i32) and as-cast it back to u32. It is like:
fn wrapper(F f) -> G where F: Fn(i32) -> i32, G: Fn(u32) -> u32
.
The problem is, I have to write many of them, including u8
, u32
, u64
. I want to write something like
fn wrapper<T, U, F>(F f) -> G where
T: Copy + AsPrimitive<U>,
U: Copy + AsPrimitive<T>,
F: Fn(T) -> T,
G: Fn(U) -> U
and of course it could not work because of the 'static
constraint.
Could you shed some light on that?
Please include the actual code and the error messages when you report a problem. The snippets you've given are not even valid Rust syntax, regardless of any type or lifetime issues.
I suspect your problem is the lifetime for f
, which you'll need to move
into the returned closure. Plus that return needs to be an anonymous type, which is perfect for impl Trait
.
This works:
pub fn wrapper<T, U, F>(f: F) -> impl Fn(U) -> U
where
T: AsPrimitive<U>,
U: AsPrimitive<T>,
F: Fn(T) -> T,
{
move |x| f(x.as_()).as_()
}
For more flexibility for the caller, consider taking and returning FnMut
instead, so it's possible to have mutable state associated with the F
closure.
pub fn wrapper<T, U, F>(mut f: F) -> impl FnMut(U) -> U
where
T: AsPrimitive<U>,
U: AsPrimitive<T>,
F: FnMut(T) -> T,
{
move |x| f(x.as_()).as_()
}
I don't see any reason. I want to cast runtime primitives in generic functions and encountered lifetime issues. If we remove the 'static I guess it still works.