Skip to content

Commit 5cdda98

Browse files
authored
feat: parenthetical syntax for message sends (cycles, timeout etc.) (#4608)
This PR introduces new syntax (parenthetical notes, or simply _parentheticals_) for `async`-valued calls and `async` self-sends. Two attributes are recognised therein: `cycles : Nat` and `timeout : Nat32`. The type-checker enforces these types (when attributes present) and warns on unknown ones. Having a `timeout` attribute present will make the message send a bounded-wait one (also called best-effort) according to the new replica semantics. Specifying `cycles` works like the (soon to be deprecated) `Cycles.add<system>`, ~but one has to decide which to use (either `Cycles.add` or a parenthetical) since there is no mix-and-match~. ----------- ~`ICCallPrim` (and friends) should carry the fragment to set the `SystemCyclesAddPrim` while the call is being set up towards the replica.~ This now happens in the desugarer by assigning to variables (`@cycles` and `@timeout`). Parentheticals - now: `(with cycles = 42_000_000) Actor.call(param)` - also now: `(with timeout = 10)` `ic0.call_with_best_effort_response : (timeout_seconds : i32) -> ()` - maybe: `(with receiveMax = 50_000)` (to limit the response size) - maybe: `(with resend = { tries = 5; delay = 3 })` when `SYS_UNKNOWN` reject response (like [Unix `EINTR`](https://unix.stackexchange.com/questions/253349/what-is-the-rationale-behind-eintr), but saves cycles by not re-encoding the arguments) - support dfinity/ic#1158 - usecase `(with memoryLimit = 1G) ActorClass(<args>)` - default/suppress call-meta-attributes: `func() : async () = (with) async { ... }` — document this! TODOs: - [x] `Changelog.md` - [x] documentation - [x] test one-ways - typecheck - [x] warn when an attribute is moot - [x] `cycles : Nat` for canister sends (_self_ and _raw_ sends too) - [x] `timeout : Nat32` for best-effort - [x] parenthetical should have no send cap (test still missing) - [x] `async` blocks - [x] `ICCallPrim`, see top - `ICCallRawPrim`, not directly annotatable (desisting for now, but see #4868) - [ ] `FIXME`s, `TODO`s - [x] `ICCallPrim` should have a non-`option` setup - [ ] break out unrelated PRs (optimisations?) and beautifications — see #4890 - [ ] warn on queries? - [x] best-effort: new error code when deadline passed? - [x] doc/md/base/Error.md -> `motoko-base`, see dfinity/motoko-base#686 - [x] visit all `git grep system_fatal` and amend `#system_unknown` - [x] decide whether `(with cycles) async` or `async (with cycles)` — decided: keep as prefix! - [x] write a temporary test that `Cycles.add` still works - [x] test that parenthetical have no send capability - [x] test `(with cycles) (func () -> async () {})()` direct application - [x] test `(with cycles) (system Lib.Class)(...)()` - [x] test error on `async*` (and call)
1 parent 3c59a0e commit 5cdda98

File tree

89 files changed

+1192
-317
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+1192
-317
lines changed

Changelog.md

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,25 @@
11
# Motoko compiler changelog
22

3+
## 0.14.2 (FUTURE)
4+
35
* motoko (`moc`)
46

5-
* bugfix: `mo-doc` will now generate documentation for `actor`s and `actor class`es (#4905).
7+
* Added support for sending `cycles` and setting a `timeout` in parentheticals.
8+
This is an **experimental feature**, with new syntax, and now also allowing best-effort
9+
message sends. The legacy call `Cycles.add<system>` is still supported (#4608).
10+
11+
For example, if one wants to attach cycles to a message send, prefix it with a parenthetical
12+
``` motoko
13+
(with cycles = 5_000) Coins.mine(forMe);
14+
```
15+
Similarly a timeout for _best-effort_ execution (also called _bounded-wait_) can be specified like
16+
``` motoko
17+
let worker = (with timeout = 15) async { /* worker loop */ };
18+
```
19+
A common base for fields optionally goes before the `with` and can be customised with both fields
20+
after it. Please consult the documentation for more usage information.
621
22+
* bugfix: `mo-doc` will now generate documentation for `actor`s and `actor class`es (#4905).
723
824
## 0.14.1 (2025-02-13)
925
@@ -22,7 +38,7 @@
2238
Additional static checks warn against possible data loss (#4812).
2339
2440
As a very simple example:
25-
```
41+
``` motoko
2642
import Nat32 "mo:base/Nat32";
2743
2844
(with migration =

doc/md/canister-maintenance/cycles.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@ In Motoko programs deployed on ICP, each actor represents a canister and has an
1313

1414
Callees can accept all, some, or none of the available cycles up to limit determined by their actor’s current balance. Any remaining cycles are refunded to the caller. If a call traps, all its accompanying cycles are automatically refunded to the caller without loss.
1515

16-
In future, we may see Motoko adopt dedicated syntax and types to support safer programming with cycles. For now, we provide a temporary way to manage cycles through a low-level imperative API provided by the [ExperimentalCycles](../base/ExperimentalCycles.md) library in package `base`.
16+
Motoko is adopting dedicated syntax and types to support safer programming with cycles. Users can now attach `(where cycles = <amount>)` as a prefix to message sends and async expressions.
17+
This new syntax will eventually obsolete the use of `ExperimentalCycles.add<system>(cycles)` in the examples that follow.
18+
19+
For now (and until officially deprecating it), we provide a temporary way to manage cycles through a low-level imperative API provided by the [ExperimentalCycles](../base/ExperimentalCycles.md) library in package `base`.
1720

1821
:::note
1922

20-
This library is subject to change and likely to be replaced by more high-level support for cycles in later versions of Motoko.
23+
This library is subject to change and likely to be replaced by more high-level support for cycles in later versions of Motoko. See [Async data](../writing-motoko/async-data.md) for further usage information about parentheticals (such as attaching cycles) on message sends.
2124

2225
:::
2326

doc/md/examples/PiggyBank.mo

+1-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ shared(msg) persistent actor class PiggyBank(
2929
: async () {
3030
assert (msg.caller == owner);
3131
assert (amount <= savings);
32-
Cycles.add<system>(amount);
33-
await benefit();
32+
await (with cyles = amount) benefit();
3433
let refund = Cycles.refunded();
3534
savings -= amount - refund;
3635
};

doc/md/examples/grammar.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@
188188

189189
<exp_un> ::=
190190
<exp_post>
191+
<parenthetical> <exp_post> <inst> <exp_nullary>
191192
'#' <id>
192193
'#' <id> <exp_nullary>
193194
'?' <exp_un>
@@ -213,7 +214,7 @@
213214
<exp_bin> ':=' <exp>
214215
<exp_bin> <binassign> <exp>
215216
'return' <exp>?
216-
'async' <exp_nest>
217+
<parenthetical>? 'async' <exp_nest>
217218
'async*' <exp_nest>
218219
'await' <exp_nest>
219220
'await*' <exp_nest>

doc/md/reference/language-manual.md

+15-5
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ The syntax of an expression is as follows:
507507
[ var? <exp>,* ] Array
508508
<exp> [ <exp> ] Array indexing
509509
<shared-pat>? func <func_exp> Function expression
510-
<exp> <typ-args>? <exp> Function call
510+
<parenthetical>? <exp> <typ-args>? <exp> Function call
511511
not <exp> Negation
512512
<exp> and <exp> Conjunction
513513
<exp> or <exp> Disjunction
@@ -520,7 +520,7 @@ The syntax of an expression is as follows:
520520
break <id> <exp>? Break
521521
continue <id> Continue
522522
return <exp>? Return
523-
async <block-or-exp> Async expression
523+
<parenthetical>? async <block-or-exp> Async expression
524524
await <block-or-exp> Await future (only in async)
525525
async* <block-or-exp> Delay an asynchronous computation
526526
await* <block-or-exp> Await a delayed computation (only in async)
@@ -746,6 +746,8 @@ type ErrorCode = {
746746
#system_fatal;
747747
// Transient error.
748748
#system_transient;
749+
// Response unknown due to missed deadline.
750+
#system_unknown;
749751
// Destination invalid.
750752
#destination_invalid;
751753
// Explicit reject by canister code.
@@ -2188,7 +2190,7 @@ Otherwise,
21882190

21892191
### Function calls
21902192

2191-
The function call expression `<exp1> <T0,…​,Tn>? <exp2>` has type `T` provided:
2193+
The function call expression `<parenthetical>? <exp1> <T0,…​,Tn>? <exp2>` has type `T` provided:
21922194

21932195
- The function `<exp1>` has function type `<shared>? < X0 <: V0, ..., Xn <: Vn > U1-> U2`.
21942196

@@ -2206,6 +2208,10 @@ Otherwise, `exp2` is evaluated to a result `r2`. If `r2` is `trap`, the expressi
22062208

22072209
Otherwise, `r1` is a function value, `<shared-pat>? func <X0 <: V0, …​, n <: Vn> <pat1> { <exp> }` (for some implicit environment), and `r2` is a value `v2`. If `<shared-pat>` is present and of the form `shared <query>? <pat>` then evaluation continues by matching the record value `{caller = p}` against `<pat>`, where `p` is the [`Principal`](../base/Principal.md) invoking the function, typically a user or canister. Matching continues by matching `v1` against `<pat1>`. If pattern matching succeeds with some bindings, then evaluation returns the result of `<exp>` in the environment of the function value not shown extended with those bindings. Otherwise, some pattern match has failed and the call results in `trap`.
22082210

2211+
A `<parenthetical>`, when present, modifies dynamic attributes of the message send (provided that the return type `T` is of form `async U`, i.e. a future). The recognized attributes are
2212+
- `cycles : Nat` to attach cycles
2213+
- `timeout : Nat32` to introduce a timeout for best-effort message execution.
2214+
22092215
:::note
22102216

22112217
The exhaustiveness side condition on `shared` function expressions ensures that argument pattern matching cannot fail (see [functions](#functions)).
@@ -2478,7 +2484,7 @@ The `return` expression exits the corresponding dynamic function invocation or c
24782484

24792485
### Async
24802486

2481-
The async expression `async <block-or-exp>` has type `async T` provided:
2487+
The async expression `<parenthetical>? async <block-or-exp>` has type `async T` provided:
24822488

24832489
- `<block-or-exp>` has type `T`.
24842490

@@ -2490,6 +2496,10 @@ The implicit return type in `<block-or-exp>` is `T`. That is, the return express
24902496

24912497
Evaluation of `async <block-or-exp>` queues a message to evaluate `<block-or-exp>` in the nearest enclosing or top-level actor. It immediately returns a future of type `async T` that can be used to `await` the result of the pending evaluation of `<exp>`.
24922498

2499+
The presence of `<parenthetical>` modifies the semantics of the async expression to
2500+
- attach cycles with attribute `cycles : Nat`
2501+
- impose a timeout (observed when awaiting the result) with attribute `timeout : Nat32`.
2502+
24932503
:::note
24942504

24952505
Because it involves messaging, evaluating an `async` expression can fail due to a lack of canister resources.
@@ -2788,4 +2798,4 @@ In general, this means that an expression of a more specific type may appear whe
27882798
- **IEEE Standard for Floating-Point Arithmetic**, in IEEE Std 754-2019 (Revision of IEEE 754-2008), vol., no., pp.1-84, 22 July 2019, doi: 10.1109/IEEESTD.2019.8766229.
27892799

27902800

2791-
<img src="https://github.com/user-attachments/assets/844ca364-4d71-42b3-aaec-4a6c3509ee2e" alt="Logo" width="150" height="150" />
2801+
<img src="https://github.com/user-attachments/assets/844ca364-4d71-42b3-aaec-4a6c3509ee2e" alt="Logo" width="150" height="150" />

doc/md/writing-motoko/async-data.md

+22-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ Like several other languages, Motoko offers `async` and `await` to support conve
1414
In Motoko, executing an asynchronous expression, whether a call to a shared function, or just a local `async` expression, produces a future, an object of type `async T`, for some result type `T`.
1515
Instead of blocking the caller until the call has returned, the message is enqueued on the callee and the future representing that pending request is immediately returned to the caller. The future is a placeholder for the eventual result of the request that the caller can later query.
1616

17+
Every operation resulting in a future (i.e. sends to other `actor`s/canisters or self sends with `async` or by function calls) can be prefixed by a _parenthetical_ of the form `(base with attr₁ = v₁; attr₂ = v₂; …)` where `base` is an optional record containing (e.g. default) attributes. Accepted attributes are currently `cycles : Nat`, specifying the amount of cycles to be sent along with the message, and `timeout : Nat32` to modify the deadline and restrict the time span while the receiver can reply.
18+
1719
The syntax `await` synchronizes on a future, and suspends computation until the future is completed by its producer.
1820

1921
Between issuing the request and deciding to wait for the result, the caller is free to do other work. Once the callee has processed the request, the future is completed and its result made available to the caller. If the caller is waiting on the future, its execution can resume with the result, otherwise the result is simply stored in the future for later use.
@@ -37,7 +39,6 @@ The `Counter` actor declares one field and three public, shared functions:
3739

3840
- Function `bump()` asynchronously increments and reads the counter.
3941

40-
4142
The only way to read or modify the state (`count`) of the `Counter` actor is through its shared functions.
4243

4344
## Using `await` to consume async futures
@@ -69,6 +70,25 @@ Unlike a local function call, which blocks the caller until the callee has retur
6970

7071
Awaiting a future a second time will just produce the same result, including re-throwing any error stored in the future. Suspension occurs even if the future is already complete; this ensures state changes and message sends prior to every `await` are committed.
7172

73+
## Using parentheticals to modify message send modalities
74+
75+
In the above examples all messages sent to the `Counter` actor do not transmit cycles and will never timeout when their results are awaited. Both of these
76+
aspects can be configured by syntactically adding a parenthetical and thus modifying the dynamic attributes of the message send.
77+
78+
To add cycles to the send one would write
79+
``` motoko no-repl
80+
let a = (with cycles = 42_000_000) Counter.bump();
81+
```
82+
Similarly, one can specify an explicit timeout to apply when awaiting the result of the message. This is useful in applications that prefer best-effort over guaranteed response message delivery:
83+
``` motoko no-repl
84+
let a = (with timeout = 25) Counter.bump();
85+
```
86+
Custom defaults for these attributes can be defined in a record that is used as the base expression of a parenthetical:
87+
``` motoko no-repl
88+
let boundedWait = { timeout = 25 };
89+
let a = (boundedWait with cycles = 42_000_000) Counter.bump();
90+
```
91+
7292
:::danger
7393

7494
A function that does not `await` in its body is guaranteed to execute atomically. In particular, the environment cannot change the state of the actor while the function is executing. If a function performs an `await`, however, atomicity is no longer guaranteed. Between suspension and resumption around the `await`, the state of the enclosing actor may change due to concurrent processing of other incoming actor messages. It is the programmer’s responsibility to guard against non-synchronized state changes. A programmer may, however, rely on any state change prior to the await being committed.
@@ -92,4 +112,4 @@ Each `await` suspends execution, allowing an interloper to change the state of t
92112

93113
- [`rxmo`](https://mops.one/rxmo): A library for reactive programming using observables, making it easier to compose asynchronous or callback-based code.
94114

95-
<img src="https://github.com/user-attachments/assets/844ca364-4d71-42b3-aaec-4a6c3509ee2e" alt="Logo" width="150" height="150" />
115+
<img src="https://github.com/user-attachments/assets/844ca364-4d71-42b3-aaec-4a6c3509ee2e" alt="Logo" width="150" height="150" />

src/codegen/compile_classical.ml

+18-9
Original file line numberDiff line numberDiff line change
@@ -2519,10 +2519,13 @@ module Closure = struct
25192519
Tagged.load_field env (Int32.add (header_size env) i)
25202520

25212521
let store_data env i =
2522-
let (set_closure_data, get_closure_data) = new_local env "closure_data" in
2523-
set_closure_data ^^
2524-
Tagged.load_forwarding_pointer env ^^
2525-
get_closure_data ^^
2522+
(if !Flags.gc_strategy = Flags.Incremental then
2523+
let set_closure_data, get_closure_data = new_local env "closure_data" in
2524+
set_closure_data ^^
2525+
Tagged.load_forwarding_pointer env ^^
2526+
get_closure_data
2527+
else
2528+
G.nop) ^^
25262529
Tagged.store_field env (Int32.add (header_size env) i)
25272530

25282531
let prepare_closure_call env =
@@ -5056,6 +5059,7 @@ module IC = struct
50565059
E.add_func_import env "ic0" "accept_message" [] [];
50575060
E.add_func_import env "ic0" "call_data_append" (i32s 2) [];
50585061
E.add_func_import env "ic0" "call_cycles_add128" (i64s 2) [];
5062+
E.add_func_import env "ic0" "call_with_best_effort_response" [I32Type] [];
50595063
E.add_func_import env "ic0" "call_new" (i32s 8) [];
50605064
E.add_func_import env "ic0" "call_perform" [] [I32Type];
50615065
E.add_func_import env "ic0" "call_on_cleanup" (i32s 2) [];
@@ -5417,7 +5421,8 @@ module IC = struct
54175421
"system_transient", 2l;
54185422
"destination_invalid", 3l;
54195423
"canister_reject", 4l;
5420-
"canister_error", 5l]
5424+
"canister_error", 5l;
5425+
"system_unknown", 6l]
54215426
(Variant.inject env "future" (get_code ^^ BoxedSmallWord.box env Type.Nat32)))
54225427

54235428
let error_message env =
@@ -9792,7 +9797,7 @@ module FuncDec = struct
97929797
(fun get_cb_index ->
97939798
get_cb_index ^^
97949799
BoxedSmallWord.box env Type.Nat32 ^^
9795-
Serialization.serialize env Type.[Prim Nat32])
9800+
Serialization.serialize env Type.[nat32])
97969801

97979802
let ic_call_one_shot env ts get_meth_pair get_arg add_cycles =
97989803
match E.mode env with
@@ -9860,7 +9865,7 @@ module FuncDec = struct
98609865
IC.assert_caller_self env ^^
98619866

98629867
(* Deserialize and look up continuation argument *)
9863-
Serialization.deserialize env Type.[Prim Nat32] ^^
9868+
Serialization.deserialize env Type.[nat32] ^^
98649869
BoxedSmallWord.unbox env Type.Nat32 ^^
98659870
ContinuationTable.peek_future env ^^
98669871
set_closure ^^
@@ -11308,7 +11313,7 @@ and compile_prim_invocation (env : E.t) ae p es at =
1130811313
compile_shl_const (Int32.of_int num_bits) ^^
1130911314
compile_shrS_const (Int32.of_int num_bits) ^^
1131011315
get_val ^^
11311-
compile_eq env Type.(Prim Nat32) ^^
11316+
compile_eq env Type.nat32 ^^
1131211317
E.else_trap_with env "losing precision" ^^
1131311318
get_val ^^
1131411319
compile_shl_const (Int32.of_int num_bits)
@@ -12149,6 +12154,7 @@ and compile_prim_invocation (env : E.t) ae p es at =
1214912154
compile_exp_vanilla env ae c ^^ set_c ^^
1215012155
FuncDec.ic_call env ts1 ts2 get_meth_pair get_arg get_k get_r get_c add_cycles
1215112156
end
12157+
1215212158
| ICCallRawPrim, [p;m;a;k;r;c] ->
1215312159
SR.unit, begin
1215412160
let set_meth_pair, get_meth_pair = new_local env "meth_pair" in
@@ -12207,6 +12213,9 @@ and compile_prim_invocation (env : E.t) ae p es at =
1220712213
| SystemCyclesBurnPrim, [e1] ->
1220812214
SR.Vanilla, compile_exp_vanilla env ae e1 ^^ Cycles.burn env
1220912215

12216+
| SystemTimeoutSetPrim, [e1] ->
12217+
SR.unit, compile_exp_as env ae (SR.UnboxedWord32 Type.Nat32) e1 ^^ IC.system_call env "call_with_best_effort_response"
12218+
1221012219
| SetCertifiedData, [e1] ->
1221112220
SR.unit, compile_exp_vanilla env ae e1 ^^ IC.set_certified_data env
1221212221
| GetCertificate, [] ->
@@ -12516,7 +12525,7 @@ and compile_lit_pat env l =
1251612525
| Nat32Lit _ ->
1251712526
BoxedSmallWord.unbox env Type.Nat32 ^^
1251812527
compile_lit_as env (SR.UnboxedWord32 Type.Nat32) l ^^
12519-
compile_eq env Type.(Prim Nat32)
12528+
compile_eq env Type.nat32
1252012529
| Nat64Lit _ ->
1252112530
BoxedWord64.unbox env Type.Nat64 ^^
1252212531
compile_lit_as env (SR.UnboxedWord64 Type.Nat64) l ^^

src/codegen/compile_enhanced.ml

+14-4
Original file line numberDiff line numberDiff line change
@@ -4716,6 +4716,7 @@ module IC = struct
47164716
E.add_func_import env "ic0" "accept_message" [] [];
47174717
E.add_func_import env "ic0" "call_data_append" (i64s 2) [];
47184718
E.add_func_import env "ic0" "call_cycles_add128" (i64s 2) [];
4719+
E.add_func_import env "ic0" "call_with_best_effort_response" [I32Type] [];
47194720
E.add_func_import env "ic0" "call_new" (i64s 8) [];
47204721
E.add_func_import env "ic0" "call_perform" [] [I32Type];
47214722
E.add_func_import env "ic0" "call_on_cleanup" (i64s 2) [];
@@ -5145,7 +5146,8 @@ module IC = struct
51455146
"system_transient", 2L;
51465147
"destination_invalid", 3L;
51475148
"canister_reject", 4L;
5148-
"canister_error", 5L]
5149+
"canister_error", 5L;
5150+
"system_unknown", 6L]
51495151
(Variant.inject env "future" (get_code ^^ BitTagged.tag env Type.Nat32)))
51505152

51515153
let error_message env =
@@ -9639,7 +9641,7 @@ module FuncDec = struct
96399641
(fun get_cb_index ->
96409642
get_cb_index ^^
96419643
TaggedSmallWord.msb_adjust Type.Nat32 ^^
9642-
Serialization.serialize env Type.[Prim Nat32])
9644+
Serialization.serialize env Type.[nat32])
96439645

96449646
let ic_call_one_shot env ts get_meth_pair get_arg add_cycles =
96459647
match E.mode env with
@@ -9708,7 +9710,7 @@ module FuncDec = struct
97089710
IC.assert_caller_self env ^^
97099711

97109712
(* Deserialize and look up continuation argument *)
9711-
Serialization.deserialize env Type.[Prim Nat32] ^^
9713+
Serialization.deserialize env Type.[nat32] ^^
97129714
TaggedSmallWord.lsb_adjust Type.Nat32 ^^
97139715
ContinuationTable.peek_future env ^^
97149716
set_closure ^^
@@ -12274,6 +12276,7 @@ and compile_prim_invocation (env : E.t) ae p es at =
1227412276
compile_exp_vanilla env ae c ^^ set_c ^^
1227512277
FuncDec.ic_call env ts1 ts2 get_meth_pair get_arg get_k get_r get_c add_cycles
1227612278
end
12279+
1227712280
| ICCallRawPrim, [p;m;a;k;r;c] ->
1227812281
SR.unit, begin
1227912282
let set_meth_pair, get_meth_pair = new_local env "meth_pair" in
@@ -12320,6 +12323,13 @@ and compile_prim_invocation (env : E.t) ae p es at =
1232012323
| SystemCyclesBurnPrim, [e1] ->
1232112324
SR.Vanilla, compile_exp_vanilla env ae e1 ^^ Cycles.burn env
1232212325

12326+
| SystemTimeoutSetPrim, [e1] ->
12327+
SR.unit,
12328+
compile_exp_as env ae (SR.UnboxedWord64 Type.Nat32) e1 ^^
12329+
TaggedSmallWord.lsb_adjust Type.Nat32 ^^
12330+
G.i (Convert (Wasm_exts.Values.I32 I32Op.WrapI64)) ^^
12331+
IC.system_call env "call_with_best_effort_response"
12332+
1232312333
| SetCertifiedData, [e1] ->
1232412334
SR.unit, compile_exp_vanilla env ae e1 ^^ IC.set_certified_data env
1232512335
| GetCertificate, [] ->
@@ -12632,7 +12642,7 @@ and compile_lit_pat env l =
1263212642
compile_eq env Type.(Prim Nat16)
1263312643
| Nat32Lit _ ->
1263412644
compile_lit_as env SR.Vanilla l ^^
12635-
compile_eq env Type.(Prim Nat32)
12645+
compile_eq env Type.nat32
1263612646
| Nat64Lit _ ->
1263712647
BoxedWord64.unbox env Type.Nat64 ^^
1263812648
compile_lit_as env (SR.UnboxedWord64 Type.Nat64) l ^^

src/ir_def/arrange_ir.ml

+2-1
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,15 @@ and prim = function
9595
| ActorOfIdBlob t -> "ActorOfIdBlob" $$ [typ t]
9696
| BlobOfIcUrl -> Atom "BlobOfIcUrl"
9797
| IcUrlOfBlob -> Atom "IcUrlOfBlob"
98-
| SelfRef t -> "SelfRef" $$ [typ t]
98+
| SelfRef t -> "SelfRef" $$ [typ t]
9999
| SystemTimePrim -> Atom "SystemTimePrim"
100100
| SystemCyclesAddPrim -> Atom "SystemCyclesAddPrim"
101101
| SystemCyclesAcceptPrim -> Atom "SystemCyclesAcceptPrim"
102102
| SystemCyclesAvailablePrim -> Atom "SystemCyclesAvailablePrim"
103103
| SystemCyclesBalancePrim -> Atom "SystemCyclesBalancePrim"
104104
| SystemCyclesRefundedPrim -> Atom "SystemCyclesRefundedPrim"
105105
| SystemCyclesBurnPrim -> Atom "SystemCyclesBurnPrim"
106+
| SystemTimeoutSetPrim -> Atom "SystemTimeoutSetPrim"
106107
| SetCertifiedData -> Atom "SetCertifiedData"
107108
| GetCertificate -> Atom "GetCertificate"
108109
| OtherPrim s -> Atom s

0 commit comments

Comments
 (0)