Skip to content

Commit f07980e

Browse files
committed
Add self-referencing struct shim
Part of JuliaLang/julia#56497 that I ignored before. 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 1470614 commit f07980e

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

src/desugaring.jl

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3854,6 +3854,24 @@ function _constructor_min_initalized(ex::SyntaxTree)
38543854
end
38553855
end
38563856

3857+
# Let S be a struct we're defining in module M. Below is a hack to allow its
3858+
# field types to refer to S as M.S. See #56497.
3859+
function insert_struct_shim(ctx, fieldtypes, name)
3860+
function replace_type(ex)
3861+
if kind(ex) == K"." &&
3862+
numchildren(ex) == 2 &&
3863+
kind(ex[2]) == K"Symbol" &&
3864+
ex[2].name_val == name.name_val
3865+
@ast ctx ex [K"call" "struct_name_shim"::K"core" ex[1] ex[2] ctx.mod::K"Value" name]
3866+
elseif numchildren(ex) > 0
3867+
@ast ctx ex [ex.kind map(replace_type, children(ex))...]
3868+
else
3869+
ex
3870+
end
3871+
end
3872+
map(replace_type, fieldtypes)
3873+
end
3874+
38573875
function expand_struct_def(ctx, ex, docs)
38583876
@chk numchildren(ex) == 2
38593877
type_sig = ex[1]
@@ -3986,7 +4004,7 @@ function expand_struct_def(ctx, ex, docs)
39864004
# TODO: if there is a previous compatible definition, re-use params. See #57253
39874005
false::K"Bool"
39884006
newtype_var
3989-
[K"call" "svec"::K"core" field_types...]
4007+
[K"call" "svec"::K"core" insert_struct_shim(ctx, field_types, struct_name)...]
39904008
]
39914009
[K"constdecl"
39924010
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)