preserve application and error inference in test builds
This commit is contained in:
@@ -229,6 +229,7 @@ Checker :: struct {
|
||||
sink_symbol: symbol.Id,
|
||||
type_symbol: symbol.Id,
|
||||
current_result: types.Type,
|
||||
inferred_test_error: ^types.Type,
|
||||
current_build_ctx: ^Build_Ctx,
|
||||
current_comptime_values: []Comptime_Value,
|
||||
static_state: Ct_State,
|
||||
@@ -4129,6 +4130,17 @@ Infer_Frame :: struct {
|
||||
template: ast.Function_Id,
|
||||
}
|
||||
|
||||
merge_inferred_test_error :: proc(checker: ^Checker, incoming: types.Type) {
|
||||
current := checker.inferred_test_error
|
||||
if current == nil || !types.is_valid(incoming) ||
|
||||
types.can_sum_widen(incoming, current^, &checker.module.types) {
|
||||
return
|
||||
}
|
||||
if merged, err := types.compose_sum(&checker.module.types, current^, incoming); err == .None {
|
||||
current^ = merged
|
||||
}
|
||||
}
|
||||
|
||||
infer_nested_expr :: proc(
|
||||
checker: ^Checker,
|
||||
expr_id: ast.Expr_Id,
|
||||
@@ -4313,6 +4325,7 @@ infer_compound_expr :: proc(
|
||||
case .Try:
|
||||
left_expected := expected if checker.ast_module.exprs[expr.left].kind == .Call else types.INVALID
|
||||
value := infer_nested_expr(checker, expr.left, locals, pkg, file, demanded, local_types, left_expected)
|
||||
merge_inferred_test_error(checker, types.fallible_error(value, store))
|
||||
return types.fallible_success(value, store) if types.kind(value, store) == .Fallible else types.INVALID
|
||||
case .Catch:
|
||||
left_expected := expected if checker.ast_module.exprs[expr.left].kind == .Call else types.INVALID
|
||||
@@ -5488,7 +5501,16 @@ infer_spec_locals_and_result :: proc(
|
||||
}
|
||||
|
||||
result := types.INVALID
|
||||
test_error := function.error
|
||||
previous_test_error := checker.inferred_test_error
|
||||
checker.inferred_test_error = &test_error if function.test else nil
|
||||
infer_statements(checker, function.body, &locals, local_types, function.pkg, function.file, demanded, &result, result_hint)
|
||||
checker.inferred_test_error = previous_test_error
|
||||
if function.test && !types.equal(function.error, test_error) {
|
||||
checker.ast_module.functions[spec.template].error = test_error
|
||||
success := types.fallible_success(checker.specs[id].result, &checker.module.types)
|
||||
checker.specs[id].result = types.fallible(&checker.module.types, success, test_error)
|
||||
}
|
||||
if types.is_constraint(declared) {
|
||||
// Narrow the inferred result to the constraint's family; an out-of-family
|
||||
// result (e.g. returning a non-integer from an `int` function) yields
|
||||
@@ -5948,6 +5970,11 @@ infer_all :: proc(checker: ^Checker) {
|
||||
}
|
||||
}
|
||||
|
||||
for function, index in checker.ast_module.functions {
|
||||
if function.analysis_root {
|
||||
ensure_spec(checker, ast.function_id(index), nil)
|
||||
}
|
||||
}
|
||||
main_template := find_template(checker, checker.main_symbol, 0)
|
||||
if main_template != ast.INVALID_FUNCTION {
|
||||
ensure_spec(checker, main_template, nil)
|
||||
@@ -6035,7 +6062,9 @@ infer_all :: proc(checker: ^Checker) {
|
||||
|
||||
for index := 0; index < len(checker.specs); index += 1 {
|
||||
id := spec_id(index)
|
||||
before := checker.specs[id].result
|
||||
inferred := infer_spec_result(checker, id)
|
||||
changed = !types.equal(before, checker.specs[id].result) || changed
|
||||
changed = merge_inferred_type(&checker.module.types, &checker.specs[id].result, inferred) || changed
|
||||
}
|
||||
if len(checker.specs) != spec_count {
|
||||
|
||||
Reference in New Issue
Block a user