Well... there’s so much more going on here than just the error message you’ve presented (actually, the error you show isn’t even one that I’m getting, AFAICT):
type_name
is for debugging purposes, so please don’t match on its results
This is intended for diagnostic use. The exact contents and format of the string returned are not specified, other than being a best-effort description of the type.
Furthermore, it is called by providing an explicit type argument, like type_name::<T>()
. If you don’t provide the argument, is will give you an error because the compiler can’t infer what it is supposed to do in any other way.
Shl
and Shr
are such that T: Shl<Output = i32>
is short for T: Shl<T, Output = i32>
, and in general A: Shl<B, Output = C>
means that you can use a: A
and b: B
in an expression a << b
whose result will be of type C
.
I don’t really know what the purpose of all the details of your function implementations is: there’s quite a few trait bounds bounds, where you check for Shl
and Shr
implementations involving i32
and i16
and also PartialEq
, even though there’s no i16
or ==
to be seen; and you also have this weird matching-on-the-type-of-T
logic going on. Furthermore, your return *value << scalefactor
combines a T
with a i32
, expecting a T
result (judging by the signature of scaleValue
), so the bound you actually need will be something like T: Shl<i32, Output = T>
, which is currently missing.
Also you require &'static T
. I would advise against using &'static
for anything but (very occasionally) the type &'static str
of string literals, in particular as long as you’re not sure about what the 'static
it does. Furthermore, going from &T
to T
by dereferencing like in *value
doesn’t even work for non-Copy
types. For Copy
types then, it is more ergonomic to just take the type by value anyways, in which case then the copying inside of scale_value
isn’t even needed anymore.
So after all this said, with some adjustments, in particular ignoring all the i16
s, your function can be written as:
use std::ops::{Shl, Shr};
pub fn scale_value<T>(value: T, scalefactor: i32) -> T
where
T: Shl<i32, Output = T> + Shr<i32, Output = T>,
{
if scalefactor > 0 {
value << scalefactor
} else {
value >> -scalefactor
}
}
fn main() {
let x: i32 = 2;
let y: i16 = 2;
let a = scale_value(x, 4);
let b = scale_value(y, 4);
// print the values
dbg!(a, b);
}