Repository navigation
sysl 0.0.157 — a @needs body is charged to its callers, not its module
Two capability fixes, released as an exception to the bootstrap freeze. A @needs declaration's body is charged to the functions that call it, not to the whole module holding it. A @tests file no longer counts toward its module's requirement. And sysl.fs requires os alone, which is what library/fs.md has always said.
Behaviour changes
Programs that were refused now build. Nothing that built before is refused now.
- A
@no_osprogram can import a module that holds a@needs(os)function, as long as it never calls that function. The same goes for a program whose target lacksos. The call itself is still refused, at the call. Before, the function's body counted toward the whole module's requirement, so the program was refused at theimportline as well. - An os-less program can link a library whose
@testsfile usessysl.fs. A@testsfile is dropped by every build exceptsysl test, and now its imports and bodies are dropped from the module's requirement too. musicbox 0.1.1 hit this: itsnotation_tests.syslreads fixtures withsysl.fs, so a board program could not link it. - A
@no_posixprogram can usesysl.fs. So can a project that declaresos = true, posix = false. Before,sysl.fsimportedsysl.posix.randon every hosted target, so every program that reached the filesystem was made to requireposix.
module store
@needs(os)
present() -> bool = sysl.fs.exists("/") // touches the filesystem
plain() -> int = 3 // reaches nothing
@no_os
import store.plain
print(plain())
In 0.0.156 this program was refused at the import. In 0.0.157 it builds and prints 3. A call to present from it is still refused, at the call:
error: this reaches 'store.present', which needs 'os', and this module declared '@no_os'
--> main.sysl:5:7
Fixes
A @needs body and a @tests file are not charged to their module (8dd5b9a)
reference/modules.md says that what a @needs declaration reaches "is charged to whoever reaches it rather than to whoever holds it". The analyzer did not do that. The body's reference into sysl.fs was an ordinary edge in the module graph, so the whole module came to require os (and posix).
Scoping.dependsOn now records, for each use, which capabilities the enclosing declaration covers. FunctionBodies sets this from the function's @needs, and a closure written inside the body inherits it. GatedModules leaves those capabilities out of the module's requirement and out of the edge check, and DeclCapabilities does not refuse such a body for what it covers. A body covers only what its own annotation names: a @needs(heap) function that reaches sysl.fs still makes its module require os. An unannotated function that calls a @needs(os) one passes the need on to its own callers, because reaching is transitive.
Uses made in scaffolding (a @tests file, or a test body) no longer go into the module's requirement. testOnlyFiles is now filled before imports are read, so an import in such a file is known to be scaffolding.
sysl.fs requires os, not posix (050a276)
library/sysl/fs/publish.sysl drew its temporary-file entropy from sysl.posix.rand under #if posix, which is true on every hosted target. A module is charged the requirements of everything it imports, so sysl.fs came to require posix. It now declares getentropy(2) as a private extern under #if posix, the way sysl.fs already declares unlink, rename and opendir, and falls back to the clock where there is no POSIX. These POSIX calls are how this host implements the module, and the module's users are not charged for them.
Tests
DeclCapabilityTests, TargetCapabilityTests and a new suite, NeedsScopeCliTests. The new suite drives a real package.hocon (thumbv6m-freestanding with os = false) and --lib, and it runs the library's own sysl test on the host.
Now accepted:
- a module that gave up
osimports the declaration beside a@needs(os)one - a closure written inside a
@needsbody is covered with the body - a board program that only renders links a library whose
@testsfile readssysl.fs, and the library'ssysl teststill runs that file on a host - a program importing the declaration beside a
@needs(os)one builds, including where that body reaches another@needs(os)declaration - a program that gave up
posixreads the filesystem, and publishes through it, which is the part that draws entropy sysl.fson a machine with an os that is not POSIX, publishing included
Still refused:
- calling the
@needs(os)declaration, at the call only and not at the import, naming the machine - an unannotated function calling it, which passes the need on to its own callers
- an unannotated body that reaches
sysl.fs, which still costs the whole module - a body reaching past what its own annotation names
- a program that gave up
os, at its reference tosysl.fs, foros - the POSIX module
sysl.fsonce imported, on a machine without POSIX - the same import in a shipping file (not a
@testsfile), which is still charged to the module
Documentation
reference/modules.md on sysl.sh now says three things. A @needs declaration's body is charged to its callers, not to its module. A function that says nothing passes the need on. A @tests file's imports are not charged to the module. It also says that a target the config says nothing about provides everything, os included, and that capabilities { os = false } is what makes a board refuse sysl.fs.
Install
brew install sysl-lang/tap/sysl # or: brew upgrade sysl
The tarballs for macOS arm64, Linux x86_64 and Linux arm64 are attached to this release. The sh.sysl:sysl_3:0.0.157 jars are on GitHub Packages (https://maven.pkg.github.com/sysl-lang/sysl-bootstrap). sysl is not published to Maven Central.
Verification
- Native gate: inherited from the landing gate. 050a276 was gated with the full Native gate: GREEN, 12,287 succeeded and 0 failed, in 92:08, covering syslNative and syslDocNative. Nothing timed out and nothing was retried. The tag is 99fd46f, which is 050a276 plus the version bump and nothing else, so the suite was not re-run.
- Warnings census, cleaned: JVM two, JS three, Native three, syslDocJVM one, syslDocNative two. That is the expected count, and every warning belongs to a dependency or is build infrastructure.
- Release tarball: extracted to a scratch prefix and run.
sysl --versionprintssysl 0.0.157, andsysl-docis present. The@no_osprogram above prints3. A@no_posixprogram printingsysl.fs.exists("/")printstrue. Under 0.0.156 both programs were refused, the first at its import and the second at its reference tosysl.fs. The call topresentis refused at the call with the message shown. - GitHub Packages: all four artifacts (the pom, the jar, the sources jar and the javadoc jar) answer 302.
- brew:
brew test syslpasses, and the installedsysl --versionprintssysl 0.0.157. The Linux glibc floor, measured in the release run, is 2.34 on both architectures. - sysl.sh on 0.0.157: 1,418 tests pass with 0 failures. Of those, 1,398 are DocsTests, including the new prose on
reference/modules.md. - Org sweep with the release tarball's own binary: 79 builds, 73 green under the bare command.
- 57 ran under
sysl test ., 11 undersysl build .and 5 undersysl build-c <dir>. - Four repos fail the bare command by design and were run as their READMEs say.
freertosagainst the FreeRTOS-Kernel POSIX port: 84 passed. (Its first run, alongside the other README runs on a loaded machine, stopped making progress after 71 tests. Run again alone, it passed all 84.)libpqagainst a scratch PostgreSQL: 51 passed.quickjs-ngwith its include path: 33 passed. pico:build-lib --target thumbv6m-freestandinggets as far as the pico-sdk's generatedcyw43_arch.h, which means the sysl type-check passed.pico2andzephyrrefuse the bare command by design, through theirrequires { headers }clause.- Not swept, being kernel or board repos that need a toolchain or SDK this machine does not have:
picokit,ogol-pico,ogol-pico2,solder-pico2,zephyr-demo,pico-scratch. Also not swept, being infrastructure:sysl-bootstrap,sysl(the self-hosted compiler),sysl.sh,homebrew-tap,github-profileandsvd.
- 57 ran under
- Outside the org,
slate: a clean clone ofslate-language/slateat dev (c359e6b, 0.1.14). With the tarball's binary,sysl test .passes 2,436 tests with 0 failures, and bothsysl build .andsysl build . --features webview(the desktop edition) build.