Skip to content

Commit

Permalink
const fields in mutable structs (#414)
Browse files Browse the repository at this point in the history
* testing const fields in mutable structs

* support const fields in mutable structs

* bump version

Co-authored-by: Jonas Isensee <[email protected]>
  • Loading branch information
JonasIsensee and Jonas Isensee authored Sep 10, 2022
1 parent a2dec21 commit a4f2980
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 0.4.23
- Support for `const` fields in mutable structs

## 0.4.22
- Fix reconstruction of partially intialized structs

Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "JLD2"
uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
version = "0.4.22"
version = "0.4.23"

[deps]
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
Expand Down
9 changes: 7 additions & 2 deletions src/data/reconstructing_datatypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -540,9 +540,14 @@ jlconvert(::ReadRepresentation{Core.TypeofBottom,nothing}, f::JLDFile, ptr::Ptr,
if odr === nothing
# Type is not stored or single instance
newi = Expr(:new, ttype)
push!(args, :(setfield!(obj, $fni, $newi)))
# use jl_set_nth_field instead of setfield! since the former also works for const fields
# in mutable structs.
push!(args, :(ccall(:jl_set_nth_field, Nothing, (Any, Csize_t, Any), obj, ($i)-1, $newi)))
else
loadfield = :(setfield!(obj, $fni, rconvert($ttype, jlconvert($rr, f, ptr+$offset, NULL_REFERENCE)::$rtype)::$ttype))
loadfield = quote
fieldval = rconvert($ttype, jlconvert($rr, f, ptr+$offset, NULL_REFERENCE)::$rtype)::$ttype
ccall(:jl_set_nth_field, Nothing, (Any, Csize_t, Any), obj, ($i)-1, fieldval)
end
if jlconvert_canbeuninitialized(rr)
push!(args, :(jlconvert_isinitialized($rr, ptr+$offset) && $(loadfield)))
else
Expand Down
27 changes: 27 additions & 0 deletions test/loadsave.jl
Original file line number Diff line number Diff line change
Expand Up @@ -513,4 +513,31 @@ end
@test_throws UndefRefError fu.x

end
end

if VERSION v"1.8"

struct SingletonStruct end

# This is a workaround since for old julia versions this syntax is not allowed and the parser
# is eager and attempts to parse this piece of code anyway
eval(Meta.parse("""mutable struct WrappedSingleton
x::Int
const y::Vector{Int}
const z::SingletonStruct
end
"""))

@testset "Constant fields in mutable structs (>v1.8) - Issue #410" begin
mktempdir() do folder
# The real test here is that it doesn't fail in v1.8
b = WrappedSingleton(1, [2,3], SingletonStruct())
save("test.jld2", "b", b)
bloaded = load("test.jld2", "b")
@test b.x == bloaded.x
@test b.y == bloaded.y
@test b.z == bloaded.z
end
end

end

2 comments on commit a4f2980

@JonasIsensee
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register()

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/68040

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.4.23 -m "<description of version>" a4f298056ed8147711601f2070014467288f9452
git push origin v0.4.23

Please sign in to comment.