E4061

E4061#

Cannot implement a trait for a type when both are defined in other packages.

MoonBit follows the orphan rule, which means that you can only:

Traits

Types

Allowed?

Current Package

Current Package

Yes

Other Package

Current Package

Yes

Current Package

Other Package

Yes

Other Package

Other Package

No

See the Access control of methods and trait implementations section of the MoonBit documentation for more information.

Erroneous example#

Suppose you have type A and trait B defined in package a in module username/hello:

a/top.mbt:

///|
pub(all) struct A(Int)

///|
pub(open) trait B {
  to_int(Self) -> Int
}

a/moon.pkg:


Now, if you want to implement trait @a.B for type @a.A:

b/moon.pkg:

import {
  "username/hello/a",
}

b/top.mbt:

///|
impl @a.B for @a.A with to_int(self : @a.A) -> Int {
  self.0
}

MoonBit will report an error.

Suggestion#

You can move either the trait or the type into the package that contains the implementation. If that is not possible, create a wrapper type around the type you wish to implement the trait for, and then implement the trait for the wrapper type:

b/top.mbt:

///|
priv struct WrapA(@a.A)

///|
impl @a.B for WrapA with to_int(self : WrapA) -> Int {
  let _ = self.0
  0
}

///|
test {
  let value = WrapA(@a.A(1))
  inspect(value.to_int(), content="0")
}