Apologies if this falls under "help" more than an IRLO discussion, but this is weird enough people have suggested filing a bug and I wanted to see if anyone could explain what's happening before I do that.
The following example doesn't work:
use core::ops::Mul;
// Don't touch this
pub trait Group:
Sized
+ Mul<Self::Scalar, Output = Self>
+ for<'a> Mul<&'a Self::Scalar, Output = Self>
{
type Scalar;
}
// Make changes to anything below
pub trait Curve {
type Scalar;
type Field;
}
pub struct Point<C: Curve> {
x: C::Field,
y: C::Field
}
impl<C: Curve> Group for Point<C> {
type Scalar = C::Scalar;
}
impl<C: Curve> Mul<C::Scalar> for Point<C> {
type Output = Self;
fn mul(self, other: C::Scalar) > Self {
unimplemented!()
}
}
impl<C: Curve> Mul<&C::Scalar> for Point<C> {
type Output = Self;
fn mul(self, other: &C::Scalar) > Self {
unimplemented!()
}
}
It fails to typecheck with the following error:
error[E0119]: conflicting implementations of trait `std::ops::Mul<&_>` for type `Point<_>`
> src/lib.rs:37:1

29  impl<C: Curve> Mul<C::Scalar> for Point<C> {
  first implementation here
...
37  impl<C: Curve> Mul<&C::Scalar> for Point<C> {
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Point<_>`
...but if instead of C::Scalar
I use a concrete type like a struct
, the Mul
impls do not conflict.
The error seems to suggest that an associated type could be its own reference type? I'm quite confused by it. I know that generic parameters of traits are a weird corner case in the orphan rules, but I can't figure out what's happening here.
If I remove the second Mul
impl, it quickly becomes clear these two types are distinct:
error[E0271]: type mismatch resolving `for<'a> <C as Curve>::Scalar == &'a <C as Curve>::Scalar`
> src/lib.rs:25:16

25  impl<C: Curve> Group for Point<C> {
 ^^^^^ expected associated type, found reference

= note: expected associated type `<C as Curve>::Scalar`
found reference `&'a <C as Curve>::Scalar`
= help: consider constraining the associated type `<C as Curve>::Scalar` to `&'a <C as Curve>::Scalar`
= note: for more information, visit https://doc.rustlang.org/book/ch1903advancedtraits.html
Is the original error about overlapping Mul
definitions a bug, or expected behavior for some reason?