I have a Hittable trait, with a method that returns a generic implementing Material:
pub trait Hittable {
fn hit<T>(&self -> Option<HitRecord<T>>
where T: Material;
}
And an implementation of this trait on a Sphere<T>:
impl<T> Hittable for Sphere<T>
where T: Material
{
fn hit(&self) -> Option<HitRecord<T>> {
// snip
}
I want the T in HitRecords to be the same as the T in Sphere<T>, but as of now now it will not compile because I need to annotate the hit method in the impl with a T as well. But if I do so, the 2 T’s will not be forced to be the same. How do I enforce that?
>Solution :
You should uplift the generic parameter from the method into the trait:
pub trait Hittable<T: Material> {
fn hit(&self) -> Option<HitRecord<T>>;
}
impl<T: Material> Hittable<T> for Sphere<T> {
fn hit(&self) -> Option<HitRecord<T>> {
// snip
}
}
Another way is to use an associated type (it models the situation better, but as long as you only implement the trait for one generic parameter it doesn’t practically matter):
pub trait Hittable {
type T: Material;
fn hit(&self) -> Option<HitRecord<Self::T>>;
}
impl<T: Material> Hittable for Sphere<T> {
type T = T;
fn hit(&self) -> Option<HitRecord<T>> {
// snip
}
}