dfinity / motoko

Simple high-level language for writing Internet Computer canisters
Apache License 2.0
506 stars 98 forks source link

Internal compiler error #4297

Open vporton opened 10 months ago

vporton commented 10 months ago

(I am unsure why an old version 0.9.8 is being used. I even deleted ~/.cache/dfinity and reinstalled DFX 0.15.1 anew.)

Checkout https://github.com/vporton/NacDBReorder/tree/182eac05f5249661fe65a14d86a31ccc32c1c009

Then in this repo, see log.txt. log.txt

crusso commented 10 months ago

Oh sorry, I only just saw this. Will take a look. Thanks for reporting it!

crusso commented 10 months ago

Ok, I took a look and can reproduce the error.

I narrowed it down to file

test/main.mo

import RO "../src/Reorder";
import Nac "mo:nacdb/NacDB";
import M "mo:matchers/Matchers";
import T "mo:matchers/Testable";
import Suite "mo:matchers/Suite";
import Order "mo:base/Order";
import Index "index/main";
import MyCycles "mo:nacdb/Cycles";
import GUID "mo:nacdb/GUID";
import Common "common";

let index = await Index.Index();
MyCycles.addPart(Common.dbOptions.partitionCycles);
await index.init();

func prepareOrder(orderer: RO.Orderer): async* RO.Order {
    await* RO.createOrder(GUID.nextGuid(orderer.guidGen), {orderer});
};

func main() {
    let suite = Suite.suite("Reorder test", [
        Suite.suite("Nat tests", [
            Suite.test("10 is 10", 10, M.equals(T.nat(10))),
            Suite.test("5 is greater than three", 5, M.greaterThan<Nat>(3)),
        ])
    ]);
    Suite.run(suite);
};

which isn't expressed as an explicit actor yet is accepted by the compiler. This is actually a convenience feature for our own test suites, but should only be used for code that can also appear in the body of an actor.

In this example, that isn't actually true because of the top-level awaits and we should reject the code rather than munging it into an actor.

If you change your code to something like this all is well:

import RO "../src/Reorder";
import Nac "mo:nacdb/NacDB";
import M "mo:matchers/Matchers";
import T "mo:matchers/Testable";
import Suite "mo:matchers/Suite";
import Order "mo:base/Order";
import Index "index/main";
import MyCycles "mo:nacdb/Cycles";
import GUID "mo:nacdb/GUID";
import Common "common";

actor {

  public func test() : async () {
    let index = await Index.Index();
    MyCycles.addPart(Common.dbOptions.partitionCycles);
    await index.init();

    func prepareOrder(orderer: RO.Orderer): async* RO.Order {
      await* RO.createOrder(GUID.nextGuid(orderer.guidGen), {orderer});
    };

    func main() {
      let suite = Suite.suite("Reorder test", [
        Suite.suite("Nat tests", [
        Suite.test("10 is 10", 10, M.equals(T.nat(10))),
        Suite.test("5 is greater than three", 5, M.greaterThan<Nat>(3)),
      ])
    ]);
    Suite.run(suite);
    };

    main();
  }
}

But we should obviously fix the compiler to reject your original code, or handle it better.

crusso commented 10 months ago

Minimal repro:

issue-4297.mo

await async {};
[nix-shell:~/motoko/test/run-drun]$ moc issue-4297.mo 
OOPS! You've triggered a compiler bug.
Please report this at https://github.com/dfinity/motoko/issues/new with the following details:

Motoko (source 0.10.2-8-g4346ef188)

Fatal error: exception File "codegen/compile.ml", line 8601, characters 11-17: Assertion failed
Raised at Codegen__Compile.Internals.call_prelude_function in file "codegen/compile.ml", line 8601, characters 11-23
Called from Codegen__Compile.Internals.add_cycles in file "codegen/compile.ml" (inlined), line 8603, characters 26-68
Called from Codegen__Compile.compile_exp_with_hint in file "codegen/compile.ml", line 11380, characters 21-48
Called from Codegen__Compile.compile_exp_as_opt in file "codegen/compile.ml", line 11417, characters 20-59
...
crusso commented 10 months ago

Tentative fix in #4306