Skip to content

Commit 7194d9b

Browse files
committed
Struct desugaring: "Undo decision to publish incomplete types..."
JuliaLang/julia#56497; Add self-referencing struct shim I have doubts about how long this solution will stay in the base repository, and how complete it is (doesn't seem to work with M1.M2.S), but we are testing for it here. Also change the expected value of a test changed in the same PR.
1 parent 950b87c commit 7194d9b

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

src/desugaring.jl

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3825,6 +3825,24 @@ function _constructor_min_initalized(ex::SyntaxTree)
38253825
end
38263826
end
38273827

3828+
# Let S be a struct we're defining in module M. Below is a hack to allow its
3829+
# field types to refer to S as M.S. See #56497.
3830+
function insert_struct_shim(ctx, fieldtypes, name)
3831+
function replace_type(ex)
3832+
if kind(ex) == K"." &&
3833+
numchildren(ex) == 2 &&
3834+
kind(ex[2]) == K"Symbol" &&
3835+
ex[2].name_val == name.name_val
3836+
@ast ctx ex [K"call" "struct_name_shim"::K"core" ex[1] ex[2] ctx.mod::K"Value" name]
3837+
elseif numchildren(ex) > 0
3838+
@ast ctx ex [ex.kind map(replace_type, children(ex))...]
3839+
else
3840+
ex
3841+
end
3842+
end
3843+
map(replace_type, fieldtypes)
3844+
end
3845+
38283846
function expand_struct_def(ctx, ex, docs)
38293847
@chk numchildren(ex) == 2
38303848
type_sig = ex[1]
@@ -3952,16 +3970,17 @@ function expand_struct_def(ctx, ex, docs)
39523970
]
39533971
end
39543972
]
3955-
# Otherwise do an assignment to trigger an error
3956-
[K"const" global_struct_name struct_name]
39573973
]
3958-
[K"const" global_struct_name struct_name]
39593974
]
39603975
[K"call"(type_body)
39613976
"_typebody!"::K"core"
39623977
struct_name
3963-
[K"call" "svec"::K"core" field_types...]
3978+
[K"call" "svec"::K"core" insert_struct_shim(ctx, field_types, struct_name)...]
39643979
]
3980+
[K"constdecl"
3981+
global_struct_name
3982+
newtype_var
3983+
]
39653984
# Default constructors
39663985
if isempty(inner_defs)
39673986
default_inner_constructors(ctx, ex, global_struct_name,

test/typedefs.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ end
251251
""")
252252
@test fieldtypes(test_mod.M36104.T36104) == (Vector{test_mod.M36104.T36104},)
253253
@test_throws ErrorException("expected") JuliaLowering.include_string(test_mod, """struct X36104; x::error("expected"); end""")
254-
@test isdefined(test_mod, :X36104)
254+
@test !isdefined(test_mod, :X36104)
255255
JuliaLowering.include_string(test_mod, "struct X36104; x::Int; end")
256256
@test fieldtypes(test_mod.X36104) == (Int,)
257257
JuliaLowering.include_string(test_mod, "primitive type P36104 8 end")

0 commit comments

Comments
 (0)