prune dead specializations
This commit is contained in:
@@ -869,6 +869,113 @@ main :: func() void {
|
||||
testing.expect_value(t, len(hir_module.functions), 3)
|
||||
}
|
||||
|
||||
@(test)
|
||||
stale_specializations_are_pruned_after_inference :: proc(t: ^testing.T) {
|
||||
text := `derived :: identity(make())
|
||||
wide :: delayed()
|
||||
identity :: func(value int) int {
|
||||
return value
|
||||
}
|
||||
make :: func() int {
|
||||
return wide
|
||||
return 1
|
||||
}
|
||||
delayed :: func() int {
|
||||
return 128
|
||||
}
|
||||
main :: func() void {}
|
||||
`
|
||||
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)
|
||||
ir_module := lower.lower(&hir_module)
|
||||
defer ir.destroy_module(&ir_module)
|
||||
llvm_text := llvm.emit(&ir_module, &diagnostics, &symbols)
|
||||
defer delete(llvm_text)
|
||||
|
||||
testing.expect_value(t, len(diagnostics.items), 0)
|
||||
testing.expect_value(t, len(hir_module.functions), 4)
|
||||
testing.expect(t, strings.contains(llvm_text, "@bro__p0__identity__i16"))
|
||||
testing.expect(t, !strings.contains(llvm_text, "@bro__p0__identity__i8"))
|
||||
}
|
||||
|
||||
@(test)
|
||||
eager_global_calls_root_specializations :: proc(t: ^testing.T) {
|
||||
text := `make :: func() i32 {
|
||||
return 7
|
||||
}
|
||||
unused_native :: func() i32 {
|
||||
return 9
|
||||
}
|
||||
unused_foreign :: c func() i32
|
||||
value i32 :: make()
|
||||
main :: func() void {}
|
||||
`
|
||||
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)
|
||||
ir_module := lower.lower(&hir_module)
|
||||
defer ir.destroy_module(&ir_module)
|
||||
llvm_text := llvm.emit(&ir_module, &diagnostics, &symbols)
|
||||
defer delete(llvm_text)
|
||||
|
||||
testing.expect_value(t, len(diagnostics.items), 0)
|
||||
testing.expect_value(t, len(hir_module.functions), 2)
|
||||
testing.expect(t, strings.contains(llvm_text, "@bro__p0__make("))
|
||||
testing.expect(t, !strings.contains(llvm_text, "@bro__p0__unused_native("))
|
||||
testing.expect(t, !strings.contains(llvm_text, "@unused_foreign("))
|
||||
}
|
||||
|
||||
@(test)
|
||||
malformed_generic_calls_do_not_retain_specializations :: proc(t: ^testing.T) {
|
||||
text := `identity :: func(value int) int {
|
||||
return value
|
||||
}
|
||||
bad :: identity(1, 2)
|
||||
main :: func() void {}
|
||||
`
|
||||
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)
|
||||
ir_module := lower.lower(&hir_module)
|
||||
defer ir.destroy_module(&ir_module)
|
||||
llvm_text := llvm.emit(&ir_module, &diagnostics, &symbols)
|
||||
defer delete(llvm_text)
|
||||
|
||||
found_arity := false
|
||||
for diagnostic in diagnostics.items {
|
||||
found_arity = found_arity || strings.contains(diagnostic.message, "expects 1 arguments, got 2")
|
||||
}
|
||||
testing.expect(t, found_arity)
|
||||
testing.expect_value(t, len(hir_module.functions), 1)
|
||||
testing.expect(t, !strings.contains(llvm_text, "@bro__p0__identity"))
|
||||
testing.expect(t, strings.contains(llvm_text, "call void @bro.trap"))
|
||||
}
|
||||
|
||||
@(test)
|
||||
long_generic_call_chain_reaches_a_fixed_point :: proc(t: ^testing.T) {
|
||||
builder := strings.builder_make()
|
||||
|
||||
Reference in New Issue
Block a user