E4062

E4062#

This impl shadows method previously defined. This will result in different implementations for trait inside and outside current package.

In MoonBit, you can implicitly implement a trait for a type by defining all the methods in that trait. For example, if you have trait like this:

trait Coordinated { // use pub(open) when you want to implement it outside current package.
  x(Self) -> Int
  y(Self) -> Int
}

Then, for a type Point, you can implement the trait like this:

struct Point {
  x : Int
  y : Int
}

fn x(self : Point) -> Int {
  self.x
}

fn y(self : Point) -> Int {
  self.y
}

However, as you can implement a trait for a type explicitly with impl, this may leads to inconsistent behavior when these two implementation have different visibility.

错误示例#

For example, in package a:

pub(open) trait T {
  f(Self) -> Int
}

pub type A Int

pub fn A::f(self : A) -> Int {
  println("A::f")
  self._
}

impl T for A with f(self : A) -> Int {
  //              ^
  // Error: This `impl` shadows method f of A previously defined at ...
  //        This will result in different implementations for T inside and outside current package.
  println("impl T for A with f")
  self._
}

If these code were able to pass compilation, then for the function defined in another package:

fn probe[T : @a.T](t : T) -> Unit {
  ignore(t.f())
}

The output will be A::f. However, if the probe function is defined in the package a:

fn probe[T : T](t : T) -> Unit {
  ignore(t.f())
}

The output will be impl T for A with f.

建议#

To fix this error, you need to make sure both the implicitly (A::f) and explicitly implementation (impl) of the trait have the same visibility.

// ...
pub impl T for A with f(self : A) -> Int {
  println("impl T for A with f")
  self._
}