Files
elixir-patterns/changelog/2026-04-30.md
T
2026-04-30 07:05:38 -07:00

2.4 KiB

Elixir Digest — 2026-04-30

Type System / Gradual Typing

#15324 — Fix invalid type inference on size compare in guards

  • Author: lukaszsamson
  • Merged: 2026-04-29
  • Mirror expressions like tuple_size(x) >= 2 and 2 <= tuple_size(x) were producing different type inferences.
  • Fix introduces mirror_order/1 helper that correctly flips comparison operators when operands are swapped.
  • Impact: Guards with size on the right now correctly infer the same type as left-sided equivalents.

#15322 — Fix map union optimization for open maps

  • Author: gldubc (Guillaume Duboc)
  • Merged: 2026-04-29
  • Optimizer subtype shortcut incorrectly concluded open map contained by closed map when field types matched.
  • Open maps can have extra keys — fix rejects shortcut on tag (open/closed) mismatch.
  • Impact: Fixes false type narrowing with unions of open and closed map types.

#15319 — Fix map difference union optimization

  • Author: gldubc (Guillaume Duboc)
  • Merged: 2026-04-28
  • Disabled :union case of single-key open-map difference optimization.
  • Could build invalid union literals causing double negation to leave phantom empty maps.

Core / Runtime

#15306 — Fix reentrancy of Code.eval_*

  • Author: lukaszsamson
  • Merged: 2026-04-28
  • Nested Code.eval_string clobbered outer eval's dbg_callback and ?elixir_eval_env in process dict.
  • Fix: save/restore pattern (save before, restore in after block).
  • Discussion: Jonatan Kłosko caught test was not actually testing nested eval; José simplified implementation.
  • Lesson: Process dictionary as implicit state = reentrancy bugs. Deliberate trade-off for version decoupling.

#15316 — Consistently return path as binary in relative_to_cwd

  • Author: lukaszsamson
  • Merged: 2026-04-28
  • Path.relative_to_cwd/1 could return chardata on :file.get_cwd failure.
  • All code paths now normalize to binary.

Patterns to Extract

  • Process dict save/restore for reentrancy (#15306): When using process dict as implicit state, always save/restore in try/after to handle reentrancy. The Elixir team chose this over closures to avoid coupling eval to specific Elixir versions.
  • Set-theoretic type system edge cases (#15322, #15319): Open vs closed map distinction is subtle in BDD-based type representations. Subtype checks must respect structural tags, not just field types.