zeolite-lang v0.10.0.0 Release Notes

Release Date: 2020-12-05 // 12 months ago
  • Language

    • [breaking] Major changes to .0rt syntax:

      • [breaking] Removes the expression argument from success and crash testcase types. Use one or more unittest (see next point) instead.
      • [new] Adds unittest keyword to allow the user to define multiple tests within a single success testcase.
      testcase "simple tests" {
      unittest checkInvariant1 {
        // this is a regular procedure with no return
      unittest checkInvariant2 {
        // this is a regular procedure with no return

      This allows multiple tests to use the same setup, while still being able to track multiple test failures. error and crash testcase types are still available.

      • [breaking] Allows testcase to statically set Argv (see lib/util) using the args keyword. By default, only the program name is set. Previously, Argv used whatever was passed to the test binary.
      testcase "with static Argv" {
        args "arg1" "arg2"
      unittest test {
        // something that requires Argv.global()

      Note that this isn't a library change; this also affects C++ extensions that use Argv from base/logging.hpp.

      • [new] Adds compiles mode for testcase. This is like success except nothing is executed. (success requires at least one unittest, whereas compiles will not execute anything even if unittest are present.)


    • [new] Adds the lib/testing library with basic helpers for unit tests.

    Compiler CLI

    • [new] Updates parsing of .zeolite-module to allow any ordering of the fields. Previously, the fields needed to be in a very specific order.

    • [fix] Adds compile-time protection against self-referential expression macros defined in expression_map: in .zeolite-module. Previously, the result was infinite recursion that could exhaust system resources.

    • [breaking] Adds an error when root/path in .zeolite-module differs from the location of the respective .zeolite-module. This is to catch both typos (e.g., copy-and-paste errors) and ambiguities.

Previous changes from v0.9.0.0

  • Compiler CLI

    • [breaking] Major changes to C++ extensions:

      • [breaking] Corrects hole in $ModuleOnly$ visibility in C++ extensions. Previously, C++ extensions could directly access categories defined in $ModuleOnly$ sources in dependencies.
      • [breaking] Randomizes cache paths and namespaces for generated C++ code so that C++ extensions cannot use static #include paths to circumvent the visibility rules of a dependency.
      • [breaking] Makes TypeInstances shared in generated C++ and in C++ extensions, to allow for better memory management of @types in the future.
      • [breaking] Adds guards to C++ headers for $TestsOnly$ categories, to prevent them from being used in non-$TestsOnly$ C++ extensions.
    • [fix] Fixes regression where calling zeolite with -p would overwrite an existing .zeolite-module.


    • [breaking] Syntax changes:

      • [breaking] Changes the syntax for calling @category functions from $$ to :, e.g., Foo:create() instead of Foo$$create(). A new error message (to be removed later) will remind the user to stop using $$.
      • [breaking] Changes the syntax for calling @type functions from $ to ., e.g., Foo.create() instead of Foo$create(). A new error message (to be removed later) will remind the user to stop using $.
    • [breaking] Changes to param usage:

      • [breaking] Updates param inference to be more accurate. The new algorithm will infer a param type iff the best choice is unambiguous given the expected and actual function arguments.
      • [breaking] Disallows bounding a single param both above and below, e.g., having both #x requires Foo and #x allows Bar. This is primarily to prevent cycles and contradictions in the type system.

      Previously, the best case for such restrictions was that there are extremely few choices for #x, and the worst case was that it implies Bar converts to Foo when it isn't true, thus making #x unusable. Having either of those requirements likely indicates a design flaw.

    • [breaking] Prohibits having a $TestsOnly$ definition for a non-$TestsOnly$ category. Previously, a concrete category declared in a non-$TestsOnly$ .0rp could be defined in a $TestsOnly$ .0rx, which creates a loophole that allows binaries to utilize $TestsOnly$ code.

    • [fix] Fixes a latent type-checking bug that could occur when attempting to assign a value with an intersection type to a variable with a union type, if one or both types has another nested type, e.g., [A&B][[A&B]|C] or [[A|B]&C][A|B]. This change shouldn't cause new type-checking failures.


    • [fix] Implements subSequence for Argv in lib/util. This is required by ReadPosition but was forgotten. Calling it prior to this would cause a failure.