deferred defaulting typing

This commit is contained in:
2026-06-26 18:00:01 +02:00
parent f9ea044169
commit 77d4c1d494
3 changed files with 189 additions and 22 deletions
+41
View File
@@ -6630,6 +6630,47 @@ contextual_inference_flows_through_compound_assignment :: proc(t: ^testing.T) {
testing.expect_value(t, len(diagnostics.items), 0)
}
@(test)
contextual_inference_resolves_open_global_arithmetic_across_uses :: proc(t: ^testing.T) {
text := `take_ci :: func(v c_int) void {}
W :: 800
Z :: 40
STEP :: 5
main :: func() void {
take_ci(W)
x int = W - Z
take_ci(Z)
x += STEP
take_ci(x)
_ = x
}
`
source_file := source.Source{path="test.bro", text=text}
diagnostics := source.init_diagnostics(&source_file)
defer source.destroy_diagnostics(&diagnostics)
symbols := symbol.init_table()
defer symbol.destroy_table(&symbols)
stream := lexer.lex(&source_file, &diagnostics, &symbols)
defer delete(stream.items)
ast_module := parser.parse(&stream, &source_file, &diagnostics)
defer ast.destroy_module(&ast_module)
hir_module := checker.check(&ast_module, &diagnostics, &symbols)
defer hir.destroy_module(&hir_module)
// `W - Z` mixes two open-constant globals while `Z`'s c_int use comes only after the
// arithmetic, and `STEP` is used only in a compound assignment. With deferred defaulting
// an undemanded open global stays typeless during the fixpoint instead of leaking a
// provisional i16 default, so W/Z/STEP all resolve to c_int. Previously this reported
// "arithmetic requires compatible numeric operands" / "cannot implicitly convert i16 to c_int".
testing.expect_value(t, len(diagnostics.items), 0)
for global in hir_module.globals {
name := symbol.resolve(&symbols, global.name)
if name == "W" || name == "Z" || name == "STEP" {
testing.expect(t, types.equal(global.type, types.C_INT))
}
}
}
@(test)
contextual_inference_rejects_local_constant_that_does_not_fit :: proc(t: ^testing.T) {
text := `main :: func() void {