From 87d8e19b39d2c7485999349b58dd45d207652207 Mon Sep 17 00:00:00 2001 From: Penelope Yong Date: Sun, 6 Jul 2025 12:27:12 +0100 Subject: [PATCH 1/6] AbstractPPL@0.12 --- HISTORY.md | 4 ++++ Project.toml | 4 ++-- docs/Project.toml | 2 +- test/Project.toml | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index e67ceba0a..0d2a56606 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # DynamicPPL Changelog +## 0.36.14 + +Added compatibility with AbstractPPL@0.12. + ## 0.36.13 Added documentation for the `returned(::Model, ::MCMCChains.Chains)` method. diff --git a/Project.toml b/Project.toml index cd473354c..351fe6365 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "DynamicPPL" uuid = "366bfd00-2699-11ea-058f-f148b4cae6d8" -version = "0.36.13" +version = "0.36.14" [deps] ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" @@ -46,7 +46,7 @@ DynamicPPLMooncakeExt = ["Mooncake"] [compat] ADTypes = "1" AbstractMCMC = "5" -AbstractPPL = "0.11" +AbstractPPL = "0.11, 0.12" Accessors = "0.1" BangBang = "0.4.1" Bijectors = "0.13.18, 0.14, 0.15" diff --git a/docs/Project.toml b/docs/Project.toml index c00c29c96..3f258909a 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -14,7 +14,7 @@ MCMCChains = "c7f686f2-ff18-58e9-bc7b-31028e88f75d" StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3" [compat] -AbstractPPL = "0.11" +AbstractPPL = "0.11, 0.12" Accessors = "0.1" DataStructures = "0.18" Distributions = "0.25" diff --git a/test/Project.toml b/test/Project.toml index 4f9ff4220..afecba1c4 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -30,7 +30,7 @@ Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [compat] ADTypes = "1" AbstractMCMC = "5" -AbstractPPL = "0.11" +AbstractPPL = "0.11, 0.12" Accessors = "0.1" Aqua = "0.8" Bijectors = "0.15.1" From 0d4cbba2cf6b8258221784e34089dd7bface2f81 Mon Sep 17 00:00:00 2001 From: Penelope Yong Date: Sun, 6 Jul 2025 12:33:06 +0100 Subject: [PATCH 2/6] Replace removed VarName constructor --- src/simple_varinfo.jl | 8 +++-- src/utils.jl | 76 ++++++++++++++++++++----------------------- 2 files changed, 41 insertions(+), 43 deletions(-) diff --git a/src/simple_varinfo.jl b/src/simple_varinfo.jl index 3ae425896..92a08a1b6 100644 --- a/src/simple_varinfo.jl +++ b/src/simple_varinfo.jl @@ -356,13 +356,15 @@ function BangBang.setindex!!(vi::SimpleVarInfo, vals, vns::AbstractVector{<:VarN return vi end -function BangBang.setindex!!(vi::SimpleVarInfo{<:AbstractDict}, val, vn::VarName) +function BangBang.setindex!!( + vi::SimpleVarInfo{<:AbstractDict}, val, vn::VarName{sym} +) where {sym} # For dictlike objects, we treat the entire `vn` as a _key_ to set. dict = values_as(vi) # Attempt to split into `parent` and `child` optic. parent, child, issuccess = splitoptic(getoptic(vn)) do optic o = optic === nothing ? identity : optic - haskey(dict, VarName(vn, o)) + haskey(dict, VarName{sym}(o)) end # When combined with `VarInfo`, `nothing` is equivalent to `identity`. keyoptic = parent === nothing ? identity : parent @@ -372,7 +374,7 @@ function BangBang.setindex!!(vi::SimpleVarInfo{<:AbstractDict}, val, vn::VarName BangBang.setindex!!(dict, val, vn) else # Split exists ⟹ trying to set an existing key. - vn_key = VarName(vn, keyoptic) + vn_key = VarName{sym}(keyoptic) BangBang.setindex!!(dict, set!!(dict[vn_key], child, val), vn_key) end return Accessors.@set vi.values = dict_new diff --git a/src/utils.jl b/src/utils.jl index d828fd771..e219b34a2 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -595,9 +595,9 @@ julia> (parent ∘ parent ∘ parent)(@varname(x.a[1])) x ``` """ -function parent(vn::VarName) +function parent(vn::VarName{sym}) where {sym} p = parent(getoptic(vn)) - return p === nothing ? VarName(vn, identity) : VarName(vn, p) + return p === nothing ? VarName{sym}(identity) : VarName{sym}(p) end """ @@ -712,7 +712,7 @@ ERROR: Could not find x.a[2] in x.a[1] function remove_parent_optic(vn_parent::VarName{sym}, vn_child::VarName{sym}) where {sym} _, child, issuccess = splitoptic(getoptic(vn_child)) do optic o = optic === nothing ? identity : optic - VarName(vn_child, o) == vn_parent + o == getoptic(vn_parent) end issuccess || error("Could not find $vn_parent in $vn_child") @@ -898,7 +898,7 @@ end # For `dictlike` we need to check wether `vn` is "immediately" present, or # if some ancestor of `vn` is present in `dictlike`. -function hasvalue(vals::AbstractDict, vn::VarName) +function hasvalue(vals::AbstractDict, vn::VarName{sym}) where {sym} # First we check if `vn` is present as is. haskey(vals, vn) && return true @@ -907,7 +907,7 @@ function hasvalue(vals::AbstractDict, vn::VarName) # If `issuccess` is `true`, we found such a split, and hence `vn` is present. parent, child, issuccess = splitoptic(getoptic(vn)) do optic o = optic === nothing ? identity : optic - haskey(vals, VarName(vn, o)) + haskey(vals, VarName{sym}(o)) end # When combined with `VarInfo`, `nothing` is equivalent to `identity`. keyoptic = parent === nothing ? identity : parent @@ -916,7 +916,7 @@ function hasvalue(vals::AbstractDict, vn::VarName) issuccess || return false # At this point we just need to check that we `canview` the value. - value = vals[VarName(vn, keyoptic)] + value = vals[VarName{sym}(keyoptic)] return canview(child, value) end @@ -927,7 +927,7 @@ end Return value corresponding to `vn` in `values` by also looking in the the actual values of the dict. """ -function nested_getindex(values::AbstractDict, vn::VarName) +function nested_getindex(values::AbstractDict, vn::VarName{sym}) where {sym} maybeval = get(values, vn, nothing) if maybeval !== nothing return maybeval @@ -936,7 +936,7 @@ function nested_getindex(values::AbstractDict, vn::VarName) # Split the optic into the key / `parent` and the extraction optic / `child`. parent, child, issuccess = splitoptic(getoptic(vn)) do optic o = optic === nothing ? identity : optic - haskey(values, VarName(vn, o)) + haskey(values, VarName{sym}(o)) end # When combined with `VarInfo`, `nothing` is equivalent to `identity`. keyoptic = parent === nothing ? identity : parent @@ -949,7 +949,7 @@ function nested_getindex(values::AbstractDict, vn::VarName) # TODO: Should we also check that we `canview` the extracted `value` # rather than just let it fail upon `get` call? - value = values[VarName(vn, keyoptic)] + value = values[VarName{sym}(keyoptic)] return child(value) end @@ -1065,22 +1065,24 @@ x.z[2][1] ``` """ varname_leaves(vn::VarName, ::Real) = [vn] -function varname_leaves(vn::VarName, val::AbstractArray{<:Union{Real,Missing}}) +function varname_leaves( + vn::VarName{sym}, val::AbstractArray{<:Union{Real,Missing}} +) where {sym} return ( - VarName(vn, Accessors.IndexLens(Tuple(I)) ∘ getoptic(vn)) for + VarName{sym}(Accessors.IndexLens(Tuple(I)) ∘ getoptic(vn)) for I in CartesianIndices(val) ) end -function varname_leaves(vn::VarName, val::AbstractArray) +function varname_leaves(vn::VarName{sym}, val::AbstractArray) where {sym} return Iterators.flatten( - varname_leaves(VarName(vn, Accessors.IndexLens(Tuple(I)) ∘ getoptic(vn)), val[I]) + varname_leaves(VarName{sym}(Accessors.IndexLens(Tuple(I)) ∘ getoptic(vn)), val[I]) for I in CartesianIndices(val) ) end -function varname_leaves(vn::VarName, val::NamedTuple) - iter = Iterators.map(keys(val)) do sym - optic = Accessors.PropertyLens{sym}() - varname_leaves(VarName(vn, optic ∘ getoptic(vn)), optic(val)) +function varname_leaves(vn::VarName{sym}, val::NamedTuple) where {sym} + iter = Iterators.map(keys(val)) do k + optic = Accessors.PropertyLens{k}() + varname_leaves(VarName{sym}(optic ∘ getoptic(vn)), optic(val)) end return Iterators.flatten(iter) end @@ -1225,30 +1227,26 @@ value(leaf::Leaf) = leaf.value # Leaf-types. varname_and_value_leaves_inner(vn::VarName, x::Real) = [Leaf(vn, x)] function varname_and_value_leaves_inner( - vn::VarName, val::AbstractArray{<:Union{Real,Missing}} -) + vn::VarName{sym}, val::AbstractArray{<:Union{Real,Missing}} +) where {sym} return ( Leaf( - VarName(vn, DynamicPPL.Accessors.IndexLens(Tuple(I)) ∘ DynamicPPL.getoptic(vn)), - val[I], + VarName{sym}(Accessors.IndexLens(Tuple(I)) ∘ AbstractPPL.getoptic(vn)), val[I] ) for I in CartesianIndices(val) ) end # Containers. -function varname_and_value_leaves_inner(vn::VarName, val::AbstractArray) +function varname_and_value_leaves_inner(vn::VarName{sym}, val::AbstractArray) where {sym} return Iterators.flatten( varname_and_value_leaves_inner( - VarName(vn, DynamicPPL.Accessors.IndexLens(Tuple(I)) ∘ DynamicPPL.getoptic(vn)), - val[I], + VarName{sym}(Accessors.IndexLens(Tuple(I)) ∘ AbstractPPL.getoptic(vn)), val[I] ) for I in CartesianIndices(val) ) end -function varname_and_value_leaves_inner(vn::DynamicPPL.VarName, val::NamedTuple) - iter = Iterators.map(keys(val)) do sym - optic = DynamicPPL.Accessors.PropertyLens{sym}() - varname_and_value_leaves_inner( - VarName{getsym(vn)}(optic ∘ getoptic(vn)), optic(val) - ) +function varname_and_value_leaves_inner(vn::VarName{sym}, val::NamedTuple) where {sym} + iter = Iterators.map(keys(val)) do k + optic = Accessors.PropertyLens{k}() + varname_and_value_leaves_inner(VarName{sym}(optic ∘ getoptic(vn)), optic(val)) end return Iterators.flatten(iter) @@ -1262,22 +1260,20 @@ function varname_and_value_leaves_inner(vn::VarName, x::Cholesky) varname_and_value_leaves_inner(Accessors.PropertyLens{:U}() ∘ vn, x.U) end end -function varname_and_value_leaves_inner(vn::VarName, x::LinearAlgebra.LowerTriangular) +function varname_and_value_leaves_inner( + vn::VarName{sym}, x::LinearAlgebra.LowerTriangular +) where {sym} return ( - Leaf( - VarName(vn, DynamicPPL.Accessors.IndexLens(Tuple(I)) ∘ DynamicPPL.getoptic(vn)), - x[I], - ) + Leaf(VarName{sym}(Accessors.IndexLens(Tuple(I)) ∘ AbstractPPL.getoptic(vn)), x[I]) # Iteration over the lower-triangular indices. for I in CartesianIndices(x) if I[1] >= I[2] ) end -function varname_and_value_leaves_inner(vn::VarName, x::LinearAlgebra.UpperTriangular) +function varname_and_value_leaves_inner( + vn::VarName{sym}, x::LinearAlgebra.UpperTriangular +) where {sym} return ( - Leaf( - VarName(vn, DynamicPPL.Accessors.IndexLens(Tuple(I)) ∘ DynamicPPL.getoptic(vn)), - x[I], - ) + Leaf(VarName{sym}(Accessors.IndexLens(Tuple(I)) ∘ AbstractPPL.getoptic(vn)), x[I]) # Iteration over the upper-triangular indices. for I in CartesianIndices(x) if I[1] <= I[2] ) From 29821296c03271073b3d93ee28c9d5f33a5e2581 Mon Sep 17 00:00:00 2001 From: Penelope Yong Date: Mon, 7 Jul 2025 01:11:08 +0100 Subject: [PATCH 3/6] Hotfix for Julia 1.10 claiming that istrans is type unstable --- src/abstract_varinfo.jl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/abstract_varinfo.jl b/src/abstract_varinfo.jl index f11b8a3ec..28bf488fa 100644 --- a/src/abstract_varinfo.jl +++ b/src/abstract_varinfo.jl @@ -481,7 +481,15 @@ If `vns` is provided, then only check if this/these varname(s) are transformed. """ istrans(vi::AbstractVarInfo) = istrans(vi, collect(keys(vi))) function istrans(vi::AbstractVarInfo, vns::AbstractVector) - return !isempty(vns) && all(Base.Fix1(istrans, vi), vns) + # This used to be: `!isempty(vns) && all(Base.Fix1(istrans, vi), vns)`. + # In theory that should work perfectly fine. For unbeknownst reasons, + # Julia 1.10 fails to infer its return type correctly. Thus we use this + # slightly longer definition. + isempty(vns) && return false + for vn in vns + istrans(vi, vn) || return false + end + return true end """ From 62e1c7817b198bfd56500fd11f29d827c94a544e Mon Sep 17 00:00:00 2001 From: Penelope Yong Date: Mon, 7 Jul 2025 10:17:23 +0100 Subject: [PATCH 4/6] Use getsym() --- src/simple_varinfo.jl | 8 ++---- src/utils.jl | 65 +++++++++++++++++++++---------------------- 2 files changed, 35 insertions(+), 38 deletions(-) diff --git a/src/simple_varinfo.jl b/src/simple_varinfo.jl index 92a08a1b6..2297bc9e1 100644 --- a/src/simple_varinfo.jl +++ b/src/simple_varinfo.jl @@ -356,15 +356,13 @@ function BangBang.setindex!!(vi::SimpleVarInfo, vals, vns::AbstractVector{<:VarN return vi end -function BangBang.setindex!!( - vi::SimpleVarInfo{<:AbstractDict}, val, vn::VarName{sym} -) where {sym} +function BangBang.setindex!!(vi::SimpleVarInfo{<:AbstractDict}, val, vn::VarName) # For dictlike objects, we treat the entire `vn` as a _key_ to set. dict = values_as(vi) # Attempt to split into `parent` and `child` optic. parent, child, issuccess = splitoptic(getoptic(vn)) do optic o = optic === nothing ? identity : optic - haskey(dict, VarName{sym}(o)) + haskey(dict, VarName{getsym(vn)}(o)) end # When combined with `VarInfo`, `nothing` is equivalent to `identity`. keyoptic = parent === nothing ? identity : parent @@ -374,7 +372,7 @@ function BangBang.setindex!!( BangBang.setindex!!(dict, val, vn) else # Split exists ⟹ trying to set an existing key. - vn_key = VarName{sym}(keyoptic) + vn_key = VarName{getsym(vn)}(keyoptic) BangBang.setindex!!(dict, set!!(dict[vn_key], child, val), vn_key) end return Accessors.@set vi.values = dict_new diff --git a/src/utils.jl b/src/utils.jl index e219b34a2..73a8b48b9 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -595,9 +595,9 @@ julia> (parent ∘ parent ∘ parent)(@varname(x.a[1])) x ``` """ -function parent(vn::VarName{sym}) where {sym} +function parent(vn::VarName) p = parent(getoptic(vn)) - return p === nothing ? VarName{sym}(identity) : VarName{sym}(p) + return p === nothing ? VarName{getsym(vn)}(identity) : VarName{getsym(vn)}(p) end """ @@ -898,7 +898,7 @@ end # For `dictlike` we need to check wether `vn` is "immediately" present, or # if some ancestor of `vn` is present in `dictlike`. -function hasvalue(vals::AbstractDict, vn::VarName{sym}) where {sym} +function hasvalue(vals::AbstractDict, vn::VarName) # First we check if `vn` is present as is. haskey(vals, vn) && return true @@ -907,7 +907,7 @@ function hasvalue(vals::AbstractDict, vn::VarName{sym}) where {sym} # If `issuccess` is `true`, we found such a split, and hence `vn` is present. parent, child, issuccess = splitoptic(getoptic(vn)) do optic o = optic === nothing ? identity : optic - haskey(vals, VarName{sym}(o)) + haskey(vals, VarName{getsym(vn)}(o)) end # When combined with `VarInfo`, `nothing` is equivalent to `identity`. keyoptic = parent === nothing ? identity : parent @@ -916,7 +916,7 @@ function hasvalue(vals::AbstractDict, vn::VarName{sym}) where {sym} issuccess || return false # At this point we just need to check that we `canview` the value. - value = vals[VarName{sym}(keyoptic)] + value = vals[VarName{getsym(vn)}(keyoptic)] return canview(child, value) end @@ -927,7 +927,7 @@ end Return value corresponding to `vn` in `values` by also looking in the the actual values of the dict. """ -function nested_getindex(values::AbstractDict, vn::VarName{sym}) where {sym} +function nested_getindex(values::AbstractDict, vn::VarName) maybeval = get(values, vn, nothing) if maybeval !== nothing return maybeval @@ -936,7 +936,7 @@ function nested_getindex(values::AbstractDict, vn::VarName{sym}) where {sym} # Split the optic into the key / `parent` and the extraction optic / `child`. parent, child, issuccess = splitoptic(getoptic(vn)) do optic o = optic === nothing ? identity : optic - haskey(values, VarName{sym}(o)) + haskey(values, VarName{getsym(vn)}(o)) end # When combined with `VarInfo`, `nothing` is equivalent to `identity`. keyoptic = parent === nothing ? identity : parent @@ -949,7 +949,7 @@ function nested_getindex(values::AbstractDict, vn::VarName{sym}) where {sym} # TODO: Should we also check that we `canview` the extracted `value` # rather than just let it fail upon `get` call? - value = values[VarName{sym}(keyoptic)] + value = values[VarName{getsym(vn)}(keyoptic)] return child(value) end @@ -1065,24 +1065,23 @@ x.z[2][1] ``` """ varname_leaves(vn::VarName, ::Real) = [vn] -function varname_leaves( - vn::VarName{sym}, val::AbstractArray{<:Union{Real,Missing}} -) where {sym} +function varname_leaves(vn::VarName, val::AbstractArray{<:Union{Real,Missing}}) return ( - VarName{sym}(Accessors.IndexLens(Tuple(I)) ∘ getoptic(vn)) for + VarName{getsym(vn)}(Accessors.IndexLens(Tuple(I)) ∘ getoptic(vn)) for I in CartesianIndices(val) ) end -function varname_leaves(vn::VarName{sym}, val::AbstractArray) where {sym} +function varname_leaves(vn::VarName, val::AbstractArray) return Iterators.flatten( - varname_leaves(VarName{sym}(Accessors.IndexLens(Tuple(I)) ∘ getoptic(vn)), val[I]) - for I in CartesianIndices(val) + varname_leaves( + VarName{getsym(vn)}(Accessors.IndexLens(Tuple(I)) ∘ getoptic(vn)), val[I] + ) for I in CartesianIndices(val) ) end -function varname_leaves(vn::VarName{sym}, val::NamedTuple) where {sym} +function varname_leaves(vn::VarName, val::NamedTuple) iter = Iterators.map(keys(val)) do k optic = Accessors.PropertyLens{k}() - varname_leaves(VarName{sym}(optic ∘ getoptic(vn)), optic(val)) + varname_leaves(VarName{getsym(vn)}(optic ∘ getoptic(vn)), optic(val)) end return Iterators.flatten(iter) end @@ -1112,7 +1111,7 @@ julia> foreach(println, varname_and_value_leaves(@varname(x), x)) (x.z[2][1], 3.0) ``` -There are also some special handling for certain types: +There is also some special handling for certain types: ```jldoctest varname-and-value-leaves julia> using LinearAlgebra @@ -1227,26 +1226,30 @@ value(leaf::Leaf) = leaf.value # Leaf-types. varname_and_value_leaves_inner(vn::VarName, x::Real) = [Leaf(vn, x)] function varname_and_value_leaves_inner( - vn::VarName{sym}, val::AbstractArray{<:Union{Real,Missing}} -) where {sym} + vn::VarName, val::AbstractArray{<:Union{Real,Missing}} +) return ( Leaf( - VarName{sym}(Accessors.IndexLens(Tuple(I)) ∘ AbstractPPL.getoptic(vn)), val[I] + VarName{getsym(vn)}(Accessors.IndexLens(Tuple(I)) ∘ AbstractPPL.getoptic(vn)), + val[I], ) for I in CartesianIndices(val) ) end # Containers. -function varname_and_value_leaves_inner(vn::VarName{sym}, val::AbstractArray) where {sym} +function varname_and_value_leaves_inner(vn::VarName, val::AbstractArray) return Iterators.flatten( varname_and_value_leaves_inner( - VarName{sym}(Accessors.IndexLens(Tuple(I)) ∘ AbstractPPL.getoptic(vn)), val[I] + VarName{getsym(vn)}(Accessors.IndexLens(Tuple(I)) ∘ AbstractPPL.getoptic(vn)), + val[I], ) for I in CartesianIndices(val) ) end -function varname_and_value_leaves_inner(vn::VarName{sym}, val::NamedTuple) where {sym} +function varname_and_value_leaves_inner(vn::VarName, val::NamedTuple) iter = Iterators.map(keys(val)) do k optic = Accessors.PropertyLens{k}() - varname_and_value_leaves_inner(VarName{sym}(optic ∘ getoptic(vn)), optic(val)) + varname_and_value_leaves_inner( + VarName{getsym(vn)}(optic ∘ getoptic(vn)), optic(val) + ) end return Iterators.flatten(iter) @@ -1260,20 +1263,16 @@ function varname_and_value_leaves_inner(vn::VarName, x::Cholesky) varname_and_value_leaves_inner(Accessors.PropertyLens{:U}() ∘ vn, x.U) end end -function varname_and_value_leaves_inner( - vn::VarName{sym}, x::LinearAlgebra.LowerTriangular -) where {sym} +function varname_and_value_leaves_inner(vn::VarName, x::LinearAlgebra.LowerTriangular) return ( - Leaf(VarName{sym}(Accessors.IndexLens(Tuple(I)) ∘ AbstractPPL.getoptic(vn)), x[I]) + Leaf(VarName{getsym(vn)}(Accessors.IndexLens(Tuple(I)) ∘ getoptic(vn)), x[I]) # Iteration over the lower-triangular indices. for I in CartesianIndices(x) if I[1] >= I[2] ) end -function varname_and_value_leaves_inner( - vn::VarName{sym}, x::LinearAlgebra.UpperTriangular -) where {sym} +function varname_and_value_leaves_inner(vn::VarName, x::LinearAlgebra.UpperTriangular) return ( - Leaf(VarName{sym}(Accessors.IndexLens(Tuple(I)) ∘ AbstractPPL.getoptic(vn)), x[I]) + Leaf(VarName{getsym(vn)}(Accessors.IndexLens(Tuple(I)) ∘ getoptic(vn)), x[I]) # Iteration over the upper-triangular indices. for I in CartesianIndices(x) if I[1] <= I[2] ) From 67bb05586ce447d81e3e761301e7cf9b98a26075 Mon Sep 17 00:00:00 2001 From: Penelope Yong Date: Mon, 7 Jul 2025 10:19:07 +0100 Subject: [PATCH 5/6] Revert "Hotfix for Julia 1.10 claiming that istrans is type unstable" This reverts commit 29821296c03271073b3d93ee28c9d5f33a5e2581. --- src/abstract_varinfo.jl | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/abstract_varinfo.jl b/src/abstract_varinfo.jl index 28bf488fa..f11b8a3ec 100644 --- a/src/abstract_varinfo.jl +++ b/src/abstract_varinfo.jl @@ -481,15 +481,7 @@ If `vns` is provided, then only check if this/these varname(s) are transformed. """ istrans(vi::AbstractVarInfo) = istrans(vi, collect(keys(vi))) function istrans(vi::AbstractVarInfo, vns::AbstractVector) - # This used to be: `!isempty(vns) && all(Base.Fix1(istrans, vi), vns)`. - # In theory that should work perfectly fine. For unbeknownst reasons, - # Julia 1.10 fails to infer its return type correctly. Thus we use this - # slightly longer definition. - isempty(vns) && return false - for vn in vns - istrans(vi, vn) || return false - end - return true + return !isempty(vns) && all(Base.Fix1(istrans, vi), vns) end """ From aaa1e8dabd1946e860c1531686f61bd0a9cd3564 Mon Sep 17 00:00:00 2001 From: Penelope Yong Date: Mon, 7 Jul 2025 11:07:10 +0100 Subject: [PATCH 6/6] Reapply "Hotfix for Julia 1.10 claiming that istrans is type unstable" This reverts commit 67bb05586ce447d81e3e761301e7cf9b98a26075. --- src/abstract_varinfo.jl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/abstract_varinfo.jl b/src/abstract_varinfo.jl index f11b8a3ec..28bf488fa 100644 --- a/src/abstract_varinfo.jl +++ b/src/abstract_varinfo.jl @@ -481,7 +481,15 @@ If `vns` is provided, then only check if this/these varname(s) are transformed. """ istrans(vi::AbstractVarInfo) = istrans(vi, collect(keys(vi))) function istrans(vi::AbstractVarInfo, vns::AbstractVector) - return !isempty(vns) && all(Base.Fix1(istrans, vi), vns) + # This used to be: `!isempty(vns) && all(Base.Fix1(istrans, vi), vns)`. + # In theory that should work perfectly fine. For unbeknownst reasons, + # Julia 1.10 fails to infer its return type correctly. Thus we use this + # slightly longer definition. + isempty(vns) && return false + for vn in vns + istrans(vi, vn) || return false + end + return true end """