3 ms·
> You can't have Foo<N> * Foo<M> -> Foo<N+M> or similar. You can though, unless I totally misunderstand your syntax use std::{marker::PhantomData, ops::{A
by duped 2y ago
> You can't have Foo<N> * Foo<M> -> Foo<N+M> or similar.
You can though, unless I totally misunderstand your syntax
use std::{marker::PhantomData, ops::{Add, Mul}};
pub struct Foo<T> {
_p: PhantomData<T>,
}
impl<N, M> Mul<Foo<M>> for Foo<N>
where
N: Add<M>
{
type Output = Foo<<N as Add<M>>::Output>;
fn mul(self, rhs: Foo<M>) -> Self::Output {
todo!()
}
}
- ynik 2y agoYou misunderstood. N, M are supposed to be integers (const generics); in your example code you've made them types. Also, your `type Output = Foo<<N as Add<M>>::Output>;` just means "multiplication has the same return type as addition". But desired is that multiplying a Foo<4> with a Foo<3> results in a Foo<7>. Rust decided that it's important to not have instantiation-time compiler errors, but this makes computation with const generics complicated: you're not allowed to write Foo<{N+M}> because N+M might overflow, even if it never actually overflows for the generic arguments used in the program.
- quotemstr 2y agoInstantiation time errors unlock so much metaprogramming potential that Rust is going to be forced to allow them sooner or later.
- Ar-Curunir 2y agoI believe this kind of stuff is being worked on.
- duped 2y agoaiui this isn't inherently limited by instantiation-time error messages and is available on nightly today with the generic_const_exprs feature. It's in the pipeline.
- deleted 2y ago[deleted]