Skip to content

fix: resolve Elixir 1.19 typing violations and Inspect regression#81

Merged
fahchen merged 1 commit into
mainfrom
opt/00-elixir-119-fixes
Apr 30, 2026
Merged

fix: resolve Elixir 1.19 typing violations and Inspect regression#81
fahchen merged 1 commit into
mainfrom
opt/00-elixir-119-fixes

Conversation

@fahchen

@fahchen fahchen commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Local Elixir 1.19.5 fails mix compile --warnings-as-errors on `%X{var | field: ...}` struct updates where `var` is bound from a `dynamic()` source. CI on 1.17.3 is unaffected, but local dev breaks. Also the `MultiSet` `Inspect` impl regresses on 1.19.5: `Inspect.Algebra.concat/2` no longer accepts the doc shape returned by `Inspect.List.inspect/2`.

Per the compiler hints, narrow each affected binding (`%X{} = var`) and switch updates to map-update syntax. Replace `Inspect.List.inspect/2` with `to_doc/2` in `MultiSet`'s `Inspect` impl.

Sites changed

  • `expression.ex` — 8 `%Scope{...}` updates in `analyse_node/2` (parameter-pattern fix in each clause).
  • `validators.ex` — `%ColouredPetriNet{...}` updates in `run/1`'s `with`.
  • `enactment.ex` — `%Snapshot{...}` in `catchup_snapshot/2` and `%Workitem{...}` updates in `apply_calibration/1` and `start_workitems/2`.
  • `workitem_consumption.ex` — `%Marking{...}` update in `consume_tokens/2`.
  • `multi_set.ex` — `Inspect.List.inspect/2` → `to_doc/2`.

Production behavior is unchanged — the new `%X{} = var` runtime guards preserve the same struct-enforcement semantics.

Test plan

  • `mix compile --warnings-as-errors` zero warnings.
  • `mix format --check-formatted` clean.
  • `mix credo --strict` exit 0.
  • `mix dialyzer` clean (5 errors, all in `.dialyzer_ignore.exs`).
  • `RESET_DB=1 mix test` — 63 doctests, 316 tests, 0 failures.
  • CI green on Elixir 1.17.3.

🤖 Generated with Claude Code

Elixir 1.19's stricter typing rejects `%X{var | field: ...}` updates when
`var` is bound from a `dynamic()` source (e.g. `Map.fetch!/2`,
function-arg pattern that doesn't pin the struct). Per the compiler's
hint, narrow each binding to the expected struct (`%X{} = var = ...` or
the function head pattern) and switch the update to map-update syntax.

Also fix the `MultiSet`'s `Inspect` implementation: `concat/2` no longer
accepts the doc shape returned by `Inspect.List.inspect/2` in Elixir
1.19.5. Use `to_doc/2` instead, which is the standard pattern for
embedding inspectable values.

Sites changed:
- `expression.ex` — 8 `%Scope{...}` updates in `analyse_node/2`
  (parameter-pattern fix in each clause).
- `validators.ex` — `%ColouredPetriNet{...}` updates in `run/1`'s `with`.
- `enactment.ex` — `%Snapshot{...}` in `catchup_snapshot/2` and
  `%Workitem{...}` updates in `apply_calibration/1` and
  `start_workitems/2`.
- `workitem_consumption.ex` — `%Marking{...}` update in
  `consume_tokens/2`.
- `multi_set.ex` — `Inspect.List.inspect/2` → `to_doc/2`.

Production behavior is unchanged — the new `%X{} = var` runtime guards
preserve the same struct-enforcement semantics. CI on Elixir 1.17.3 was
already green; this PR makes the local dev env on Elixir 1.19.5 green
too.
@fahchen
fahchen merged commit 87f90f3 into main Apr 30, 2026
5 checks passed
@fahchen
fahchen deleted the opt/00-elixir-119-fixes branch April 30, 2026 23:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant