feat: infer complete ptrcast target types

This commit is contained in:
2026-09-20 00:01:13 +02:00
parent 5dac5baa05
commit 7f7de7a8d2
11 changed files with 122 additions and 65 deletions
+18 -9
View File
@@ -2498,19 +2498,21 @@ main func() void {
opaque_anyopaque_and_ptrcast_compile_and_lower :: proc(t: ^testing.T) {
text := `Handle :: opaque
take func(_ ?*mut anyopaque) void {}
take_bytes func(_ ?*mut u8) void {}
use_handle func(_ ?@mut Handle) void {}
main func() void {
values [2]mut u8 := [1, 2]
raw ?*mut anyopaque := (&values).ptr
bytes ?*mut u8 := ptrcast!(u8, raw)
bytes ?*mut u8 := ptrcast!(raw)
take(bytes)
take_bytes(ptrcast!(raw))
if bytes |p| {
p[1] = 5
}
one u8 := 1
single ?@mut anyopaque := &one
typed ?@mut u8 := ptrcast!(u8, single)
typed ?@mut u8 := ptrcast!(?@mut u8, single)
if typed |p| {
p^ = 2
}
@@ -2545,8 +2547,8 @@ main func() void {
}
testing.expect_value(t, len(diagnostics.items), 0)
testing.expect_value(t, hir_casts, 2)
testing.expect_value(t, ir_casts, 2)
testing.expect_value(t, hir_casts, 3)
testing.expect_value(t, ir_casts, 3)
}
@(test)
@@ -2555,10 +2557,11 @@ anyopaque_by_value_and_invalid_ptrcasts_are_rejected :: proc(t: ^testing.T) {
main func() void {
raw ?*mut anyopaque := null
value anyopaque := undefined
_ = ptrcast!(void, raw)
_ = ptrcast!(anyopaque, raw)
_ = ptrcast!(Callback, raw)
_ = ptrcast!(u8, 1)
_ = ptrcast!(raw)
_ = ptrcast!(u8, raw)
_ = ptrcast!(?*mut void, raw)
_ = ptrcast!(?@mut u8, raw)
_ = ptrcast!(?*mut u8, 1)
_ = ptrcast!(1, raw)
}
`
@@ -2575,19 +2578,25 @@ main func() void {
defer hir.destroy_module(&hir_module)
found_by_value := false
found_inference := false
found_bad_target := false
found_bad_operand := false
found_target_type := false
found_shape := false
for diagnostic in diagnostics.items {
found_by_value = found_by_value || strings.contains(diagnostic.message, "could not infer a concrete type")
found_bad_target = found_bad_target || strings.contains(diagnostic.message, "ptrcast! target must be a sized runtime object type")
found_inference = found_inference || strings.contains(diagnostic.message, "cannot infer ptrcast! target type")
found_bad_target = found_bad_target || strings.contains(diagnostic.message, "ptrcast! target must be a pointer or optional pointer")
found_bad_operand = found_bad_operand || strings.contains(diagnostic.message, "ptrcast! operand must be a pointer")
found_target_type = found_target_type || strings.contains(diagnostic.message, "ptrcast! target must be a type")
found_shape = found_shape || strings.contains(diagnostic.message, "ptrcast! cannot convert pointer shape")
}
testing.expect(t, found_by_value)
testing.expect(t, found_inference)
testing.expect(t, found_bad_target)
testing.expect(t, found_bad_operand)
testing.expect(t, found_target_type)
testing.expect(t, found_shape)
}
@(test)