Conversation
Stdlib: Downloads URL: https://github.com/JuliaLang/Downloads.jl.git Stdlib branch: master Julia branch: master Old commit: 168d18d New commit: faa1314 Julia version: 1.14.0-DEV Downloads version: 1.7.0 (It's okay that it doesn't match) Bump invoked by: @DilumAluthge Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: JuliaLang/Downloads.jl@168d18d...faa1314 ``` $ git log --oneline 168d18d..faa1314 faa1314 Bump julia-actions/setup-julia from 2 to 3 (JuliaLang#292) e59fd8b Bump julia-actions/cache from 2 to 3 (JuliaLang#290) f1937ce Bump codecov/codecov-action from 5 to 6 (JuliaLang#291) ``` Co-authored-by: DilumAluthge <5619885+DilumAluthge@users.noreply.github.com>
Stdlib: LibCURL URL: https://github.com/JuliaWeb/LibCURL.jl.git Stdlib branch: master Julia branch: master Old commit: 2e3f4cc New commit: b8ee014 Julia version: 1.14.0-DEV LibCURL version: 1.0.0 (Does not match) Bump invoked by: @DilumAluthge Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: JuliaWeb/LibCURL.jl@2e3f4cc...b8ee014 ``` $ git log --oneline 2e3f4cc..b8ee014 b8ee014 Bump julia-actions/cache from 2 to 3 (JuliaLang#120) 71acb9f Bump codecov/codecov-action from 5 to 6 (JuliaLang#121) ``` Co-authored-by: DilumAluthge <5619885+DilumAluthge@users.noreply.github.com>
…g#61645) This is a significant cleanup of he semantics of subtyping envout by removing any semantic relation between TypeVars and the inputs. See JuliaLang#61634 and JuliaLang#61645 for more details. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Stdlib: Tar URL: https://github.com/JuliaIO/Tar.jl.git Stdlib branch: master Julia branch: master Old commit: 6a61f5c New commit: 237cfcb Julia version: 1.14.0-DEV Tar version: 1.10.0 (Does not match) Bump invoked by: @DilumAluthge Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: JuliaIO/Tar.jl@6a61f5c...237cfcb ``` $ git log --oneline 6a61f5c..237cfcb 237cfcb Typo and tweaks from AI review (JuliaLang#195) c168bb1 avoid using a global buffer for `skip` since it is racy 4c35aaf avoid making no progress with cyclic symlinks f106eec be more accurate in checking bad Windows paths, trailing dot and space is also not allowed 68ed6c1 fix typo doing double `typemax` 6ed14a8 use `UInt8('\n')` to be consistent with other char -> uint conversions 6c4b9b6 NFC: correct argument to `check_extract_tarball` 97cc930 Bump julia-actions/setup-julia from 2 to 3 (JuliaLang#194) ``` Co-authored-by: DilumAluthge <5619885+DilumAluthge@users.noreply.github.com>
Stdlib: SHA URL: https://github.com/JuliaCrypto/SHA.jl.git Stdlib branch: master Julia branch: master Old commit: e7069c3 New commit: 51a0726 Julia version: 1.14.0-DEV SHA version: 1.13.0 (Does not match) Bump invoked by: @DilumAluthge Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: JuliaCrypto/SHA.jl@e7069c3...51a0726 ``` $ git log --oneline e7069c3..51a0726 51a0726 Update project version to 1.13.0 (JuliaLang#131) 4b34db6 Bump julia-actions/cache from 2 to 3 (JuliaLang#129) 028a2fb Bump codecov/codecov-action from 5 to 6 (JuliaLang#130) ``` Co-authored-by: DilumAluthge <5619885+DilumAluthge@users.noreply.github.com>
…ookup tables (JuliaLang#61766) closes JuliaLang#44175 `serialize` contains an optimization to deduplicate identical objects both for performance benefit and to retain aliasing relationships during round trips. conceptually, it does this by: for each value that is eligible for `serialize_cycle` (in practice, this mostly resolves to `ismutable`), maintain `counter` for the index at which we encountered that object, and save the `objectid` for future lookups. Then, if we see the same `objectid` later, serialize a `BACKREF` to the appropriate `counter`. On the deser side, when we see a `BACKREF`, access the object at the index of the associated `counter` rather than making a new object. however, it uses an `IdDict` for both purposes. this PR squeezes out a lot more performance by using a `Dict` for the serialization lookup and a `Vector` for the deser. questions for the reviewers mostly concern compatibility. this does change the fields of `Serializer` which is (unfortunately) a public type. but I'm not sure if the fields themselves are considered public? I have headed off in advance impacts to, e.g. [`Distributed.ClusterSerializer`](https://github.com/JuliaLang/Distributed.jl/blob/fde987fbb05c65bb6bd183396137383931107059/src/clusterserialize.jl#L10-L14) which makes assumptions about the way that `Serialization.serialize` makes use of a `.table` field on `AbstractSerializer`, by factoring out these field accesses into getter/setter functions and then specializing on `Serializer`. Is this an appropriate compromise? or should we just patch `Distributed` to not rely on this assumption? or is the change to `Serialization` considered wholesale breaking. there was a similar discussion in JuliaLang#43554 here are performance numbers on a few workloads: on the motivating MWE from JuliaLang#44175: <details> <summary> setup</summary> ```julia mutable struct MinimalNode childvalues::Union{NTuple{4, Int8}, NTuple{3, Int8}, NTuple{2, Int8}, NTuple{1, Int8}, Tuple{}}; childnodes::Union{NTuple{4, MinimalNode}, NTuple{3, MinimalNode}, NTuple{2, MinimalNode}, NTuple{1, MinimalNode}, Tuple{}}; end function addbranches!(mn::MinimalNode, aleft::Int64, bleft::Int64, parity::Int64, depth = 0) (depth == 12) && (return nothing); if parity == 1 (aleft <= 1) && (return nothing); mn.childvalues = Tuple(1:aleft); mn.childnodes = Tuple([MinimalNode((), ()) for ii in 1:aleft]); aleft -= 1; else (bleft <= 1) && (return nothing); mn.childvalues = Tuple(1:bleft); mn.childnodes = Tuple([MinimalNode((), ()) for ii in 1:bleft]); bleft -= 1; end addbranches!.(mn.childnodes, aleft, bleft, 3-parity, depth + 1); end function buildfaketree() root = MinimalNode((), ()); addbranches!(root, 4, 4, 1, 0); return root; end using Serialization; MN = [buildfaketree() for ii in 1:10000]; @time serialize("test.jls", MN); 35 seconds ``` </details> PR: ```julia julia> @time serialize("test.jls", MN); 6.419340 seconds (15.78 M allocations: 784.602 MiB, 17.18% gc time) julia> @time deserialize("test.jls"); 4.382877 seconds (20.79 M allocations: 817.876 MiB, 32.13% gc time) ``` master: ```julia julia> @time serialize("test_master.jls", MN); 17.084042 seconds (26.55 M allocations: 917.083 MiB, 5.38% gc time) julia> @time deserialize("test_master.jls"); 20.479949 seconds (31.56 M allocations: 1.204 GiB, 15.45% gc time) ``` but we also improve something as simple as `Vector{String}` setup: ```julia julia> using Random julia> v = map((_)->randstring(10), 1:1000000); ``` PR: ```julia julia> @time serialize("string.jls", v); 0.240658 seconds (37 allocations: 59.501 MiB, 9.13% gc time) julia> @time deserialize("string.jls"); 0.084324 seconds (1.00 M allocations: 64.112 MiB) ``` master: ```julia julia> @time serialize("string.jls", v); 0.592193 seconds (999.51 k allocations: 43.252 MiB, 11.42% gc time) julia> @time deserialize("string.jls"); 0.371651 seconds (2.00 M allocations: 81.410 MiB, 15.02% gc time) ``` assisted as always by Opus 4.7
fixes JuliaArrays/StaticArrays.jl#1282 test case minimized by codex
…uliaLang#61802) Two one-line typo fixes for duplicated words in source comments: - `src/signals-unix.c` — "redefine this as as an \"unreachable reached\" error message" → "redefine this as an \"unreachable reached\" error message" - `JuliaLowering/src/desugaring.jl` — "is the list of statements which needs to to be emitted" → "...which needs to be emitted" No code/behavior change. Co-authored-by: Maya Chen <275405107+otjdiepluong@users.noreply.github.com>
…liaLang#61791) The diagonal rule was changed to semi-static in JuliaLang#34272 — it uses `var_occurs_invariant(u->body, u->var)` (a structural check on the UnionAll body) rather than the dynamic `occurs_inv` counter, since the latter only reflects whichever invariant positions were actually traversed. The recently-added diagonality-change check in `env_unchanged` (JuliaLang#61503), however, still tested `v->occurs_inv == 0`, so it could spuriously flag a variable as "newly diagonal" when its body has T only in branches the algorithm never visited. Cache `var_occurs_invariant(u->body, u->var)` once at varbinding creation as `body_occurs_inv` and use it in `env_unchanged` (and at the existing recompute sites in `subtype_unionall` and `intersect_unionall`). The two checks can be made to diverge by hiding a `Ref{T}` in a Union branch that is never picked dynamically (added as a regression test); However, the divergence only changes how much `exists_subtype` exploration is performed after `sub == true` and not the boolean result or the chosen ∃-bindings. As a result, this is a performance fix, but not a correctness fix. Co-authored-by: Keno Fischer <Keno@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
as for the pairs version Co-authored-by: Andy Dienes <51664769+adienes@users.noreply.github.com>
This reduces the number of invalidations of loading BufferIO.jl commit 957f141 from 1026 to 549. The large number of invalidations come from excessive world splitting on un-inferred IO objects, which, ironically, are probably intentionally left un-inferred to reduce unnecessary compilation. This is a poor bandaid solution: World splitting delenda est and all that. If that is not feasible, then an option to selectively disable it e.g. through a future `@max_methods 0` would impove the situation. For example, about 400 methods are invalidated due to the addition of a new `write(::T, ::Char)` method, which invalidates the single, world split `write(::IO, ::Char)` method. However, deeper fixes of this issue is outside the scope of this PR. --------- Co-authored-by: Jeff Bezanson <jeff.bezanson@gmail.com> Co-authored-by: Andy Dienes <51664769+adienes@users.noreply.github.com>
This is a less-ambitious version of the program started in JuliaLang#60736 that avoids the need for JuliaLang#61200, by restricting itself to world-age at definition and side-stepping the issue of which names were `export`ed or `public` at specific world ages. A copy of my OP plus a summary of the new strategy: InteractiveUtils provides a number of utilities for querying and accessing the contents of modules. Because these modules can gain new bindings, some callers of InteractiveUtils functions produce warnings WARNING: Detected access to binding ... prior to its definition world. One dramatic example occurs with the sequence using OptimizationProblems: OptimizationProblems using OptimizationProblems.ADNLPProblems using ADNLPModels: ADNLPModel when running with Revise. ADNLPProblems loads new problems via Requires, and starting with v3.13 Revise queries `InteractiveUtils.subtypes` to cache dependent fieldtypes. This triggers the warning. To fix this, add a `world` keyword argument to `names`/`unsorted_names` to control the world age at which bindings are looked up. It is then threaded through `varinfo`, `methodswith`, and `subtypes` in InteractiveUtils so they operate on bindings in the correct world. The default for the `world` kwarg preserves the current behavior: `names`/`unsorted_names` default to `tls_world_age()` (matching the prior C-side use of `jl_current_task->world_age`); the InteractiveUtils entry points default to `get_world_counter()` so interactive tools see the latest definitions by default. Closes JuliaLang#60736 Closes JuliaLang#61200 Related: timholy/Revise.jl#993 Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
**Best reviewed with "Hide whitespace" When looking into JuliaLang#61292, I tried to use `versioninfo` to get the JIT’s cpu target. I found out that even though it shares parentheses with “ORCJIT”, the displayed cpu is always just the host CPU. Then I fell into the confusing and undocumented output of `versioninfo` rabbit hole trying to improve it and this is the result of that. Once I have a better idea about which changes are/aren't welcome, I’ll edit the docstring to be more explicit about what each item is. May be worth reviewing per-commit as I've tried to separate each change This PR: * Changes “GB” and “MB” to “GiB” and “MiB” when reporting memory information. * Moves the detected host cpu llvm target to be with the CPU instead of in the LLVM section. I changed this because the previous way implied it was the JIT target cpu. They usually match, but they may not if julia was launched with the `-C` flag * The build commit has been moved down into “Build Information” * Refactors the “Build Information” section. It will now always be shown, and the GC julia was built with was moved from the “Platform Information” section. * Adds the target cpu and triple that the base system image was built with when `verbose=true`. ~This adds a new Sys.BASE_SYSIMG_TARGET constant variable because calling `sysimage_target` from InteractiveUtils returns “sysimage”. Hidden behind `verbose` flag~ Edit: `sysimage_target` behaviour seems to have been fixed so the implementation now uses it. * LLVM section now reports the JIT target CPU where the host CPU use to be. ~This expands/uses API that was added by @gbaraldi for GPUCompiler in JuliaLang#49858.~ (edit: I found a way to do it using existing code) * The triple on the OS line is now the JIT target triple (same implementations worries as above), and the build machine triple (MACHINE) is now reported in the verbose-only sysimage line in “Build Information”. This is probably more relevant on macOS, where the triple includes the kernel version, but I find it [confusing](JuliaGPU/Metal.jl#179 (comment)) to show the build kernel version when reporting the current OS. Current output (master): ```julia-repl julia> versioninfo() Julia Version 1.14.0-DEV.2169 Commit 61cb046 (2026-05-10 23:05 UTC) Build Info: Official https://julialang.org release Platform Info: OS: macOS (arm64-apple-darwin24.0.0) CPU: 12 × Apple M2 Max WORD_SIZE: 64 LLVM: libLLVM-21.1.8 (ORCJIT, apple-m2) GC: Built with stock GC Threads: 8 default, 1 interactive, 8 GC (on 8 virtual cores) Environment: JULIA_NUM_THREADS = auto julia> versioninfo(verbose=true) Julia Version 1.14.0-DEV.2169 Commit 61cb046 (2026-05-10 23:05 UTC) Build Info: Official https://julialang.org release Platform Info: OS: macOS (arm64-apple-darwin24.0.0) uname: Darwin 25.5.0 Darwin Kernel Version 25.5.0: Mon Apr 27 20:39:09 PDT 2026; root:xnu-12377.121.6~2/RELEASE_ARM64_T6020 arm64 arm CPU: Apple M2 Max: speed user nice sys idle irq #1-12 2400 MHz 131350 s 0 s 70466 s 1842258 s 0 s Memory: 32.0 GB (304.4375 MB free) Uptime: 469303.0 sec Load Avg: 3.224609375 3.75244140625 3.3671875 WORD_SIZE: 64 LLVM: libLLVM-21.1.8 (ORCJIT, apple-m2) GC: Built with stock GC Threads: 8 default, 1 interactive, 8 GC (on 8 virtual cores) Environment: ``` This PR: ```julia-repl julia> versioninfo() Julia Version 1.14.0-DEV.2178 Build Info: Official https://julialang.org release Commit 09e1b83 (2026-05-11 13:03 UTC) GC: Built with stock GC Platform Info: OS: macOS (arm64-apple-darwin25.5.0) CPU: 12 × Apple M2 Max (apple-m2) WORD_SIZE: 64 LLVM: libLLVM-21.1.8 (ORCJIT, apple-m2) Threads: 8 default, 1 interactive, 8 GC (on 8 virtual cores) Environment: JULIA_NUM_THREADS = auto julia> versioninfo(verbose=true) Julia Version 1.14.0-DEV.2178 Build Info: Official https://julialang.org release Commit 09e1b83 (2026-05-11 13:03 UTC) GC: Built with stock GC Sysimage: generic;apple-m1,clone_all (arm64-apple-darwin24.0.0) Platform Info: OS: macOS (arm64-apple-darwin25.5.0) uname: Darwin 25.5.0 Darwin Kernel Version 25.5.0: Mon Apr 27 20:39:09 PDT 2026; root:xnu-12377.121.6~2/RELEASE_ARM64_T6020 arm64 arm CPU: Apple M2 Max (apple-m2): speed user nice sys idle irq #1-12 2400 MHz 131335 s 0 s 70450 s 1842109 s 0 s Memory: 32.0 GiB (345.53125 MiB free) Uptime: 469288.0 sec Load Avg: 3.2978515625 3.7919921875 3.37451171875 WORD_SIZE: 64 LLVM: libLLVM-21.1.8 (ORCJIT, apple-m2) Threads: 8 default, 1 interactive, 8 GC (on 8 virtual cores) Environment: ```
) Fixes JuliaLang#61805 It seems that the problem is that our `foldr_impl` is passing a non-reversed iterator to `_xfadjoint`, and then doing the actual final reduction on a reversed iterator. This is normally fine, but it interacts incorrectly with `FlatteningRF` which does a sub-reduction inside each reducing step: ```julia @inline function (op::FlatteningRF)(acc, x) op′, itr′ = _xfadjoint(op.rf, x) return _foldl_impl(op′, acc, itr′) end ``` and this sub-reduction is not reversed when it gets hit during `foldr`, resulting in the weird reduction order shown in the linked issue: ```julia julia> foldr(Iterators.flatten([["a","b"],["c","d"]])) do l, r @info "" l r l * r end ┌ Info: │ l = "d" └ r = "c" ┌ Info: │ l = "a" └ r = "dc" ┌ Info: │ l = "b" └ r = "adc" "badc" ``` This PR changes around the location of the `_reverse_iter` so that the sub-reductions are also reversed: ```julia julia> foldr(Iterators.flatten([["a","b"],["c","d"]])) do l, r @info "" l r l * r end ┌ Info: │ l = "c" └ r = "d" ┌ Info: │ l = "b" └ r = "cd" ┌ Info: │ l = "a" └ r = "bcd" "abcd" ``` --------- Co-authored-by: Andy Dienes <51664769+adienes@users.noreply.github.com> Co-authored-by: Matt Bauman <mbauman@juliahub.com>
… has no methods (JuliaLang#61700) inspired by new-user confusion I've seen on discourse, example https://discourse.julialang.org/t/scope-of-parametric-types-and-associated-error-messages/48928 ```julia julia> struct Foo{T} x::T Foo(x) = new{typeof(x)}(x) end # master julia> Foo{Int}(1) ERROR: MethodError: no method matching Foo{Int64}(::Int64) The type `Foo{Int64}` exists, but no method is defined for this combination of argument types when trying to construct it. Stacktrace: [1] top-level scope @ REPL[1]:1 # PR julia> Foo{Int}(1) ERROR: MethodError: no method matching Foo{Int64}(::Int64) The type `Foo{Int64}` exists, but no method is defined for this combination of argument types when trying to construct it. Closest candidates are: Foo(::Any) @ Main REPL[1]:3 Stacktrace: [1] top-level scope @ REPL[1]:1 ``` this might be a little controversial since we're technically lying to the user (it is a method on a different type than the one they passed) but given that it would condition it only on `isempty(methods(f))` it seems useful to me
…lity (JuliaLang#61426) ``` julia> using BenchmarkTools julia> @Btime [1.0 2; 3 4.0]; 75.248 ns (8 allocations: 336 bytes) # master 9.593 ns (2 allocations: 112 bytes) # PR julia> @Btime [1 2 3im; 4 5 6im;;;] 104.256 ns (10 allocations: 720 bytes) # master 14.236 ns (2 allocations: 176 bytes) # PR ``` replaces JuliaLang#52028 with suggestion given in JuliaLang#52028 (comment)
When a struct is redefined, we first check whether the new definition is in fact identical to the old definition, and if so we just reuse the old type. Revise leans pretty heavily on this behavior, as signature extraction relies (in corner cases) on struct definition. As identified in JuliaLang#61789, the equivalence check failed for self-referential `struct`s ```julia struct R x next::R end ``` The fix is fairly straightforward: before comparing equivalence with `equiv_field_types`, ensure that type-substitution occurs throughout the struct definition. Fixes JuliaLang#61789 This pull request was written with the assistance of generative AI (Claude Code, Opus 4.7). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…inearAlgebra-74a7cfa-master 🤖 Bump LinearAlgebra stdlib 3a7a009 → 74a7cfa
…ang#61769) JuliaLang#61764 changed the code gen for MMTk write barrier. The generated code will need to reference a global variable from `libmmtk_julia.so`. Sometimes, we see a linker error: ```console lld: error: undefined symbol: MMTK_SIDE_LOG_BIT_BASE_ADDRESS━━━ 0/84 Press `?` for help, `c` to cancel. >>> referenced by array.jl:1053 >>> text#0.o:(julia___init___0) in archive /home/yilin/Code/julia_workspace/julia/usr/share/julia/compiled/v1.14/LLVMLibUnwind_jll/jl_9aCDMN >>> referenced by array.jl:0 >>> text#0.o:(julia___init___0) in archive /home/yilin/Code/julia_workspace/julia/usr/share/julia/compiled/v1.14/LLVMLibUnwind_jll/jl_9aCDMN >>> referenced by LLVMLibUnwind_jll.jl:26 (/home/yilin/Code/julia_workspace/julia/usr/share/julia/stdlib/v1.14/LLVMLibUnwind_jll/src/LLVMLibUnwind_jll.jl:26) >>> text#0.o:(julia___init___0) in archive /home/yilin/Code/julia_workspace/julia/usr/share/julia/compiled/v1.14/LLVMLibUnwind_jll/jl_9aCDMN >>> referenced 3 more times lld: error: undefined symbol ``` This PR moves the variable from the binding to the Julia side.
I was getting some very silly results where `CodeInstance` nodes were
`UnitRange{Int64}` and `Core.DebugInfo` was `Compiler.AnalysisResults`,
etc.
Bug found by claude. Probably introduced in JuliaLang#52854, when this field went
from `size_t` to `uint8_t`.
~~todo: tests~~ would need to implement a parser for heapsnapshot
files....
Remove a spurious line. I wonder why CI didn't detect that.
…nstructors (JuliaLang#61442) The constructors documentation used `new` with implicit and explicit type parameters in examples without clearly stating the underlying rule. This adds a subsection explaining that `new` inherits the type parameters from the curly braces on the inner constructor name, when explicit parameters are needed, and what happens when the constructor name has fewer parameters than the type requires. The existing explanation in the "Outer-only constructors" section is also updated to reference this rule. The rules described here were determined empirically, as the existing documentation did not specify them. If any details are inaccurate, corrections are welcome. --------- Co-authored-by: James Wrigley <JamesWrigley@users.noreply.github.com>
Co-authored-by: Dilum Aluthge <5619885+DilumAluthge@users.noreply.github.com> Co-authored-by: Christian Guinard <28689358+christiangnrd@users.noreply.github.com> Co-authored-by: Cody Tapscott <topolarity@tapscott.me>
The processor_{x86,arm,fallback}.cpp files that included these headers
were deleted in JuliaLang#61292, which replaced the hand-maintained CPU/feature
tables with the [cpufeatures](https://github.com/JuliaLang/cpufeatures)
library. No remaining code in the tree references features_x86.h,
features_aarch32.h, or features_aarch64.h, nor the JL_FEATURE_DEF macro
they defined.
JuliaLang#61292 listed these headers under Files to delete.
…1851) On my machine this can make a _hefty_ difference: ```julia julia> using REPL julia> @time REPL.REPLCompletions.completions("Core.Compiler.", 14); 0.001048 seconds (15.47 k allocations: 945.453 KiB) # PR 3.838192 seconds (3.01 M allocations: 179.134 MiB, 2.97% gc time, 99.94% compilation time) # master ``` ```julia julia> using REPL julia> @time REPL.REPLCompletions.completions("(1+1).", 6); 0.000683 seconds (3.08 k allocations: 147.062 KiB, 47.45% compilation time) # PR 3.807135 seconds (2.99 M allocations: 178.334 MiB, 2.98% gc time, 99.98% compilation time) # master ``` Originally investigated by Claude 🤖 when I noticed that `Core.Compiler.<tab>` is _much_ slower than `Core.<tab>`. Co-authored-by: Shuhei Kadowaki <aviatesk@gmail.com>
This `jl_value_t **` array is treated as an untracked region by our static analyzer, so it is possible to copy an unrooted value into it and then extract it later without the analyzer stopping you. This function has the contract that if `p != NULL`, then `iparams == jl_svec_data(p)` and iparams is rooting storage, but otherwise iparams is not rooting. This causes us to lose track of e.g. newly-allocated normalized types from `normalize_unionall` which are stored only in `iparams`, eventually leading to GC corruption. Bug introduced in 3c2c5ce. (likely exposed somewhat by 2614585, which tweaked when type normalization allocates) Diagnosed with heavy assistance from Claude 🤖. Resolves JuliaLang#62140.
…iac` (JuliaLang#62128) JuliaC has been the canonical home for these files for some time. It's time we clean up these old copies. As a bonus, this expands our platform / test support for `--trim` to cover all of our CI platforms. Likely requires JuliaLang#62121 for FreeBSD and we'll want to update `julia-buildkite` to remove / filter the unneeded separate `trimming` job. This will need a follow-up PR to https://github.com/JuliaCI/julia-buildkite/ to enable the new `trim` test. --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Resolve `IRShow` debuginfo helpers through the active `Compiler` module instead of `Base.Compiler`. This keeps `IRCode` printing working when `Compiler` is loaded as a stdlib and owns the `DebugInfoStream` values being printed. Following up JuliaLang#61979. Co-authored-by: GPT-5.5 <noreply@openai.com>
Remove unused locals and mark intentionally unused callback arguments in IRShow printing helpers. Driven by changes I made with JuliaLang#62155. JETLS found them. Co-authored-by: GPT-5.5 <noreply@openai.com>
This should improve both invalidations and `--trim` support.
…liaLang#62153) Byte-precise `DebugInfo` (JuliaLang#61991) constructs `Core.DebugInfo` with a `String` linetable, but only recent Julia's constructor accepts a `String` there (older versions, e.g. v1.12, accept only `Union{Nothing,DebugInfo}`). As a result `add_debuginfo!` raised a `MethodError` on those versions, which made lowering itself impossible. Detect whether a `String` linetable is supported and, when it is not, degrade byte spans to line numbers and emit line-based `DebugInfo` (the same shape as the `LineNumberNode` path), so lowering still produces a valid `CodeInfo`. The byte-precise path on recent Julia is unaffected. While JuliaLowering targets nightly and full compatibility is a non-goal, it is desirable to retain minimal, lowering-only v1.12 compatibility: JETLS still targets v1.12 currently and relies on JL's lowering (then runs inference on the resulting `CodeInfo`), without going through `JuliaLowering.eval`. Remaining incompatibilities are confined to the `eval` path (`Core.declare_const`, `jl_begin_new_module`/ `jl_end_new_module`) and are intentionally left unaddressed here. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
More quiet tests + 32-bit support
Split argument datatype lookup from common typename lookup and compute reflection field counts structurally, so union types with mismatched field counts are rejected while same-layout unions remain supported. Fixes JuliaLang#62098 Co-authored-by: Keno Fischer <Keno@users.noreply.github.com> Co-authored-by: OpenAI Codex <codex@openai.com>
Make several small passes.jl cleanups that clarify existing invariants
and help a code analyzer:
- Make `perform_lifting!` assert non-empty lifted leaves, return
`Union{LiftedValue, Nothing}` instead of `Any`, and dispatch final
statement-value resolution on `LiftedLeaves` vs `LiftedDefs`. This makes
explicit that definition lifting resolves through lifted phi-like values
and must not return raw boolean leaf values.
- Remove an unreachable `compact.result` reference from CFG
simplification
- Initialize conditionally assigned locals, mark intentionally unused
bindings with `_` names, and remove stale unused locals/comments.
Also fix-up `show` implementation for `WindowsRawSocket`, for `--trim` compat in both cases. This was improved in JuliaLang#62158 but not completely fixed.
This should be enough to enable the new, multi-platform `trim` tests.
…59663) This commit includes several, interlocked changes: 1. It removes an undocumented SubString constructor which triage has agreed can be considered internal and should be removed * EDIT: After triage comments, the method is now deprecated, but not removed. 2. It adds a new public, but unexported function `raw_substring`, which creates a substring without checking for valid string indices. This new function is used in place of the old removed method, internally in Julia. * EDIT: After triage comments, this was renamed from `unsafe_substring` to `raw_substring` 3. It adds a new public, but unexported function `unannotate`, which gives the underlying non-annotated string of an `AnnotatedString` or `SubString{AnnotatedString}`. The reason for this change is that currently, code outside Base (namely, in StyledStrings and JuliaSyntaxHighlighting) relies on this operation. Its current implementation reaches into both `AnnotatedString` and `SubString` internals. Instead, I provide the function here in Base, and let the two stdlibs use it. Also in general, I think it's a completely reasonable basic function to have for annotated strings. For reviewers: We can make these functions exported (I don't have a strong opinion on that). For this PR to land, it also requires compatible PRs in StyledStrings.jl and JuliaSyntaxHighlighting.jl, which uses the removed constructor. This depends on two PRs to be merged first: 1. JuliaLang/JuliaSyntaxHighlighting.jl#13 2. JuliaLang/StyledStrings.jl#125 Supersedes JuliaLang#59606 Supersedes JuliaLang#55458 Closes JuliaLang#59610 Closes JuliaLang#55247
Switch Windows executable and DLL link recipes to invoke $(LD) directly and stage the MinGW CRT startup objects and import libraries from CompilerSupportLibraries. This keeps Julia's Windows build on the bundled runtime libraries instead of mixing in host MinGW CRT files.
The path.exists? femtolisp builtin has no callers anywhere in Julia: the flisp front-end scripts and the bundled boot image never reference it, and Julia stats the filesystem through libuv rather than flisp. Drop the dead fl_path_exists function, its builtin-table entry, and the now-unneeded <sys/types.h>/<sys/stat.h> includes. This is motivated by avoiding POSIX `stat` in the codebase (everything else already uses libuv), which on windows is provided by mingw shims that have runtime-library-version-dependent ABI. Co-authored-by: Keno Fischer <Keno@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…62179) The Windows strptime matches %Z against the process timezone names via the _tzname global. Newer mingw-w64 redirects the _tzname macro to a different CRT symbol (__tzname / __imp___tzname); when the host compiler's headers are newer than the bundled CompilerSupportLibraries CRT import library (as after JuliaLang#62152) that symbol is not exported by the bundled library and the link fails: src/support/strptime.c:625: undefined reference to `__imp___tzname' For non-UCRT targets, #undef the macro and re-declare the classic dllimport char *_tzname[2]. That references the __imp__tzname symbol, which the bundled msvcrt import library still provides, so it links regardless of the host header vintage and across both 32- and 64-bit mingw-w64. Co-authored-by: Keno Fischer <Keno@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Opaque closures created inside another closure could leave captured
locals from the enclosing closure as raw `BindingId` nodes in the
`new_opaque_closure` arguments. Linearization then failed because those
bindings were not native slots of the current lambda:
```julia-repl
julia> JuliaLowering.include_string(Main, """
let y = [1]
outer = Base.Experimental.@opaque () -> begin
inner = Base.Experimental.@opaque n -> n in y
inner(1)
end
outer()
end
""")
ERROR: LoweringError:
let y = [1]
outer = Base.Experimental.@opaque () -> begin
inner = Base.Experimental.@opaque n -> n in y
Detailed provenance:
#₄/y @#= /Users/aviatesk/julia/julia/JuliaLowering/src/bindings.jl:123 =#
└─ y
└─ y
└─ @ string:1
Stacktrace:
[1] _renumber(ctx::JuliaLowering.LinearIRContext{…}, ssa_rewrites::Dict{…}, slot_rewrites::Dict{…}, label_table::Dict{…}, ex::JuliaSyntax.SyntaxTree{…})
@ JuliaLowering ~/julia/julia/JuliaLowering/src/linear_ir.jl:1097
[2] (::JuliaLowering.var"#_renumber##2#_renumber##3"{JuliaLowering.LinearIRContext{…}, Dict{…}, Dict{…}, Dict{…}})(e::JuliaSyntax.SyntaxTree{Dict{…}})
@ JuliaLowering ~/julia/julia/JuliaLowering/src/linear_ir.jl:1120 [inlined]
[3] mapchildren(f::JuliaLowering.var"#_renumber##2#_renumber##3"{…}, ctx::JuliaLowering.LinearIRContext{…}, ex::JuliaSyntax.SyntaxTree{…})
@ JuliaSyntax ~/julia/julia/JuliaSyntax/src/porcelain/syntax_graph.jl:722
...
```
Convert opaque closure type bounds in the current closure-conversion
context and initialize capture arguments from the enclosing closure's
capture storage when needed. This preserves boxed storage for mutable
captures while allowing nested opaque closures to capture values from
their enclosing closure.
---------
Co-authored-by: GPT-5.5 <noreply@openai.com>
Co-authored-by: Em Chu <61633163+mlechu@users.noreply.github.com>
…a jobserver (JuliaLang#61958) Fixes JuliaLang#58591 Parallel package precompilation previously let every worker independently claim half the machine's cores for native-image codegen, oversubscribing the CPU when many workers hit the imaging phase at once while leaving cores idle during the long tail when only one big job remained. ## Design The orchestrating precompile process creates a named-semaphore token pool sized to `Sys.EFFECTIVE_CPU_THREADS + 1` and shares it with worker subprocesses via the `JULIA_IMAGE_JOBSERVER` environment variable. The tokens form a single CPU budget that covers both the worker processes and their imaging threads, rather than two budgets that multiply: - The orchestrator holds one baseline token per CPU-active worker. Since a worker's main thread sleeps while its imaging threads run, that baseline doubles as the imaging phase's first codegen thread instead of being counted twice. - Each worker's imaging thread pool is elastic: shards are compiled from a work queue, and the pool starts with the baseline thread plus whatever tokens are free right then, keeps polling for tokens released by sibling workers while it still has unclaimed shards, and returns each token to the pool as soon as the thread holding it runs out of work. A worker that entered the imaging phase on a busy machine expands into cores as neighbors finish, and a draining worker feeds busy ones instead of idling the rest of its allotment until the slowest shard completes. - Setting `JULIA_IMAGE_THREADS` still pins a fixed per-worker thread count and takes precedence over the jobserver. Token acquisition can never hang precompilation: waiting is bounded by a timeout and a cancellation check and degrades to bounded oversubscription (the pre-jobserver behavior) if the pool is unavailable, e.g. if tokens were leaked by a killed worker. Only one jobserver can be active per process; a concurrent in-process precompile session falls back to uncoordinated behavior rather than corrupting the live pool. ## Results Precompiling an environment with GLMakie and Plots from a cleared cache went from 193s to 182s (~6% faster) on a 6-core M2 MacBook, with user CPU time essentially unchanged — the speedup comes from better balance, not extra work. Previously we both undersubscribed (idle cores during the long tail) and, more egregiously, oversubscribed (when many packages hit the imaging phase at the same time). master d2936ef ``` julia> Base.Precompilation.precompilepkgs(timing=true, verbose=true) Precompiling project... total │ include (deps) (comp) │ methods img-gen cache ~pk-rss ... 28.0 s │ 18.29s 4.29s 12.54s │ 36014 9.70s 44.0MB 1689MB ✓ Plots ... 88.3 s │ 56.21s 14.33s 37.16s │ 104623 32.14s 146.6MB 3302MB ✓ Makie 44.1 s │ 26.89s 8.10s 16.95s │ 36975 17.19s 49.8MB 2731MB ✓ GLMakie 316 dependencies successfully precompiled in 193 seconds. 41 already precompiled. ``` PR ``` total │ include (deps) (comp) │ methods img-gen cache ~pk-rss ... 24.9 s │ 17.30s 3.52s 12.38s │ 36015 7.60s 44.0MB 1772MB ✓ Plots ... 80.0 s │ 56.00s 14.22s 37.10s │ 104626 23.95s 146.6MB 3254MB ✓ Makie 39.3 s │ 26.78s 8.33s 16.74s │ 36979 12.48s 49.8MB 2771MB ✓ GLMakie 316 dependencies successfully precompiled in 182 seconds. 41 already precompiled. ``` ## Relation to JuliaLang#58591 The issue settled on "a jobserver like make". This implementation targets the case thaultiple large packages hitting image generation at once (e.g. GLMakie + DiffEq) — while leaving the already-saturated bulk phase untouched. Because the imaging pool is elastic, a worker is no longer stuck with whatever was free at spawn or phase-entry time: it grows back up after a neighbor finishes. Named semaphores give Windows support for free (the same primitive mposable with the LLVM jobserver (llvm/llvm-project#145131), which isn't in our bundled LLVM 21. It is not yet wire-compatible with the GNU make jobserver protocol; making it speak that protocol is a natural follow-up. This also supersedes JuliaLang#60794, delivering the same all-cores tail benefit but bounded so it can't reintroduce oversubscription. Fixes JuliaLang#58591 Closes JuliaLang#60794 Co-authored-by: Claude <claude@users.noreply.github.com>
…nds (JuliaLang#62109) See discussion in JuliaLang#62099. This moves towards the proposed rule and in particular addressed the motivating example, but is not yet a principled implementation of that rule. --------- Co-authored-by: Keno Fischer <Keno@users.noreply.github.com> Co-authored-by: OpenAI Codex <codex@openai.com>
…Lang#62187) See the message length in JuliaLang#62186 Limit the number of loaded package names shown in the precompilation summary warning and append an "N more" suffix when the list is longer than the cap. This keeps the message readable when many packages are already loaded. Co-authored-by: GitHub Copilot <copilot@users.noreply.github.com>
Keno
force-pushed
the
kf/subtype-forall-ub-split
branch
from
June 22, 2026 22:21
e6ae6ae to
c9df31c
Compare
A left-side (universally quantified) `where` variable with a trivial
lower bound, a union upper bound, and only covariant occurrences in the
body ranges over each arm of its upper bound independently, i.e. the
UnionAll distributes over the arms:
(Tuple{T,T} where T<:Union{A,B}) ==
Union{Tuple{T,T} where T<:A, Tuple{T,T} where T<:B}
(diagonality, if any, is preserved: each value of such a variable is
concrete and therefore lies entirely within a single arm).
Exploit this in `subtype_unionall` on the ∀ path by splitting the upper
bound before descending into the body: descend the ub's Union tree with
`pick_union_decision(e, 0)`, so each Union node registers as an ordinary
left-union decision and the enclosing ∀∃ loop enumerates all arms. This
makes judgments like
(Tuple{T,T} where T<:Union{Float64,Int64}) <:
Union{Tuple{Float64,Float64},Tuple{Int64,Int64}}
true, and fixes a previously `@test_broken` type equality. The gate is
checked by a new static walker: covariant here means reachable purely
through Tuple parameters, Union components, and Vararg element types;
any occurrence under a non-Tuple datatype parameter, in a Vararg length,
or inside an inner UnionAll disables the split. The ∃ side, lower
bounds, and intersection are unaffected.
`jl_obvious_subtype` was verified to return "unknown" (never
definitely-false) on the newly-true judgments, so it cannot mask the new
result in release builds nor trip the consistency assert in debug
builds.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Keno
force-pushed
the
kf/subtype-forall-ub-split
branch
from
June 22, 2026 22:38
c9df31c to
3bb0611
Compare
Keno
pushed a commit
that referenced
this pull request
Aug 13, 2026
…2491) `CodeInstance.def` is Any so everything downstream of `mi` also got inferred to Any. Should fix these invalidations seen when loading CUDA.jl on 1.13: ```julia inserting any(f::Function, a::StaticArraysCore.StaticArray; dims) @ StaticArrays ~/.julia/packages/StaticArrays/0cEwi/src/mapreduce.jl:308 invalidated: backedges: 1: superseding any(f::Function, a::AbstractArray; dims) @ Base reducedim.jl:993 with MethodInstance for any(::Compiler.var"#compileable_specialization##0#compileable_specialization##1", ::AbstractArray) (584 children) ``` That being said I couldn't actually test it because GPUCompiler currently doesn't work on nightly, so it was confirmed by `code_warntype` inspection. Importantly, `mi` is now inferred as a `MethodInstance` so `mi.sparam_vals` infers to `SimpleVector`. Debugged with Claude Code
Keno
pushed a commit
that referenced
this pull request
Sep 10, 2026
Discovered (with help of Claude) that in 1.13, the first version where
my prior changes to stacktrace cycle printing are landing, has a flaw -
more than two frames in the cycle, and the brackets are printed on the
wrong frames, even being left unclosed:
```
Stacktrace:
[1] error()
@ Base .\error.jl:45
[2] r(n::Int64)
@ Main .\REPL[9]:1
[3] (::var"#r##0#r##1"{Int64})(::Int64)
@ Main .\REPL[9]:1
[4] iterate
@ .\generator.jl:48 [inlined]
[5] _collect(c::UnitRange{Int64}, itr::Base.Generator{UnitRange{Int64}, var"#r##0#r##1"{Int64}}, ::Base.EltypeUnknown, isz::Base.HasShape{1})
@ Base .\array.jl:848
┌ [6] collect_similar(cont::UnitRange{Int64}, itr::Base.Generator{UnitRange{Int64}, var"#r##0#r##1"{Int64}})
│ @ Base .\array.jl:763
├ [7] map(f::Function, A::UnitRange{Int64})
│ @ Base .\abstractarray.jl:3396
├ [8] r(n::Int64)
│ @ Main .\REPL[9]:1
├ [9] top-level scope
│ @ REPL[10]:1
```
This PR fixes this:
```
Stacktrace:
[1] error()
┌ [2] r(n::Int64)
├ [3] (::var"#r_map##0#r_map##1"{Int64})(::Int64)
├ [4] iterate(::Base.Generator{...})
├ [5] _collect(c::UnitRange{Int64}, ...)
├ [6] collect_similar(cont::UnitRange{Int64}, ...)
├ [7] map(f::Function, A::UnitRange{Int64})
╰───── repeated 10 times
[62] r(n::Int64)
```
Side-effect is that the presentation order of the nested example flips
(b/c all else equal, inner cycle now comes first instead of last), which
is why that test changed.
Please mark for 1.13 backport.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A left-side (universally quantified)
wherevariable with a trivial lower bound, a union upper bound, and only covariant occurrences in the body ranges over each arm of its upper bound independently, i.e. the UnionAll distributes over the arms:(Tuple{T,T} where T<:Union{A,B}) == Union{Tuple{T,T} where T<:A, Tuple{T,T} where T<:B}(diagonality, if any, is preserved: each value of such a variable is concrete and therefore lies entirely within a single arm).
Exploit this in
subtype_unionallon the ∀ path by splitting the upper bound before descending into the body: descend the ub's Union tree withpick_union_decision(e, 0), so each Union node registers as an ordinary left-union decision and the enclosing ∀∃ loop enumerates all arms. This makes judgments like(Tuple{T,T} where T<:Union{Float64,Int64}) <: Union{Tuple{Float64,Float64},Tuple{Int64,Int64}}true, and fixes a previously
@test_brokentype equality. The gate is checked by a new static walker: covariant here means reachable purely through Tuple parameters, Union components, and Vararg element types; any occurrence under a non-Tuple datatype parameter, in a Vararg length, or inside an inner UnionAll disables the split. The ∃ side, lower bounds, and intersection are unaffected.jl_obvious_subtypewas verified to return "unknown" (never definitely-false) on the newly-true judgments, so it cannot mask the new result in release builds nor trip the consistency assert in debug builds.Since
jl_types_equaland specificity results may shift, a PkgEval run is advisable. Thesubtype,specificity,ambiguous, andcoretest suites pass locally, as doclang-sa-subtypeandclang-sagc-subtype.This pull request was written with the assistance of generative AI (Claude).
🤖 Generated with Claude Code