bare func declaration identities (comptime)
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user