Dialyzer: clear 114 pre-existing warnings and re-enable the CI gate #43

Open
opened 2026-06-09 23:31:09 +00:00 by sickday · 1 comment
Owner

Summary

The codebase has 114 pre-existing Dialyzer warnings (MIX_ENV=test mix dialyzer against a clean PLT). It has never passed Dialyzer cleanly. The CI Dialyzer step has been set to continue-on-error: true so it runs for visibility but does not gate CI / image builds. This issue tracks clearing the backlog so the gate can be re-enabled.

Note: a stale/incomplete PLT can under-report (early in investigation it showed only ~9). Always validate against a freshly built PLT: delete _build/*/dialyxir_*.plt* then mix dialyzer --plt before counting.

Breakdown (114 total)

1. Missing Game.Types module — ~57 warnings (highest leverage)

sync.ex (18), tick.ex (16), bot/ai.ex (16), region.ex (7) all alias Game.Types and reference Game.Types.player/0, Game.Types.entity_index/0, etc. in @specs — but Game.Types does not exist. Creating it with the referenced type definitions should clear the bulk in one change. Audit every Game.Types.* reference first to define the full surface correctly.

2. Wrong self-type references — ~3

Specs reference Module.t() instead of t() for the module they're in:

  • game/model/structs/backpack.ex:70Backpack.t() should be t()
  • game/model/structs/skills.ex:59Skills.t() should be t()
  • Cache.Definition.ObjectDefinition.t/0 (collision update.ex / manager.ex)

3. Forward-compat branches over stubs — ~15 (pattern_match / pattern_match_cov)

Stub functions return a constant, making a downstream branch provably unreachable. Examples: door_manager.ex load_objects_at/3[]; most bot/goals/*.ex (chop/fish/mine/pk/travel + goal_runner.ex); interactions.ex (5); attack_style.ex; actions.ex; pending_action.ex. Decide per-site: implement the stub, or scope-ignore the forward-compat clause.

4. Mix / IEx false positives — ~6 (unknown_function)

BlackLobster.MixProject.name/0 and IEx.Helpers.recompile/0 are genuinely available at runtime (the server runs via mix run --no-halt, see Dockerfile — not an OTP release), but aren't in the default PLT. Affects black_lobster.ex, cache/supervisor.ex, network/supervisor.ex, network/session/js5.ex, game/world/system_update.ex, command/commands/admin/reload.ex. Fix by plt_add_apps: [:mix, :iex] or an ignore file. (Adding apps to the PLT changes analysis breadth — rebuild and re-check after.)

5. Misc — ~30

unused_fun (npc_supervisor.ex ×5, bot/manager.ex ×3, npc.ex), no_return (npc_supervisor.ex, bot/manager.ex), call / call_without_opaque / guard_fail, and opaque-term misuse in pathfinder.ex (passing a gb_sets/MapSet internal across an astar_loop boundary). Plus benign always-true/false comparison warnings from compile-time adapter selection (repo.ex SQLite3 == Postgres, cache/definition/loc.ex binary() /= nil, runecraft_and_bank.ex Stack /= nil) — likely worth # dialyzer guards or restructuring.

Suggested order

  1. Create Game.Types (clears ~57).
  2. Fix self-type-refs (~3).
  3. Decide Mix/IEx via plt_add_apps vs ignore (~6).
  4. Walk the stub/forward-compat branches (~15).
  5. Mop up misc (~30), rebuild PLT, confirm zero, flip CI Dialyzer back to blocking (remove continue-on-error).

Repro

cd Server
find _build -name 'dialyxir_*.plt*' -delete
MIX_ENV=test mix dialyzer --plt   # rebuild clean PLT
MIX_ENV=test mix dialyzer

Suggested labels: optimization, ci-cd, priority:medium.

## Summary The codebase has **114 pre-existing Dialyzer warnings** (`MIX_ENV=test mix dialyzer` against a clean PLT). It has never passed Dialyzer cleanly. The CI `Dialyzer` step has been set to `continue-on-error: true` so it runs for visibility but does **not** gate CI / image builds. This issue tracks clearing the backlog so the gate can be re-enabled. > Note: a stale/incomplete PLT can under-report (early in investigation it showed only ~9). Always validate against a freshly built PLT: delete `_build/*/dialyxir_*.plt*` then `mix dialyzer --plt` before counting. ## Breakdown (114 total) ### 1. Missing `Game.Types` module — ~57 warnings (highest leverage) `sync.ex` (18), `tick.ex` (16), `bot/ai.ex` (16), `region.ex` (7) all `alias Game.Types` and reference `Game.Types.player/0`, `Game.Types.entity_index/0`, etc. in `@spec`s — **but `Game.Types` does not exist**. Creating it with the referenced type definitions should clear the bulk in one change. Audit every `Game.Types.*` reference first to define the full surface correctly. ### 2. Wrong self-type references — ~3 Specs reference `Module.t()` instead of `t()` for the module they're in: - `game/model/structs/backpack.ex:70` → `Backpack.t()` should be `t()` - `game/model/structs/skills.ex:59` → `Skills.t()` should be `t()` - `Cache.Definition.ObjectDefinition.t/0` (collision `update.ex` / `manager.ex`) ### 3. Forward-compat branches over stubs — ~15 (`pattern_match` / `pattern_match_cov`) Stub functions return a constant, making a downstream branch provably unreachable. Examples: `door_manager.ex` `load_objects_at/3` → `[]`; most `bot/goals/*.ex` (chop/fish/mine/pk/travel + `goal_runner.ex`); `interactions.ex` (5); `attack_style.ex`; `actions.ex`; `pending_action.ex`. Decide per-site: implement the stub, or scope-ignore the forward-compat clause. ### 4. Mix / IEx false positives — ~6 (`unknown_function`) `BlackLobster.MixProject.name/0` and `IEx.Helpers.recompile/0` are genuinely available at runtime (the server runs via `mix run --no-halt`, see Dockerfile — not an OTP release), but aren't in the default PLT. Affects `black_lobster.ex`, `cache/supervisor.ex`, `network/supervisor.ex`, `network/session/js5.ex`, `game/world/system_update.ex`, `command/commands/admin/reload.ex`. Fix by `plt_add_apps: [:mix, :iex]` **or** an ignore file. (Adding apps to the PLT changes analysis breadth — rebuild and re-check after.) ### 5. Misc — ~30 `unused_fun` (`npc_supervisor.ex` ×5, `bot/manager.ex` ×3, `npc.ex`), `no_return` (`npc_supervisor.ex`, `bot/manager.ex`), `call` / `call_without_opaque` / `guard_fail`, and opaque-term misuse in `pathfinder.ex` (passing a `gb_sets`/`MapSet` internal across an `astar_loop` boundary). Plus benign always-true/false comparison warnings from compile-time adapter selection (`repo.ex` `SQLite3 == Postgres`, `cache/definition/loc.ex` `binary() /= nil`, `runecraft_and_bank.ex` `Stack /= nil`) — likely worth `# dialyzer` guards or restructuring. ## Suggested order 1. Create `Game.Types` (clears ~57). 2. Fix self-type-refs (~3). 3. Decide Mix/IEx via `plt_add_apps` vs ignore (~6). 4. Walk the stub/forward-compat branches (~15). 5. Mop up misc (~30), rebuild PLT, confirm zero, flip CI `Dialyzer` back to blocking (remove `continue-on-error`). ## Repro ``` cd Server find _build -name 'dialyxir_*.plt*' -delete MIX_ENV=test mix dialyzer --plt # rebuild clean PLT MIX_ENV=test mix dialyzer ``` Suggested labels: `optimization`, `ci-cd`, `priority:medium`.
sickday self-assigned this 2026-06-11 14:11:26 +00:00
sickday added this to the v1 project 2026-06-11 14:11:48 +00:00
Author
Owner

Update: the highest-leverage item here is already done — Game.Types now exists (lib/black_lobster/game/types.ex) defining player/0, entity_index/0, tile/0, so the ~57 warnings that hung on the missing module are resolved. .dialyzer_ignore.exs and plt_add_apps: [:mix, :iex] are also in place. Remaining work: rebuild a clean PLT, recount the actual warnings (the '114' and 'Game.Types does not exist' framing in the body is now stale), clear the rest, then remove continue-on-error: true from the Dialyzer step in .forgejo/workflows/ci.yml to make the gate blocking.

Update: the highest-leverage item here is already done — `Game.Types` now exists (`lib/black_lobster/game/types.ex`) defining `player/0`, `entity_index/0`, `tile/0`, so the ~57 warnings that hung on the missing module are resolved. `.dialyzer_ignore.exs` and `plt_add_apps: [:mix, :iex]` are also in place. Remaining work: rebuild a clean PLT, recount the actual warnings (the '114' and 'Game.Types does not exist' framing in the body is now stale), clear the rest, then remove `continue-on-error: true` from the Dialyzer step in .forgejo/workflows/ci.yml to make the gate blocking.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
BlackLobster/Server#43
No description provided.