Repository navigation
sysl 0.0.159 — a type costs what it runs, not what names it
a type costs what it runs, not what names it
One capability fix, released as an exception to the bootstrap freeze. It finishes what 0.0.157 and 0.0.158 began: a module was still charged a gated module's requirement whenever it named one of that module's types — in a field, a variant's payload, a signature or a type argument — though naming a type runs none of its code.
Behaviour changes
Programs that were refused now build. Nothing that built before is refused now, with one exception below.
- Naming a type from a gated module charges nothing. A module whose error enum wraps
sysl.fs.IoErrorfor its one@needs(os)function is importable by a@no_osprogram, or one whose target hasos = false, for everything else it declares. So is a module naming the type in an unannotated signature, in a struct field, or as a type argument such asOption[IoError]; and a@no_osprogram may construct a value of such a type itself. - What a type runs is still charged, where it runs. Calling one of its methods charges its module, exactly as calling a function does; so do taking a method's address and erasing a value into a trait object. A type with a destructor (
impl Drop) charges its module wherever a value of it can die — and so does every type that holds one, through a field, a&T, a slice or an array. The refusal then reads "a 'sys.Handle' can die here, and its destructor reaches 'sys', which requires 'os'", at the place the type is named. - The exception: a method call is now charged by itself. It used to be charged only through the type's name, so a module that called a gated type's method on a value whose type it never wrote down (an inferred one) was not charged for it; it is now.
- Known limit: a method called inside a generic instantiation is not charged to the generic's module, since the type was its caller's choice, made in a module of its own.
module store
import sysl.fs.{IoError, write_bytes}
enum Failure
Io(e: IoError)
@needs(os)
save(p: string) -> Result[unit, Failure] = write_bytes(p, "x".bytes).map_err((e) -> Io(e))
version() -> int = 3
A @no_os program may now import store.version; before this release it was refused at the import, because Failure names IoError. A call to save from it is still refused, at the call.
Fixes
A type is charged for the code it runs, not for being named (140be89)
The rule chosen is the user's option 2: a type is charged only for the code it runs.
- Naming. Resolving a type, trait, variant or alias (
typeKey,traitKey,variantKey,aliasedKey, and a qualified path through a type inthroughModule) recordsEdgeUse.namedwith the key, andGatedModules.effectivecharges a named use nothing. An import whose every use only names a type is charged nothing likewise. - Methods. A method call names no module, so
GatedModules.chargeCallsreads what each non-generic body runs off the typed tree (Reachability.calledBy: calls, addresses taken, tables erased into) and records a running use on the callee's module. These go intoedgeUsesonly, never the module graph, so they cannot make a cycle;requirements()now walksedgeUses' keys. - Destructors. A named use whose type can die running code — it, or anything it holds through a field,
&T, slice or array, has animpl Drop— is charged as an ordinary reference, and reported ahead of the import.
Tests: TypeChargingTests (new) — the IoError-wrapping enum builds and prints 3; signature, field, type-argument, construction and qualified-path naming are free; the @needs call is refused at the call; a method call is refused; a Drop type and a type holding one are refused where held, a plain type beside it is not. DeclCapabilityTests and TargetCapabilityTests: the unannotated-signature case now builds (it asserted the old rule), plus the enum case on an os = false machine.
Verification
- Native gate on
140be899:GATE: GREEN, 12343 succeeded, 0 failed. The release inherits it (gated sha 140be89; dev = 140be89 + version bump). - Warnings census clean (JVM / JS / Native / syslDocJVM / syslDocNative), every warning named and outside this repository.
- Documented on sysl.sh:
reference/modules.md § A type costs what it runs.