fix: canonicalize nested composition references

This commit is contained in:
2026-10-24 03:51:50 +02:00
parent cbbf5e7d6c
commit 3a90a90428
2 changed files with 17 additions and 15 deletions
+4 -3
View File
@@ -453,7 +453,8 @@ sum_syntax :: proc(store: ^Store, left, right: Type) -> Type {
} }
append_sum_variants :: proc(store: ^Store, value: Type, out: ^[dynamic]Sum_Variant) -> bool { append_sum_variants :: proc(store: ^Store, value: Type, out: ^[dynamic]Sum_Variant) -> bool {
item, ok := node(store, value) resolved := resolve_alias(value, store)
item, ok := node(store, resolved)
if !ok { if !ok {
return false return false
} }
@@ -461,7 +462,7 @@ append_sum_variants :: proc(store: ^Store, value: Type, out: ^[dynamic]Sum_Varia
if item.explicit_backing { if item.explicit_backing {
return false return false
} }
for member in enum_members_for(store, value) { for member in enum_members_for(store, resolved) {
if member.value <= 0 || member.value > 0xffff { if member.value <= 0 || member.value > 0xffff {
return false return false
} }
@@ -473,7 +474,7 @@ append_sum_variants :: proc(store: ^Store, value: Type, out: ^[dynamic]Sum_Varia
return false return false
} }
tag_members := enum_members_for(store, item.child) tag_members := enum_members_for(store, item.child)
for field in fields_for(store, value) { for field in fields_for(store, resolved) {
found := false found := false
for member in tag_members { for member in tag_members {
if member.name == field.name { if member.name == field.name {
+13 -12
View File
@@ -16783,7 +16783,7 @@ composed_map :: $(init(ErrorAlias, i32, {
})) }))
reflects_composed_keys func($E type) bool { reflects_composed_keys func($E type) bool {
keys [4]E := {.shared, .left, .right, .tail} keys [4]E := [.shared, .left, .right, .tail]
match typeinfo!(E) { match typeinfo!(E) {
.enum |info|: { .enum |info|: {
if info.fields.len != 4 { return false } if info.fields.len != 4 { return false }
@@ -16802,8 +16802,8 @@ reflects_composed_keys func($E type) bool {
main func() i32 { main func() i32 {
if !$(reflects_composed_keys(ErrorAlias)) { return 27 } if !$(reflects_composed_keys(ErrorAlias)) { return 27 }
keys [4]ErrorAlias := {.shared, .left, .right, .tail} keys [4]ErrorAlias := [.shared, .left, .right, .tail]
expected [4]i32 := {10, 20, 30, 40} expected [4]i32 := [10, 20, 30, 40]
for keys |key, index| { for keys |key, index| {
if get(&composed_map, key) |value| { if get(&composed_map, key) |value| {
if value != expected[index] { return 28 } if value != expected[index] { return 28 }
@@ -16930,6 +16930,8 @@ main func() i32 {
enum_field_struct_rejects_payload_sums_and_nominal_unions :: proc(t: ^testing.T) { enum_field_struct_rejects_payload_sums_and_nominal_unions :: proc(t: ^testing.T) {
directory := "/tmp/brolang-test-enum-field-struct-rejections" directory := "/tmp/brolang-test-enum-field-struct-rejections"
main_path := "/tmp/brolang-test-enum-field-struct-rejections/main.bro" main_path := "/tmp/brolang-test-enum-field-struct-rejections/main.bro"
output := "/tmp/brolang-test-enum-field-struct-rejections-output"
defer _ = os.remove(output)
_ = os2.remove_all(directory) _ = os2.remove_all(directory)
defer _ = os2.remove_all(directory) defer _ = os2.remove_all(directory)
testing.expect(t, os.make_directory(directory) == nil) testing.expect(t, os.make_directory(directory) == nil)
@@ -16941,14 +16943,13 @@ Keys :: alias Payload | Empty`,
`Keys :: union { first i32, second i32 }`, `Keys :: union { first i32, second i32 }`,
} }
for declaration in declarations { for declaration in declarations {
text := fmt.aprintf(`meta :: import "@std/meta" text := fmt.aprint("meta :: import \"@std/meta\"\n", declaration, `
%s
Flags :: alias meta.EnumFieldStruct(Keys, bool, false) Flags :: alias meta.EnumFieldStruct(Keys, bool, false)
main func() void { main func() void {
flags Flags := {} flags Flags := {}
_ = flags _ = flags
} }
`, declaration) `)
defer delete(text) defer delete(text)
testing.expect(t, os.write_entire_file(main_path, transmute([]byte)text)) testing.expect(t, os.write_entire_file(main_path, transmute([]byte)text))
sources := source.init_store() sources := source.init_store()
@@ -16961,15 +16962,15 @@ main func() void {
directory, &sources, &diagnostics, &symbols, project_root_path=".", directory, &sources, &diagnostics, &symbols, project_root_path=".",
) )
defer ast.destroy_module(&module) defer ast.destroy_module(&module)
testing.expect_value(t, len(diagnostics.items), 0)
hir_module := checker.check(&module, &diagnostics, &symbols) hir_module := checker.check(&module, &diagnostics, &symbols)
defer hir.destroy_module(&hir_module) defer hir.destroy_module(&hir_module)
testing.expect(t, loaded) testing.expect(t, loaded)
found_rejection := false testing.expect(t, len(diagnostics.items) > 0)
for diagnostic in diagnostics.items { testing.expect_value(t, compiler_core.compile_package(
found_rejection = found_rejection || directory, output, nil, target.DEFAULT, cimport.Options{}, ".",
strings.contains(diagnostic.message, "EnumFieldStruct key must be an enum") ), 1)
} testing.expect(t, !os.exists(output))
testing.expect(t, found_rejection)
} }
} }