Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jdx/pklr
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.4.0
Choose a base ref
...
head repository: jdx/pklr
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.4.1
Choose a head ref
  • 2 commits
  • 8 files changed
  • 2 contributors

Commits on Apr 7, 2026

  1. fix: resolve nullable outer property access and semicolons (#54)

    ### Original error
    
    ```shell
    ❯ RUST_BACKTRACE=1 hk run pre-commit
    
    thread 'main' (49584) panicked at src/settings.rs:90:30:
    Failed to load configuration: Failed to read config file: /Users/jonathan/development/inko-tantivy/hk.pkl
    
    Caused by:
        Eval error: field not found: checkFail
    
    Location:
        src/config.rs:389:18
    stack backtrace:
       0: __rustc::rust_begin_unwind
       1: core::panicking::panic_fmt
       2: core::result::unwrap_failed
       3: hk::settings::<impl hk::settings::generated::settings::Settings>::get
       4: hk::cli::run::{{closure}}
       5: tokio::runtime::park::CachedParkThread::block_on
       6: tokio::runtime::runtime::Runtime::block_on
       7: hk::main
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
    ```
    
    ---
    
    ### Summary
    
    - Arc-wrap `Lambda` captures so cloning a Lambda is O(1)
    - Seed `Null` into `eval_scope` for nullable-no-default base class
      properties so `outer.optProp` resolves to `Null` instead of erroring
    - Treat `;` as whitespace so Pkl's semicolon property separator is
    accepted
    
    ---
    
    ### Details
    
    #### `outer.before` — field not found
    
    hk's `helpers.pkl` `TestMaker` class uses this pattern:
    
    ```pkl
    class TestMaker {
      before: String?
      local function makeTest(...): Config.StepTest = new Config.StepTest {
        before = outer.before
        ...
      }
    }
    ```
    
    When `outer.before` was evaluated and `before` had no default value and
    was not set on the `TestMaker` instance, `outer` (a snapshot of the
    scope before evaluating the object body) didn't contain `before` at all,
    causing a "field not found: before" error.
    
    Fix: in `eval_amended_object`, after building `eval_scope` from
    `base_scope + current_scope`, iterate over the base entries and insert
    `Null` for any nullable-no-default property absent from `eval_scope`.
    Since `eval_scope` becomes `outer` in the child `eval_entries` call,
    `outer.before` now resolves to `Null`.
    
    #### O(2^n) Lambda capture cloning
    
    `TestMaker` defines five local functions in sequence: `makeTest`,
    `checkPass`, `checkFail`, `fixPass`, `fixFail`. Each is a deferred
    lambda that captures `child_scope.flatten()` at evaluation time, which
    includes all previously-defined lambdas. With `Lambda` captures stored
    as a bare `IndexMap`, cloning a `Lambda` deep-copied its entire capture
    map — causing each successive lambda's clone cost to double, resulting
    in O(2^n) total work when `scope.flatten()` was called across 128 hk
    builtins.
    
    Fix: change `Value::Lambda`'s captures from `IndexMap<String, Value>` to
    `Arc<IndexMap<String, Value>>`. Clone is now O(1).
    
    #### Semicolons as property separators
    
    Pkl allows `;` as a separator between properties in object bodies (e.g.,
    `new { file = "package.json"; contains = "..." }`). The lexer was
    rejecting them as unexpected characters.
    
    Fix: skip `;` alongside whitespace in `skip_whitespace_and_comments`.
    
    (`checkFail` was missing because its function definition used a dotted
    return type `Config.StepTest`, fixed in the previous commit. After that
    fix, the error became `field not found: before`.)
    
    ---
    
    ### Test plan
    
    - [x] All 266 existing tests continue to pass
    - [x] `HK_PKL_BACKEND=pklr hk run check` succeeds in
    [inko-tantivy](https://github.com/jhult/inko-tantivy)
    jhult authored Apr 7, 2026
    Configuration menu
    Copy the full SHA
    5e84d7f View commit details
    Browse the repository at this point in the history
  2. chore: release v0.4.1 (#55)

    ## 🤖 New release
    
    * `pklr`: 0.4.0 -> 0.4.1 (✓ API compatible changes)
    
    <details><summary><i><b>Changelog</b></i></summary><p>
    
    <blockquote>
    
    ## [0.4.1](v0.4.0...v0.4.1) -
    2026-04-07
    
    ### Fixed
    
    - resolve nullable outer property access and semicolons
    ([#54](#54))
    </blockquote>
    
    
    </p></details>
    
    ---
    This PR was generated with
    [release-plz](https://github.com/release-plz/release-plz/).
    
    <!-- CURSOR_SUMMARY -->
    ---
    
    > [!NOTE]
    > <sup>[Cursor Bugbot](https://cursor.com/bugbot) is generating a
    summary for commit f211a5c. Configure
    [here](https://www.cursor.com/dashboard/bugbot).</sup>
    <!-- /CURSOR_SUMMARY -->
    jdx authored Apr 7, 2026
    Configuration menu
    Copy the full SHA
    5ef6e4d View commit details
    Browse the repository at this point in the history
Loading