Skip to content

Commit

Permalink
fix reconstruction with unknown type param (#521)
Browse files Browse the repository at this point in the history
* fix reconstruction with unknown type param

* fix and test
  • Loading branch information
JonasIsensee authored Jan 4, 2024
1 parent ad988ca commit 28b2185
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 16 deletions.
24 changes: 12 additions & 12 deletions src/data/reconstructing_datatypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ function types_from_refs(f::JLDFile, ptr::Ptr)
nulldt = CommittedDatatype(UNDEFINED_ADDRESS, 0)
cdt = get(f.datatype_locations, ref, nulldt)
res = cdt !== nulldt ? (typeof(jltype(f, cdt)::ReadRepresentation)::DataType).parameters[1] : load_dataset(f, ref)
unknown_params = unknown_params || isunknowntype(res)
unknown_params = unknown_params || isunknowntype(res) || isreconstructed(res)
res
end for ref in refs]
return params, unknown_params
Expand Down Expand Up @@ -402,9 +402,9 @@ function jlconvert(rr::ReadRepresentation{T,DataTypeODR()},
m isa Upgrade && return m
else
m = _resolve_type(rr, f, ptr, header_offset, mypath, hasparams, hasparams ? params : nothing)
isunknowntype(m) && return m
end

isunknowntype(m) && return m
unknown_params && return UnknownType{m, Tuple{params...}}
if hasparams
try
m = m{params...}
Expand Down Expand Up @@ -557,7 +557,7 @@ function constructrr(f::JLDFile, unk::Type{UnknownType{T,P}}, dt::CompoundDataty
attrs::Vector{ReadAttribute}) where {T,P}
field_datatypes = read_field_datatypes(f, attrs)
if T isa DataType
if unk.name == Tuple
if T === Tuple
# For a tuple with unknown fields, we should reconstruct the fields
rodr = reconstruct_odr(f, dt, field_datatypes)
# This is a "pseudo-RR" since the tuple is not fully parametrized, but
Expand All @@ -569,24 +569,24 @@ function constructrr(f::JLDFile, unk::Type{UnknownType{T,P}}, dt::CompoundDataty

end
elseif T isa UnionAll
body = behead(unk.name)
if length(body.parameters) != length(unk.parameters)
@warn("read type $(typestring(unk)) has a different number of parameters from type " *
"$(unk.name) in workspace; reconstructing")
reconstruct_compound(f, typestring(unk), dt, field_datatypes)
body = behead(T)
if length(body.parameters) != length(P.parameters)
@warn("read type $(typestring(T)) has a different number of parameters from type " *
"$(T) in workspace; reconstructing")
reconstruct_compound(f, typestring(T), dt, field_datatypes)
else
params = [P.parameters...,]
for i = 1:length(params)
if isa(params[i], UnknownType)
if isunknowntype(params[i])
param = body.parameters[i]::TypeVar
params[i] = param.ub
end
end

# Try to construct the rr for the relaxed type. On failure, fall back to
# reconstruct_compound.`
try
T2 = unk.name{params...}
T2 = try
T{params...}
catch err
@warn("type parameters for $(typestring(unk)) do not match type $(T) in workspace; reconstructing")
return reconstruct_compound(f, shorttypestring(unk), dt, field_datatypes)
Expand Down
6 changes: 3 additions & 3 deletions test/Artifacts.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[testfiles]
git-tree-sha1 = "496c72594b20fe977506afc3c7af39e8dedae53d"
git-tree-sha1 = "8d34be7b8603854dca03eb0330f214a9194de75a"
lazy = true

[[testfiles.download]]
url = "https://github.com/JonasIsensee/JLD2TestFiles/archive/refs/tags/v0.1.0.tar.gz"
sha256 = "e2e00e745a840b5a76cdf8b8bf17c78d135985c86397a8e53e0fd678ab42f4f5"
sha256 = "f91805f612a00178ca68d5ecc895af09c231d1ca949c7ef0157cb9730b3a84aa"
url = "https://github.com/JonasIsensee/JLD2TestFiles/archive/refs/tags/v0.1.1.tar.gz"
12 changes: 11 additions & 1 deletion test/test_files.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ using Test, JLD2
using LazyArtifacts
# When adding test files to the JLD2Testfiles repo tag a new
# release and adapt Artifacts.toml and the line below accordingly.
testfiles = artifact"testfiles/JLD2TestFiles-0.1.0/artifacts"
testfiles = artifact"testfiles/JLD2TestFiles-0.1.1/artifacts"

@testset "HDF5 compat test files" begin
# These are test files copied from the HDF5.jl test suite
Expand Down Expand Up @@ -133,4 +133,14 @@ end
# Opening for overwriting should succeed
close(jldopen(path, "w+"))
end
end

@testset "Mutable Struct Reconstruction Issue #506" begin
fn = joinpath(testfiles,"struct_reconstruction.jld2")
data = load(fn)
@test data["dms"] isa JLD2.SerializedDict
@test JLD2.isreconstructed(data["dms"].kvvec[1].second)
@test data["ds"] isa JLD2.SerializedDict
@test JLD2.isreconstructed(data["ds"].kvvec[1].second)
@test JLD2.isreconstructed(data["tms"][2])
end

0 comments on commit 28b2185

Please sign in to comment.