refine distinct construction semantics

This commit is contained in:
2026-08-02 19:13:13 +02:00
parent b9526b5f06
commit f25f76adff
5 changed files with 88 additions and 36 deletions
+34 -5
View File
@@ -13323,6 +13323,40 @@ main func() i32 {
testing.expect(t, retype_count >= 5)
}
@(test)
distinct_construction_casts_to_scalar_backing_and_infers_bound_global :: proc(t: ^testing.T) {
directory := "/tmp/brolang-test-distinct-construction"
main_path := "/tmp/brolang-test-distinct-construction/main.bro"
output := "/tmp/brolang-test-distinct-construction-output"
_ = os2.remove_all(directory)
defer _ = os2.remove_all(directory)
defer _ = os.remove(output)
testing.expect(t, os2.make_directory_all(directory) == nil)
text := `UserID :: distinct u32
OtherID :: distinct u32
NO_ID :: maxval!(UserID)
Data :: union { id UserID }
Record :: struct { data Data = Data{ id = NO_ID } }
main func() i32 {
small u8 = 7
wide usize = 8
a UserID = UserID(small)
b UserID = UserID(wide)
c UserID = UserID(OtherID(9))
d UserID :: $UserID(usize(10))
record Record = {}
_ = record
if u32(a) != 7 or u32(b) != 8 or u32(c) != 9 or u32(d) != 10 { return 1 }
return 0
}
`
testing.expect(t, os.write_entire_file(main_path, transmute([]byte)text))
testing.expect_value(t, compiler_core.compile_package(directory, output), 0)
state := run_executable(output)
testing.expect_value(t, state.exit_code, 0)
}
@(test)
distinct_types_reject_implicit_conversions_and_invalid_backings :: proc(t: ^testing.T) {
text := `Opaque :: opaque
@@ -13339,8 +13373,6 @@ main func() void {
id UserID = raw
backing u32 = UserID(2)
other OtherID = UserID(3)
narrow u8 = 4
_ = UserID(narrow)
_ = UserID()
_ = UserID(1, 2)
left UserID :: UserID(5)
@@ -13368,7 +13400,6 @@ main func() void {
invalid_backing_count := 0
implicit_conversion_count := 0
found_exact := false
found_arity := false
found_arithmetic := false
found_comparison := false
@@ -13376,7 +13407,6 @@ main func() void {
for diagnostic in diagnostics.items {
invalid_backing_count += 1 if strings.contains(diagnostic.message, "requires a concrete runtime backing type") else 0
implicit_conversion_count += 1 if strings.contains(diagnostic.message, "cannot implicitly convert") else 0
found_exact = found_exact || strings.contains(diagnostic.message, "requires an exact u32 value, got u8")
found_arity = found_arity || strings.contains(diagnostic.message, "expects 1 argument")
found_arithmetic = found_arithmetic || strings.contains(diagnostic.message, "arithmetic requires compatible numeric operands")
found_comparison = found_comparison || strings.contains(diagnostic.message, "comparison requires compatible numeric operands")
@@ -13384,7 +13414,6 @@ main func() void {
}
testing.expect_value(t, invalid_backing_count, 4)
testing.expect(t, implicit_conversion_count >= 3)
testing.expect(t, found_exact)
testing.expect(t, found_arity)
testing.expect(t, found_arithmetic)
testing.expect(t, found_comparison)