Skip to content

Backports for 1.13.0-rc1#61318

Open
KristofferC wants to merge 14 commits intorelease-1.13from
backports-release-1.13
Open

Backports for 1.13.0-rc1#61318
KristofferC wants to merge 14 commits intorelease-1.13from
backports-release-1.13

Conversation

@KristofferC
Copy link
Copy Markdown
Member

@KristofferC KristofferC commented Mar 13, 2026

Backported PRs:

Need manual backport:

Contains multiple commits, manual intervention needed:

Non-merged PRs with backport label:

These `@assert`s are not directly problematic for `--trim` (thanks to an
overload / monkey patch it does), but they can cause false positives for
dynamic dispatches in JET and similar tools so it's probably best to
replace them with the 2-arg variant (which just needs to print a String,
rather than an `Expr` containing arbitrary Julia objects)

(cherry picked from commit d64c0da)
@KristofferC KristofferC added the release Release management and versioning. label Mar 13, 2026
JamesWrigley and others added 11 commits March 14, 2026 00:18
…tion (#61264)

When a const-prop frame encounters a cycle and gets poisoned,
`finishinfer!` marks the result as tombstoned and sets `cache_mode =
CACHE_MODE_NULL`, which prevents `promotecache!` from pushing the result
to the local inference cache.
Meanwhile, `constprop_cache_lookup` (added in #57545) skips tombstoned
entries entirely. This combination means the same const-prop is
re-attempted on every cycle iteration, causing inference to never
terminate when `aggressive_constant_propagation = true`.

Fix this by:
- In `const_prop_call`, explicitly pushing tombstoned results to the
inference cache after a successful but limited `typeinf`, and returning
`nothing` to fall back to the regular inference result.
- In `constprop_cache_lookup`, no longer skipping tombstoned entries so
they can be found on subsequent lookups, preventing re-attempts.
- In `const_prop_call` cache-hit path, checking `inf_result.tombstone`
and returning `nothing` (same as the existing cycle-hit handling).
- Removing the now-unnecessary tombstone check from
`OverlayCodeCache.get`, where the subsequent `overridden_by_const` and
`isdefined` checks already filter out such entries.

Note that #57545 added `tombstone && continue` to `cache_lookup` to
prevent `LimitedAccuracy` results from propagating to callers via
`const_prop_result`. This change removes that skip but achieves the same
protection by explicitly checking `inf_result.tombstone` in
`const_prop_call` and returning `nothing` instead of using the result.

Fixes #61257

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Rewriting the bundled zstd executables with install_name_tool
invalidates their existing signatures on macOS. Re-sign them ad
hoc after updating the rpath so the CLI remains launchable for Pkg
archive decompression.

Add a regression test that runs the bundled zstd executable
instead of only checking that libzstd can be loaded.

Fixes #61354 (but see discussion there as to whether it really does?)

Co-authored-by: Codex <codex@openai.com>

Co-authored-by: Codex <codex@openai.com>
(cherry picked from commit 3de619d)
@KristofferC KristofferC requested a review from giordano as a code owner March 24, 2026 13:08
aviatesk and others added 2 commits March 28, 2026 19:30
…tial hang (#61316)

Investigation of aviatesk/JETLS.jl#509 revealed that the root cause is a
hang in the subtyping algorithm. A minimal reproducer has been added to
`test/subtype.jl`, which does not terminate in a reasonable time on the
current master branch.

The fix was developed using Claude and Codex, with iterative
cross-review between the two to arrive at what I believe is the most
sound approach. However, I am not very familiar with the subtype
algorithm implementation, so there may be implementation issues I have
not caught. Note that the bulk of this patch was written by AI.

---

`subtype_ccheck` calls `local_forall_exists_subtype`, which leaks
right-side Union choices (via `pick_union_decision`) into the shared
`Runions` statestack. When many
Union-bounded type parameters share a common variable (e.g. 6 parameters
all bounded by `Union{Ref{F},Val{F}}`), each bounds check adds decisions
that `exists_subtype` must iterate over combinatorially, causing O(2^N)
iterations.

Make `subtype_ccheck` save and restore both the `Runions` state and
variable environment (`save_env`/`restore_env`).

When `pick_union_decision` added new entries during the check (detected
via `Runions.used` growth) and the check succeeded, a merge loop
(`ccheck_merge_env`) enumerates all successful right-side ∃ branches and
merges their variable constraints via `simple_meet` (lb) / `simple_join`
(ub). This yields the widest constraints valid across any successful
branch, instead of discarding all constraints. A separate
`ccheck_restore_metadata` step then overrides the metadata fields
(`occurs_inv`, `occurs_cov`,
`max_offset`, `innervars`) with the original values, since `merge_env`'s
metadata merging (max for occurs, min for max_offset) tightens
constraints — the opposite of what `subtype_ccheck` needs.

The merge loop uses `next_union_state_from` to iterate only the ccheck's
own ∃ decisions (starting from
`oldRunions.used`), avoiding interference with outer Union iteration.
Each branch runs a full ∀∃ check via
`local_forall_exists_subtype`. The `ccheck_merging` flag prevents
re-entrant merge loops from nested `subtype_ccheck` calls; the
`!e->intersection` guard avoids conflicts with `intersect_all`'s own
`merge_env` handling.

When no Union splitting occurred, the variable constraints are
deterministic and safe to keep; restoring them unconditionally
introduces false negatives that break the `obvious_subtype` invariant.
The `envout` array is preserved across the restore because inner
`subtype_unionall` calls may have already written inferred
type-parameter values that must survive.

Known limitation: detection via `Runions.used` growth is imperfect —
`local_forall_exists_subtype`'s exists-free path (path 1) internally
pushes/pops its own `Runions`, so Union choices made there do not
increase the outer `Runions.used`. Currently harmless because
exists-free inputs have no exists-variable constraints to corrupt, but
the detection mechanism has a structural gap.

Fixes aviatesk/JETLS.jl#509.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…61130)

fixes #60715

`tmerge_types_slow` would check `issimpleenoughtype(u)` after the
`PartialStruct`s were stripped from the types, but that path wasn't
getting hit as it would early return via `tmerge_fast_path`

Claude assisted the analysis but the proposed fix is mine
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release Release management and versioning.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants