E4062

E4062#

impl 会遮盖先前定义的方法。这将导致当前包内部和外部的特征实现不同。

在 MoonBit 中,你可以通过定义某个类型的所有方法来隐式实现该特征。例如,如果你有如下特征:

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

然后,对于类型 Point,你可以像这样实现特征:

struct Point {
  x : Int
  y : Int
}

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

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

然而,由于你可以使用 impl 明确地为某个类型实现一个特征,当这两个实现具有不同的可见性时,这可能会导致不一致的行为。

错误示例#

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._
}

如果这些代码能够通过编译,那么对于在另一个包中定义的函数:

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

输出将是 A::f。但是,如果 probe 函数定义在 a 包中:

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

这个输出将会是 impl T for A with f

建议#

要修复此错误,您需要确保特征的隐式实现(A::f)和显式实现(impl)具有相同的可见性。

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