Type error [M0139], inner actor classes are not supported yet

Recently I’ve faced with an error

type error [M0139], inner actor classes are not supported yet; any actor class must come last in your program

If I understand the description correctly, you can only go 1 level deep when importing actors. Meaning you can not import other actors in an actor that is being imported? Is that correct?

In my case, I am only accessing imported actor’s type on the level 2.

What are the limitations for this? Are there any plans to allow it in the future (at least the ability to access actor’s type without being able to instantiate it)?

No, this should work provided each actor class is in a separate file, imported from its dependents.

You can not have any recursion though, and each class increases the size of the final binary significantly.

If you can share an example that doesn’t work I can hopefully fix it.

To clarify: Recursion is not permitted. (I think Claudio meant “cannot have” in place of “can have”)

If you can share an example that doesn’t work I can hopefully fix it.

Yes, especially if you have trouble resolving mutual recursion among separate files. There may be another way to structure the definitions to resolve it.

I have actor A that imports actor B and actor C

At the same time actor B imports actor C

As I understood it is is not permitted currently. Correct?

I am discussing with @skilesare how I can share an example.

Right - sorry about that. I have a nasty habit of omitting the crucial word sometimes.

That should actually be ok. A cut down example of your code might help. Easier would be to construct it in the Motoko playground and “share” a link.

The actor class example is close to what you were describing originally.

@claudio Austin should share the repo with you soon, so you can take a look.

Motoko Playground - DFINITY is an example you can play with.

(I took the Map example and add a second actor class, Classes.Class)

Thanks. The repo https://github.com/ORIGYN-SA/events/tree/feat/PRD-11-distributed-events-processing was shared with you. Would be great if you could take a look when you have time.

@claudio I’ve found what caused the problem

the line let Types = MigrationTypes.Types; which I moved inside actor class declaration

I think the error message was a bit misleading

However I’ve ran into another one right after that

Stderr:
Ill-typed intermediate code after Async Lowering (use -v to see dumped IR):
/home/zhenya/Documents/events/src/actors/Main/modules/init.mo:119.11-119.73: IR type error [M0000], subtype violation:
  (BroadcastIdsResponse__44 -> (), Error -> ()) -> {#schedule : () -> (); #suspend}
  (() -> (), Error -> ()) -> {#schedule : () -> (); #suspend}

Raised at Ir_def__Check_ir.error.(fun) in file "ir_def/check_ir.ml", line 95, characters 30-92
Called from Ir_def__Check_ir.check_exp.(<:) in file "ir_def/check_ir.ml" (inlined), line 367, characters 19-45
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 697, characters 4-17
Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 391, characters 4-32
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 706, characters 4-22
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 778, characters 4-40
Called from Ir_def__Check_ir.check_dec in file "ir_def/check_ir.ml", line 1086, characters 4-21
Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 695, characters 4-22
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 778, characters 4-40
Called from Ir_def__Check_ir.check_dec in file "ir_def/check_ir.ml", line 1086, characters 4-21
Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 695, characters 4-22
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 778, characters 4-40
Called from Ir_def__Check_ir.check_dec in file "ir_def/check_ir.ml", line 1086, characters 4-21
Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 695, characters 4-22
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 778, characters 4-40
Called from Ir_def__Check_ir.check_dec in file "ir_def/check_ir.ml", line 1086, characters 4-21
Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 695, characters 4-22
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 778, characters 4-40
Called from Ir_def__Check_ir.check_dec in file "ir_def/check_ir.ml", line 1086, characters 4-21
Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 695, characters 4-22
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 778, characters 4-40
Called from Ir_def__Check_ir.check_dec in file "ir_def/check_ir.ml", line 1086, characters 4-21
Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 695, characters 4-22
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 746, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 778, characters 4-40
Called from Ir_def__Check_ir.check_dec in file "ir_def/check_ir.ml", line 1086, characters 4-21
Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 695, characters 4-22
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 778, characters 4-40
Called from Ir_def__Check_ir.check_dec in file "ir_def/check_ir.ml", line 1086, characters 4-21
Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 695, characters 4-22
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 778, characters 4-40
Called from Ir_def__Check_ir.check_dec in file "ir_def/check_ir.ml", line 1086, characters 4-21
Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 695, characters 4-22
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 778, characters 4-40
Called from Ir_def__Check_ir.check_dec in file "ir_def/check_ir.ml", line 1086, characters 4-21
Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 695, characters 4-22
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 778, characters 4-40
Called from Ir_def__Check_ir.check_dec in file "ir_def/check_ir.ml", line 1086, characters 4-21
Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 695, characters 4-22
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 746, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 746, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 746, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 746, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 746, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 746, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 746, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 746, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 746, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 746, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 746, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 778, characters 4-40
Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 391, characters 4-32
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 778, characters 4-40
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 778, characters 4-40
Called from Ir_def__Check_ir.check_dec in file "ir_def/check_ir.ml", line 1086, characters 4-21
Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 695, characters 4-22
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_dec in file "ir_def/check_ir.ml", line 1086, characters 4-21
Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15
Called from Ir_def__Check_ir.check_comp_unit in file "ir_def/check_ir.ml", line 1148, characters 4-23
Called from Ir_def__Check_ir.check_prog in file "ir_def/check_ir.ml", line 1167, characters 6-28

Ouch, that’s not good.

Is there a branch of the repo I can use to reproduce this?

And which version of moc or dfx are you using?

I think the error message was a bit misleading

Indeed. I’ll file an issue.

2 Likes

Here is a link to the branch

I am using moc 7.5

Yeah, I found it.

Does the bug disappear if you define:

actors/SubscribersStore/interface.mo

module {
  public type SubscribersStore = actor {
    addBroadcastIds: shared (params: Config.BroadcastIdsParams) -> async Config.BroadcastIdsResponse;
...
module {
  public type SubscribersStore = actor {
    addBroadcastIds: shared (params: Config.BroadcastIdsParams) -> async ();
    ...

I expect the problem is to do with the special case that the response type is (), but hidden under a type definition.

Ok, I think I’ve got a small reproducible:

Might take a while to fix. Can you avoid it by just inlining the () instead of using the type abbreviation for now?

1 Like

Claudio, thanks for investigation and quick response! Will inline it as a temporary solution.

@claudio I’ve found another one

Stderr:
Ill-typed intermediate code after Async Lowering (use -v to see dumped IR):
(unknown location): IR type error [M0000], subtype violation:
  (() -> (), Error -> ())
  (None -> (), Error -> ())

Raised at Ir_def__Check_ir.error.(fun) in file "ir_def/check_ir.ml", line 95, characters 30-92
Called from Ir_def__Check_ir.check_exp.(<:) in file "ir_def/check_ir.ml" (inlined), line 367, characters 19-45
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 403, characters 10-27
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 706, characters 4-22
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 696, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 746, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 746, characters 4-23
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 778, characters 4-40
Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 391, characters 4-32
Called from Ir_def__Check_ir.check_exp in file "ir_def/check_ir.ml", line 778, characters 4-40
Called from Ir_def__Check_ir.check_dec in file "ir_def/check_ir.ml", line 1086, characters 4-21
Called from Stdlib__list.iter in file "list.ml", line 110, characters 12-15
Called from Ir_def__Check_ir.check_comp_unit in file "ir_def/check_ir.ml", line 1148, characters 4-23
Called from Ir_def__Check_ir.check_prog in file "ir_def/check_ir.ml", line 1167, characters 6-28

Reproduction code

import Debug "mo:base/Debug";

shared (deployer) actor class Test() {
  public shared (context) func test(): async () {
    await async {
      Debug.trap("");
    };
  };
};
1 Like

Ohoh. Will investigate.