Skip to content

Instantly share code, notes, and snippets.

@l0calh05t
Created April 26, 2020 08:16
Show Gist options
  • Save l0calh05t/b56b39cd9594e1e3e813c8ab9026f0df to your computer and use it in GitHub Desktop.
Save l0calh05t/b56b39cd9594e1e3e813c8ab9026f0df to your computer and use it in GitHub Desktop.
Rust generic op trait pains
use std::ops::Mul;
pub struct Foo<T>(T, T);
// Either of the following traits can be implemented individually, but both together cause an infinite recursion.
// If both traits are limited to a single type T it works fine.
impl<L, R, O> Mul<&Foo<R>> for &Foo<L>
where
for<'l, 'r> &'l L: Mul<&'r R, Output = O>,
{
type Output = Foo<O>;
fn mul(self, other: &Foo<R>) -> Foo<O> {
Foo(&self.0 * &other.0, &self.1 * &other.1)
}
}
impl<T> Mul<&T> for &Foo<T>
where
for<'l, 'r> &'l T: Mul<&'r T, Output = T>,
{
type Output = Foo<T>;
fn mul(self, other: &T) -> Foo<T> {
Foo(&self.0 * other, &self.1 * other)
}
}
use std::ops::Mul;
pub struct Foo<T>(T, T);
// ok
impl<T> Mul<&T> for &Foo<T>
where
for<'l, 'r> &'l T: Mul<&'r T, Output = T>,
{
type Output = Foo<T>;
fn mul(self, other: &T) -> Foo<T> {
Foo(&self.0 * other, &self.1 * other)
}
}
// causes error E0210 with the somewhat misleading hint
// "type parameter `T` must be used as the type parameter for some local type"
impl<T> Mul<&Foo<T>> for &T
where
for<'l, 'r> &'l T: Mul<&'r T, Output = T>,
{
type Output = Foo<T>;
fn mul(self, other: &Foo<T>) -> Foo<T> {
Foo(self * &other.0, self * &other.1)
}
}
// impl for a concrete foreign type causes no issues...
/*impl Mul<&Foo<f32>> for &f32 {
type Output = Foo<f32>;
fn mul(self, other: &Foo<f32>) -> Foo<f32> {
Foo(self * &other.0, self * &other.1)
}
}*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment