From 19bda2628c53fc89837868e2ae77ae03eb8c750e Mon Sep 17 00:00:00 2001 From: Andy Dienes Date: Mon, 23 Feb 2026 11:52:59 -0500 Subject: [PATCH 1/4] enforce issimpleenoughtype in fast path for tmerge for PartialStruct --- Compiler/src/typelimits.jl | 4 +++- Compiler/test/inference.jl | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Compiler/src/typelimits.jl b/Compiler/src/typelimits.jl index 99f5c4185067f..fe1161f455782 100644 --- a/Compiler/src/typelimits.jl +++ b/Compiler/src/typelimits.jl @@ -677,7 +677,9 @@ end @nospecializeinfer function tmerge(lattice::PartialsLattice, @nospecialize(typea), @nospecialize(typeb)) r = tmerge_fast_path(lattice, typea, typeb) - r !== nothing && return r + if r !== nothing + return (isa(r, PartialStruct) && !issimpleenoughtype(r.typ)) ? widenconst(r) : r + end # type-lattice for Const and PartialStruct wrappers aps = isa(typea, PartialStruct) diff --git a/Compiler/test/inference.jl b/Compiler/test/inference.jl index eb559caca3717..40e45fe0136c6 100644 --- a/Compiler/test/inference.jl +++ b/Compiler/test/inference.jl @@ -6563,4 +6563,10 @@ throwconditional(c, x) = c ? throw(x isa Int) : throw(x isa Float64) throwconditional(c, x) end == Bool +# issue #60715 +let + f() = 1; f(_, x...) = (0, f(x...)) + @test f(1, 2, 3) == (0, (0, (0, 1))) +end + end # module inference From d9b477ab27a7165477623342cfc205d30483472b Mon Sep 17 00:00:00 2001 From: Andy Dienes Date: Mon, 23 Feb 2026 13:56:49 -0500 Subject: [PATCH 2/4] catch in issimplertype rather than after tmerge_fast_path --- Compiler/src/typelimits.jl | 5 ++--- Compiler/test/inference.jl | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/Compiler/src/typelimits.jl b/Compiler/src/typelimits.jl index fe1161f455782..d6f1ba91dec0f 100644 --- a/Compiler/src/typelimits.jl +++ b/Compiler/src/typelimits.jl @@ -338,6 +338,7 @@ end typea === typeb && return true if typea isa PartialStruct aty = widenconst(typea) + issimpleenoughtype(aty) || return false if typeb isa Const || typeb isa PartialStruct @assert n_initialized(typea) โ‰ค n_initialized(typeb) "typeb โŠ‘ typea is assumed" elseif typeb isa PartialStruct @@ -677,9 +678,7 @@ end @nospecializeinfer function tmerge(lattice::PartialsLattice, @nospecialize(typea), @nospecialize(typeb)) r = tmerge_fast_path(lattice, typea, typeb) - if r !== nothing - return (isa(r, PartialStruct) && !issimpleenoughtype(r.typ)) ? widenconst(r) : r - end + r !== nothing && return r # type-lattice for Const and PartialStruct wrappers aps = isa(typea, PartialStruct) diff --git a/Compiler/test/inference.jl b/Compiler/test/inference.jl index 40e45fe0136c6..874824d41a7ff 100644 --- a/Compiler/test/inference.jl +++ b/Compiler/test/inference.jl @@ -5077,6 +5077,22 @@ let ๐•ƒแตข = Compiler.fallback_lattice @test t.fields == Any[Const(42), Int] end +# issue #60715 +let ๐•ƒ = Compiler.fallback_lattice + local fn, fn1, pn, pn1 + F(n) = iszero(n) ? Union{} : Tuple{Int, Union{Int, F(n-1)}} + P(n) = (f = F(n); Compiler.PartialStruct(๐•ƒ, f, [Const(0), fieldtype(f, 2)])) + + n = 0 + while Compiler.issimpleenoughtype(F(n+1)) + n += 1 + fn, fn1, pn, pn1 = F(n), F(n+1), P(n), P(n+1) + @test Compiler.:โŠ‘(๐•ƒ, pn, pn1) + end + @test !Compiler.issimplertype(๐•ƒ, pn1, pn) + @test !isa(Compiler.tmerge(๐•ƒ, pn, pn1), Compiler.PartialStruct) +end + foo_empty_vararg(i...) = i[2] bar_empty_vararg(i) = foo_empty_vararg(10, 20, 30, i...) @test bar_empty_vararg(Union{}[]) === 20 From 0696471347e05de4084e04ce98a750a64ba26428 Mon Sep 17 00:00:00 2001 From: Andy Dienes <51664769+adienes@users.noreply.github.com> Date: Mon, 23 Feb 2026 15:59:10 -0500 Subject: [PATCH 3/4] Update Compiler/src/typelimits.jl Co-authored-by: Jameson Nash --- Compiler/src/typelimits.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Compiler/src/typelimits.jl b/Compiler/src/typelimits.jl index d6f1ba91dec0f..337a673e6b20f 100644 --- a/Compiler/src/typelimits.jl +++ b/Compiler/src/typelimits.jl @@ -338,7 +338,7 @@ end typea === typeb && return true if typea isa PartialStruct aty = widenconst(typea) - issimpleenoughtype(aty) || return false + issimplertype(aty, widenconst(bty)) || return false if typeb isa Const || typeb isa PartialStruct @assert n_initialized(typea) โ‰ค n_initialized(typeb) "typeb โŠ‘ typea is assumed" elseif typeb isa PartialStruct From 4ab4c38cc5c6289cadfc3d5463711b4aa60a0142 Mon Sep 17 00:00:00 2001 From: Andy Dienes Date: Mon, 23 Feb 2026 16:06:49 -0500 Subject: [PATCH 4/4] fixup --- Compiler/src/typelimits.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Compiler/src/typelimits.jl b/Compiler/src/typelimits.jl index 337a673e6b20f..2d025221c77b9 100644 --- a/Compiler/src/typelimits.jl +++ b/Compiler/src/typelimits.jl @@ -338,7 +338,7 @@ end typea === typeb && return true if typea isa PartialStruct aty = widenconst(typea) - issimplertype(aty, widenconst(bty)) || return false + issimplertype(๐•ƒ, aty, widenconst(typeb)) || return false if typeb isa Const || typeb isa PartialStruct @assert n_initialized(typea) โ‰ค n_initialized(typeb) "typeb โŠ‘ typea is assumed" elseif typeb isa PartialStruct