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/a.mbt:

pub(all) type A Int
pub(open) trait B {
  to_int(Self) -> Int
}

a/moon.pkg.json:

{}

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

b/moon.pkg.json:

{
  "import": [
    "username/hello/a"
  ]
}

b/b.mbt:

impl @a.B for @a.A with to_int(self : @a.A) -> Int {
  //                    ^~~~~~
  // Error: Cannot define method to_int of trait @a.B from package a for type @a.A from package a
  self._
}

MoonBit will report an error.

Suggestion#

You can move either the trait or type into the current package where the implementation is in. If that is not possible, you can create a new type over the type you wish to implement the trait for, and then implement the trait for the new type:

b/b.mbt:

type WrapA @a.A

impl @a.B for WrapA with to_int(self : WrapA) -> Int {
  ...
}