Problem with impl specialization of generic traits


#1

Hi, Rust newby here. I’m currently struggling with specialized impls of a generic trait:

use std::num;

trait Sample : num::NumCast {}
impl Sample for i16 {}
impl Sample for f32 {}

trait SampleConvert<T> where Self:Sample, T:Sample
{
    fn from(x:T) -> Self;
}

impl SampleConvert<i16> for f32
{
    fn from(x:i16) -> f32 { x as f32 * 3.0517578125e-5f32 }
}

impl SampleConvert<f32> for i16
{
    fn from(x:f32) -> i16 { (x * 32767f32) as i16 }
}

fn convert<T,U> (x:T) -> U where T:Sample,U:Sample
{
    SampleConvert::from(x)
}

fn main() {
    let y:f32 = convert(1i16);
}

fails to compile with

error: the trait `SampleConvert<T>` is not implemented for the type `U` [E0277]

which kind of makes sense because I provided only one impl for some particular types T,U.
However, I’m now unsure how make the compiler happy. For example, I tried adding a generic “dummy” impl

impl<S,T> SampleConvert<T> for S where S:Sample, T:Sample
{
    fn from(x:T) -> Self { num::cast(x).unwrap() }
}

which resulted in a new error

error: conflicting implementations for trait `SampleConvert` [E0119]

Any ideas how to solve this?


#2

The compiler is right, you have to ask for a SampleConvert bound to use SampleConvert. I think this should do it: where U: SampleConvert<T>


#3

That works and makes totally sense! Thanks a lot!