RCE language specification, draft 0.5
7. Well-formedness: what is refused at entry
This section is the checklist of rules a program must pass to be accepted
(well-formedness). Each rule has a name such as W-TY-1, and a refused
program is reported with the rule it broke. Example: a function declared
-> i64 whose body returns text is refused by W-TY-1.
A program is refused if any rule fails. Every diagnostic names its rule.
Lexical and syntax
- W-LEX-1 Not UTF-8, BOM, bare CR, or a tab character.
- W-LEX-2 Inconsistent dedent (2.6).
- W-LEX-3 A literal outside every possible type range, or an invalid
\u{}. - W-SYN-1 Not in the language of section 3.
- W-VER-1 A first-line
# rce-version:declaration naming a version other than 0.5, 0.6 or 0.7 (2.7).
Names and modules
- W-NAME-1 Unresolved name, or a name resolved in the wrong namespace.
- W-NAME-2 Duplicate declaration in one scope; shadowing a parameter, field or module-level name inside the same item.
- W-MOD-1
useof a private item; W-MOD-2 import cycle. The reference checker reports a private name reached throughuseas W-VIS-1, which is the same rule. - W-MOD-3 An imported name that clashes with a declaration of the importing module or with a name imported from another module (imported names are not renamed).
- W-SAFE-1 The identifiers
unsafe,Rc,Arc,RefCell,transmute,static: refused with "memory safety is by construction" (there are no escape hatches in RCE other than theexternboundary of 5.11). - W-FFI-1 An
externdeclaration whose ABI is not"C", that is comptime or generic, or whose parameter or result types break 5.11; or a foreign function's name used other than as the callee of a direct call.
Types
- W-TY-1 Any typing rule of section 5 fails.
- W-TY-2 Nested option
τ??; borrow of a borrow&&τ;[τ]not behind a borrow; a borrow, region type orfntype inside a data type. - W-TY-3 Integer/float mixing without
as; implicit narrowing. - W-PAT-1 A binding pattern whose name equals a variant in scope.
- W-MATCH-1 A non-exhaustive
match(5.3 [Match]); W-MATCH-2 an unreachable arm (subsumed by earlier unguarded arms). - W-PLACE Left side of an assignment or
op=is not a mutable place.
Ownership and borrowing
- W-OWN-1 Use after move (O1). W-OWN-2 Violating [No-Alias-Write] or
[No-Mut-Read]. W-OWN-3 Storing, returning (except R-RET) or capturing a
borrow. W-REG-1 A region-typed value escaping its
with arenablock. - W-SPAWN-1 Spawning with a borrow or region-typed argument.
The Form
- W-STATE-1 A
statewith no fields; W-STATE-2 a field initializer that is not a comptime constant; W-STATE-3 a field type that is not an owned data type. - W-STEP-1 A
stepnaming an undeclared region or matching an undeclared event. W-STEP-2 Totality: an event that no step and no actor handler can ever match. W-STEP-3 The arrow form on a region with more than one field. W-STEP-4 Within one region, two unguarded steps whose patterns overlap (the second is unreachable). - W-EFF-1
emit,spawn, channel operations orselectin a purefn; reading another region's fields in a step; calling a foreign function anywhere butfn mainor a task function. - W-REC-1 A cycle in the call graph, including through trait methods after
monomorphization, other than a cycle of plain functions (one function
calling itself included) whose calls are done by layered summed
measures, or each of whose cycles of calls passes through a function
declared with
bound(6.7);parorfor … parin a function of a cycle with a bounded function;boundon an iterator, a foreign function or a trait signature. - W-CT-1 Comptime code that calls a non-comptime-safe function or traps or exceeds fuel.
- W-INT-1 An
exampleorcheckthat does not hold. - W-SIMD-1 A lane-wise operator on arrays of different lengths, of an unfixed length, or with non-numeric lanes (5.1).
- W-LIN-1 A linear value not consumed exactly once on every path, copied, moved inside a loop, or placed in a collection, field, payload, channel or iterator (5.12).
- W-DEV-1 A growable value (
List,Map,Set,text, slice, channel, iterator) bound in a device region, oremit,spawn, send,select,yieldor a foreign call inside one (5.13). - W-ITER-1 An iterator function that is not pure or has an arrow body;
yieldoutside an iterator function; aniter τvalue used other than as aforoperand or.collect()receiver (5.14). - W-REF-1 A refined type (5.1) that is generic, refines a type other than
an integer type,
textor a collection, or whose predicate is outside the decidable fragment (a term other thanself,self.len()or an integer literal, an operator other than a comparison,and,or,not, or a call other than a text character class). - W-LOOP-1 A
LOOP_LIMITdeclaration that is notconst LOOP_LIMIT: u64 = nwith a positive literal n (6.7). - W-TRAIT-1 An impl not matching its trait; W-TRAIT-2 incoherent or orphan
impls; W-TRAIT-3 a type used with
==,!=, an ordering operator or a generic bound without implementing the trait it needs.
Version 0.8 only (5.16)
- W-CTX-1 Context text made other than by
C.litof a string literal orC.encode; joined with another context or plain text; carried by an event payload; an unknown context. - W-SEC-1 An operator or method on a secret other than
==/!=; a secret in an emitted value, a channel, an error payload or a foreign call. - W-CAP-1 A capability outside an event payload field or a parameter;
Guardedoutside a state field; an authority that is not a declared struct. - W-CAP-2 A step that writes a
Guarded[τ, A]field on an event without aCap[A]field. (W-NAME-2 refuses a declaration named after a 5.16 type or context.)
Version 0.6 only (Appendix C, applies only to a module declaring
# rce-version: 0.6): W-PAR-1 to W-PAR-4, W-DL-1, W-ND-1, W-GRP-1 to
W-GRP-3, W-SES-1 to W-SES-3, W-SCOPE-1, W-ATOM-1, W-ATOM-2, W-CRDT-1,
W-LVAR-1, W-LVAR-2, W-NODE-1, W-SUP-1, W-SUP-2, W-INTR-1 and W-RT-1.
Refused examples by rule
Each program below breaks the rule named above it. Run it to see the refusal, or edit it until it is accepted.
W-CT-1 (3)
Expected: refused at the admit stage by W-CT-1: line 3: W-CT-1 comptime block in `f`: trap: check failed
Expected: refused at the admit stage by W-CT-1: line 1: W-CT-1 const `BIG`: trap: overflow: 300 is outside u8
Expected: refused at the admit stage by W-CT-1: line 0: W-CT-1 state initializer: trap: overflow: 256 is outside u8
W-DEV-1 (3)
Expected: refused at the check stage by W-DEV-1: line 3: W-DEV-1 emit inside a device region
Expected: refused at the check stage by W-DEV-1: line 5: W-DEV-1 `c_tick` is a foreign function and cannot be called in a device region
Expected: refused at the check stage by W-DEV-1: line 3: W-DEV-1 a device region holds fixed-size values only, found List[u64]
W-EFF-1 (2)
Expected: refused at the check stage by W-EFF-1: line 3: W-EFF-1 `c_rand` is a foreign function: only main and task functions may call it
Expected: refused at the check stage by W-EFF-1: line 2: W-EFF-1 emit in a pure function
W-FFI-1 (3)
Expected: refused at the check stage by W-FFI-1: line 1: W-FFI-1 unknown ABI "stdcall" (only "C")
Expected: refused at the check stage by W-FFI-1: line 1: W-FFI-1 foreign parameter type List[u8] is not bool, an integer, f64, &text, &[scalar] or &mut [scalar]
Expected: refused at the check stage by W-FFI-1: line 1: W-FFI-1 foreign result type text is not bool, an integer, f64 or ()
W-INT-1 (12)
Expected: refused at the admit stage by W-INT-1: line 8: W-INT-1 check: trap: size limit
Expected: refused at the admit stage by W-INT-1: line 1: W-INT-1 check: trap: not a char boundary
Expected: refused at the admit stage by W-INT-1: line 1: W-INT-1 check: trap: non-finite float
Expected: refused at the admit stage by W-INT-1: line 2: W-INT-1 check is false
Expected: refused at the admit stage by W-INT-1: line 2: W-INT-1 example does not hold: event 1 (Go) refused: trap(division by zero)
Expected: refused at the admit stage by W-INT-1: line 9: W-INT-1 check: trap: loop bound
Expected: refused at the admit stage by W-INT-1: line 2: W-INT-1 check: trap: loop bound
Expected: refused at the admit stage by W-INT-1: line 9: W-INT-1 check: trap: loop bound
Expected: refused at the admit stage by W-INT-1: line 4: W-INT-1 check: trap: overflow: -1 is outside u64
Expected: refused at the admit stage by W-INT-1: line 2: W-INT-1 example does not hold: event 1 (Dec) refused: trap(overflow: -1 is outside u64)
Expected: refused at the admit stage by W-INT-1: line 2: W-INT-1 example does not hold: final value is 2, expected 3
Expected: refused at the admit stage by W-INT-1: line 2: W-INT-1 example does not hold: event 1 (Dec) refused: Underflow
W-ITER-1 (3)
Expected: refused at the check stage by W-ITER-1: line 1: W-ITER-1 iterator function `ticks` must be pure
Expected: refused at the check stage by W-ITER-1: line 5: W-ITER-1 an iterator may only be the operand of `for` or the receiver of `.collect()`
Expected: refused at the check stage by W-ITER-1: line 2: W-ITER-1 yield outside an iterator function
W-LEX-1 (1)
Expected: refused at the parse stage by W-LEX-1: line 2: W-LEX-1 tab character
W-LEX-2 (1)
Expected: refused at the parse stage by W-LEX-2: line 3: W-LEX-2 inconsistent dedent
W-LEX-3 (1)
Expected: refused at the check stage by W-LEX-3: line 1: W-LEX-3 literal 300 is outside u8
W-LIN-1 (6)
Expected: refused at the check stage by W-LIN-1: line 8: W-LIN-1 a linear value cannot be copied
Expected: refused at the check stage by W-LIN-1: line 4: W-LIN-1 struct field `a` cannot hold a linear value
Expected: refused at the check stage by W-LIN-1: line 4: W-LIN-1 a linear value cannot sit inside List
Expected: refused at the check stage by W-LIN-1: line 0: W-LIN-1 linear `h` is moved inside a loop
Expected: refused at the check stage by W-LIN-1: line 8: W-LIN-1 linear `h` is consumed on some branches but not others
Expected: refused at the check stage by W-LIN-1: line 0: W-LIN-1 linear `h` is not consumed at the end of its block
W-LOOP-1 (1)
Expected: refused at the check stage by W-LOOP-1: line 1: W-LOOP-1 LOOP_LIMIT must be declared `const LOOP_LIMIT: u64 = n` with a positive literal n
W-MATCH-1 (1)
Expected: refused at the check stage by W-MATCH-1: line 6: W-MATCH-1 match is not exhaustive: missing Green
W-NAME-1 (1)
Expected: refused at the check stage by W-NAME-1: line 1: W-NAME-1 unknown name `y`
W-OWN-1 (1)
Expected: refused at the check stage by W-OWN-1: line 5: W-OWN-1 `s` is used after it was moved
W-OWN-2 (2)
Expected: refused at the check stage by W-OWN-2: line 3: W-OWN-2 `xs` is borrowed by the for loop and cannot be modified inside it
Expected: refused at the check stage by W-OWN-2: line 6: W-OWN-2 `xs` is borrowed mutably and again in one call
W-OWN-3 (1)
Expected: refused at the check stage by W-OWN-3: line 1: W-OWN-3 a returned borrow must derive from a borrowed parameter (R-RET)
W-REC-1 (3)
Expected: refused at the check stage by W-REC-1: line 4: W-REC-1 recursion through countdown has no decreasing measure (6.7): no layers of summed measures, each kept by every call not yet done and shrunk by at least one, leave the remaining calls without a cycle, and a cycle of its calls passes through no function declared with `bound`
Expected: refused at the check stage by W-REC-1: line 8: W-REC-1 recursion through loop_forever has no decreasing measure (6.7): no layers of summed measures, each kept by every call not yet done and shrunk by at least one, leave the remaining calls without a cycle, and a cycle of its calls passes through no function declared with `bound`
Expected: refused at the check stage by W-REC-1: line 1: W-REC-1 recursion through f, g has no decreasing measure (6.7): no layers of summed measures, each kept by every call not yet done and shrunk by at least one, leave the remaining calls without a cycle, and a cycle of its calls passes through no function declared with `bound`
W-REG-1 (1)
Expected: refused at the check stage by W-REG-1: line 5: W-REG-1 a value in arena `a` escapes into `out`
W-SAFE-1 (1)
Expected: refused at the check stage by W-SAFE-1: line 2: W-SAFE-1 `unsafe` is refused
W-SIMD-1 (2)
Expected: refused at the check stage by W-SIMD-1: line 2: W-SIMD-1 lane-wise `+` needs two arrays of one fixed length, found [i32; 3] and [i32; 4]
Expected: refused at the check stage by W-SIMD-1: line 2: W-SIMD-1 lane-wise `*` needs numeric lanes, found text
W-SPAWN-1 (2)
Expected: refused at the check stage by W-SPAWN-1: line 4: W-SPAWN-1 `c_work` is a foreign function and cannot be spawned
Expected: refused at the check stage by W-SPAWN-1: line 7: W-SPAWN-1 spawned tasks cannot receive borrows
W-STATE-2 (1)
Expected: refused at the check stage by W-STATE-2: line 2: W-STATE-2 field `n` needs a comptime initial value
W-STEP-2 (1)
Expected: refused at the check stage by W-STEP-2: line 5: W-STEP-2 event `Dec` is handled by no step or actor: δ would not be total
W-STEP-4 (1)
Expected: refused at the check stage by W-STEP-4: line 7: W-STEP-4 unreachable: the unguarded step at line 6 already handles S on E
W-SYN-1 (10)
Expected: refused at the parse stage by W-SYN-1: line 1: W-SYN-1 expected `)` (found `=`)
Expected: refused at the parse stage by W-SYN-1: line 1: W-SYN-1 expected end of line (found `<`)
Expected: refused at the parse stage by W-SYN-1: line 1: W-SYN-1 expected a declaration (found `class`)
Expected: refused at the parse stage by W-SYN-1: line 1: W-SYN-1 expected `else` (found end of line)
Expected: refused at the parse stage by W-SYN-1: line 2: W-SYN-1 expected indented block (found `fn`)
Expected: refused at the parse stage by W-SYN-1: line 2: W-SYN-1 expected `->` (found integer `1`)
Expected: refused at the parse stage by W-SYN-1: line 2: W-SYN-1 expected indented block (found `event`)
Expected: refused at the parse stage by W-SYN-1: line 4: W-SYN-1 expected `on` (found `E`)
Expected: refused at the parse stage by W-SYN-1: line 1: W-SYN-1 expected an expression (found `try`)
Expected: refused at the parse stage by W-SYN-1: line 1: W-SYN-1 unterminated string
W-TRAIT-2 (1)
Expected: refused at the check stage by W-TRAIT-2: line 1: W-TRAIT-2 orphan impl: neither the trait nor the type is declared in this module
W-TY-1 (10)
Expected: refused at the check stage by W-TY-1: line 2: W-TY-1 `*` on f32 and f64: no implicit conversion
Expected: refused at the check stage by W-TY-1: line 2: W-TY-1 `+` on f32 and f64: no implicit conversion
Expected: refused at the check stage by W-TY-1: line 2: W-TY-1 fail needs an error, found ?0
Expected: refused at the check stage by W-TY-1: line 1: W-TY-1 `+` on u8 and i64: no implicit conversion
Expected: refused at the check stage by W-TY-1: line 2: W-TY-1 expected text, found ?0
Expected: refused at the check stage by W-TY-1: line 1: W-TY-1 `f` can reach its end without returning i64
Expected: refused at the check stage by W-TY-1: line 2: W-TY-1 expected u64, found text
Expected: refused at the check stage by W-TY-1: line 2: W-TY-1 cannot compare u8 with text
Expected: refused at the check stage by W-TY-1: line 2: W-TY-1 `+` on u64 and i64: no implicit conversion
Expected: refused at the check stage by W-TY-1: line 6: W-TY-1 expected i64, found i64 ! E
Built from spec commit 49fa9af. Code cells run the reference checker rce-check, written in Rust and compiled to WebAssembly, inside your browser; nothing is sent to a server. Read-aloud uses the Kokoro-82M model (Apache-2.0), served from this site and run in your browser.