bug: codegen crash with `await` at top-level
In a pair-programming session with @kentosugama we stumbled upon this backend bug:
func foo() : async Nat {
return await async 4;
};
assert (await foo()) == 4;
The crash stack looks like
Motoko (source 0.7.3-41-g4aea75428)
Fatal error: exception "Assert_failure codegen/compile.ml:6902:11"
Raised at Codegen__Compile.Internals.call_prelude_function in file "codegen/compile.ml", line 6902, characters 11-23
Called from Codegen__Compile.Internals.add_cycles in file "codegen/compile.ml" (inlined), line 6904, characters 26-68
Called from Codegen__Compile.compile_exp in file "codegen/compile.ml", line 9272, characters 21-48
Called from Codegen__Compile.compile_exp_as in file "codegen/compile.ml", line 9314, characters 24-44
Called from Codegen__Compile.compile_exp.go in file "codegen/compile.ml", line 9238, characters 30-61
Called from Codegen__Compile.compile_exp.go in file "codegen/compile.ml", line 9239, characters 17-28
Called from Codegen__Compile.compile_exp in file "codegen/compile.ml", line 9241, characters 18-27
Called from Codegen__Compile.compile_exp in file "codegen/compile.ml", line 9206, characters 22-45
Called from Codegen__Compile.compile_exp in file "codegen/compile.ml", line 9206, characters 22-45
Called from Codegen__Compile.compile_exp in file "codegen/compile.ml", line 9206, characters 22-45
Called from Codegen__Compile.compile_exp in file "codegen/compile.ml", line 9206, characters 22-45
<lot of this>
Called from Codegen__Compile.compile_exp in file "codegen/compile.ml", line 9246, characters 19-40
Called from Codegen__Compile.compile_exp in file "codegen/compile.ml", line 9246, characters 19-40
Called from Codegen__Compile.compile_exp_as_opt in file "codegen/compile.ml", line 9323, characters 20-40
Called from Codegen__Compile.compile_dec.(fun) in file "codegen/compile.ml", line 9594, characters 29-59
Called from Codegen__Compile.compile_dec.(fun) in file "codegen/compile.ml", line 9574, characters 29-41
Called from Codegen__Compile.compile_decs_public.go.(fun) in file "codegen/compile.ml", line 9635, characters 44-62
Called from Codegen__Compile.compile_decs_public.(fun) in file "codegen/compile.ml", line 9638, characters 39-61
Called from Codegen__Compile.Func.of_body in file "codegen/compile.ml", line 769, characters 6-18
Called from CamlinternalLazy.force_lazy_block in file "camlinternalLazy.ml", line 31, characters 17-27
Re-raised at CamlinternalLazy.force_lazy_block in file "camlinternalLazy.ml", line 36, characters 4-11
Called from Lib.AllocOnUse.use in file "lib/lib.ml", line 527, characters 13-28
Called from Codegen__Compile.IC.export_init.(fun) in file "codegen/compile.ml", line 3881, characters 20-43
Called from Codegen__Compile.Func.of_body in file "codegen/compile.ml", line 769, characters 6-18
Called from Codegen__Compile.IC.export_init in file "codegen/compile.ml", line 3878, characters 18-228
Called from Codegen__Compile.compile in file "codegen/compile.ml", line 9994, characters 6-24
Called from Pipeline.compile_files in file "pipeline/pipeline.ml", line 708, characters 19-56
Called from Diag.bind in file "lang_utils/diag.ml", line 32, characters 27-30
Called from Diag.bind in file "lang_utils/diag.ml", line 32, characters 27-30
Called from Dune__exe__Moc.process_files in file "exes/moc.ml", line 211, characters 49-94
Called from Dune__exe__Moc in file "exes/moc.ml", line 306, characters 4-23
This could be the top-level await that is not supported.
This is
(* Calling well-known prelude functions *)
(* FIXME: calling into the prelude will not work if we ever need to compile a program
that requires top-level cps conversion;
use new prims instead *)
module Internals = struct
let call_prelude_function env ae var =
match VarEnv.lookup_var ae var with
| Some (VarEnv.Const (_, Const.Fun (mk_fi, _))) ->
compile_unboxed_zero ^^ (* A dummy closure *)
G.i (Call (nr (mk_fi ())))
| _ -> assert false
let add_cycles env ae = call_prelude_function env ae "@add_cycles"
let reset_cycles env ae = call_prelude_function env ae "@reset_cycles"
let reset_refund env ae = call_prelude_function env ae "@reset_refund"
end
Are you compiling for IC or for wasmtime?
For the IC. I just suggested Kento to make that test part of an actor.
Maybe we could emit a check_ir error message if async effect occurs at top-level.
Making this low priority.
Well, it should probably be caught by the type checker. Shouldn't it give a capability error (or whatever the name of our implicit type parameters for await contexts are)?
Odd, but the code should be enclose in an actor so I wonder if this due to the old hack of allowing top-level decs for the body of an implicit actor. That should be forbidden for compiled code I think
Was that the main file or a library?
It was a test file in run-drun