bare func declaration identities (comptime)

This commit is contained in:
2026-07-18 14:05:55 +02:00
parent 85693e57e1
commit e889a99e55
8 changed files with 512 additions and 74 deletions
+50 -11
View File
@@ -624,9 +624,15 @@ ct_coerce_value :: proc(state: ^Ct_State, id: Ct_Value_Id, expected: types.Type,
return ct_add_value(state, value), true
}
if value.kind == .Function {
_, _, actual_function, actual_ok := types.function_pointer(value.type, store)
actual_item, actual_ok := types.node(store, value.type)
_, _, expected_function, expected_ok := types.function_pointer(expected, store)
if actual_ok && expected_ok && types.equal(actual_function, expected_function) {
if actual_ok && actual_item.kind == .Function && expected_ok &&
types.equal(value.type, expected_function) {
value.type = expected
return ct_add_value(state, value), true
}
_, _, actual_function, actual_pointer := types.function_pointer(value.type, store)
if actual_pointer && expected_ok && types.equal(actual_function, expected_function) {
value.type = expected
return ct_add_value(state, value), true
}
@@ -928,7 +934,8 @@ ct_materialize_value :: proc(
}
return invalid_hir_expr(checker, span, state.diagnostic, value.type)
case .Function:
return build_function_value(checker, ast.Function_Id(u32(value.index)), span, expected)
value_expected := expected if types.is_valid(expected) else value.type
return build_function_value(checker, ast.Function_Id(u32(value.index)), span, value_expected)
case .None:
return add_hir_expr(checker, hir.Expr{
kind=.None, span=span, type=value.type,
@@ -1076,16 +1083,20 @@ ct_eval_expr :: proc(
if global == ast.INVALID_GLOBAL || int(global) >= len(checker.ast_module.globals) {
template := find_template(checker, expr.name, target_pkg, expr_lookup_file(expr, state.file))
if template != ast.INVALID_FUNCTION {
pointer_type, _, function_ok := function_pointer_type_for_template(
function_type, _, function_ok := function_type_for_template(
checker,
template,
state.demanded,
state.demanded != nil,
)
if function_ok {
return ct_add_value(state, Ct_Value{
kind=.Function, type=pointer_type, index=u64(template),
}), ct_flow(.Normal), true
id := ct_add_value(state, Ct_Value{
kind=.Function, type=function_type, index=u64(template),
})
if types.is_valid(expected) {
return ct_coerce_expr_value(state, id, expected, expr.span)
}
return id, ct_flow(.Normal), true
}
return INVALID_CT_VALUE, ct_flow(.Normal), ct_failf(state, .Not_Comptime, expr.span, "function '%s' is not comptime-callable as a value", symbol_text(checker, expr.name))
}
@@ -1099,7 +1110,7 @@ ct_eval_expr :: proc(
return ct_eval_expr(state, g.expr, global_expected, depth+1)
case .Function_Literal:
template := ast.Function_Id(u32(expr.integer))
pointer_type, _, ok := function_pointer_type_for_template(
function_type, _, ok := function_type_for_template(
checker,
template,
state.demanded,
@@ -1110,9 +1121,13 @@ ct_eval_expr :: proc(
state, .Not_Comptime, expr.span, "function literal is not comptime-callable as a value",
)
}
return ct_add_value(state, Ct_Value{
kind=.Function, type=pointer_type, index=u64(template),
}), ct_flow(.Normal), true
id := ct_add_value(state, Ct_Value{
kind=.Function, type=function_type, index=u64(template),
})
if types.is_valid(expected) {
return ct_coerce_expr_value(state, id, expected, expr.span)
}
return id, ct_flow(.Normal), true
case .Comptime:
if expr.left != ast.INVALID_EXPR {
return ct_eval_expr(state, expr.left, expected, depth+1)
@@ -4164,3 +4179,27 @@ build_comptime_expr :: proc(
}
return invalid_hir_expr(checker, expr.span, diagnostic, expected)
}
try_build_specialization_expr :: proc(
checker: ^Checker,
expr_id: ast.Expr_Id,
expected: types.Type,
pkg: ast.Package_Id,
file: ast.File_Id,
) -> (hir.Expr_Id, bool) {
if len(checker.current_comptime_values) == 0 && len(checker.static_bindings) == 0 ||
expr_id == ast.INVALID_EXPR || int(expr_id) >= len(checker.ast_module.exprs) {
return hir.INVALID_EXPR, false
}
state := ct_state_make(checker, pkg, file, values=checker.current_comptime_values, diagnose=false)
defer ct_state_destroy(&state)
value, flow, ok := ct_eval_expr(&state, expr_id, expected, 0)
if !ok || flow.kind != .Normal || value == INVALID_CT_VALUE || int(value) >= len(state.values) {
return hir.INVALID_EXPR, false
}
static := state.values[value]
if static.kind != .Function {
return hir.INVALID_EXPR, false
}
return ct_materialize_value(&state, value, checker.ast_module.exprs[expr_id].span, expected), true
}