Skip to content

Commit a0083b4

Browse files
aviateskclaudemlechu
authored
JuliaLowering: Reject duplicate field names in struct definitions (#61471)
The flisp lowerer reports an error for `struct A; x; x; end`, but JuliaLowering did not have an explicit check. The duplicate was only caught later as a "function argument name not unique" error during constructor generation, which was confusing. Add an explicit check in `_collect_struct_fields` that throws a `LoweringError` with the same message format as flisp when a duplicate field name is encountered. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Em Chu <61633163+mlechu@users.noreply.github.com>
1 parent d803fc3 commit a0083b4

File tree

3 files changed

+34
-0
lines changed

3 files changed

+34
-0
lines changed

JuliaLowering/src/desugaring.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3201,6 +3201,11 @@ function _collect_struct_fields(ctx, field_names, field_types, field_attrs, fiel
32013201
m = _match_struct_field(e)
32023202
if !isnothing(m)
32033203
# Struct field
3204+
for prev in field_names
3205+
if prev.name_val == m.name.name_val
3206+
throw(LoweringError(m.name, "duplicate field name"))
3207+
end
3208+
end
32043209
push!(field_names, m.name)
32053210
n = length(field_names)
32063211
push!(field_types, isnothing(m.type) ? @ast(ctx, e, "Any"::K"core") : m.type)

JuliaLowering/test/typedefs.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,11 @@ JuliaLowering.include_string(test_mod, "const orig_P36104 = P36104")
448448
JuliaLowering.include_string(test_mod, "primitive type P36104 16 end")
449449
@test test_mod.P36104 !== test_mod.orig_P36104
450450

451+
# Duplicate field names should be rejected
452+
@test_throws LoweringError JuliaLowering.include_string(test_mod, "struct DupField; x; x; end")
453+
@test_throws LoweringError JuliaLowering.include_string(test_mod, "struct DupField2; x::Int; x::String; end")
454+
@test_throws LoweringError JuliaLowering.include_string(test_mod, "mutable struct DupField3; x; y; x; end")
455+
451456
# Struct with outer constructor where one typevar is constrained by the other
452457
# See https://github.com/JuliaLang/julia/issues/27269)
453458
@test JuliaLowering.include_string(test_mod, """

JuliaLowering/test/typedefs_ir.jl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,3 +1370,27 @@ end
13701370
47 (call top._defaultctors %₄₅ %₄₆)
13711371
48 latestworld
13721372
49 (return core.nothing)
1373+
1374+
########################################
1375+
# Error: Duplicate field name in struct
1376+
struct A; x; x; end
1377+
#---------------------
1378+
LoweringError:
1379+
struct A; x; x; end
1380+
# ╙ ── duplicate field name
1381+
1382+
########################################
1383+
# Error: Duplicate field name with different types
1384+
struct A; x::Int; x::String; end
1385+
#---------------------
1386+
LoweringError:
1387+
struct A; x::Int; x::String; end
1388+
# ╙ ── duplicate field name
1389+
1390+
########################################
1391+
# Error: Duplicate field name in mutable struct
1392+
mutable struct A; x; y; x; end
1393+
#---------------------
1394+
LoweringError:
1395+
mutable struct A; x; y; x; end
1396+
# ╙ ── duplicate field name

0 commit comments

Comments
 (0)