Created
April 26, 2020 08:16
-
-
Save l0calh05t/b56b39cd9594e1e3e813c8ab9026f0df to your computer and use it in GitHub Desktop.
Rust generic op trait pains
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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