comptime storage and function values
This commit is contained in:
@@ -903,13 +903,16 @@ function_value_signature :: proc(
|
||||
return nil, types.INVALID, false
|
||||
}
|
||||
function := checker.ast_module.functions[template]
|
||||
if !function.c_abi || types.is_valid(function.error) {
|
||||
return nil, types.INVALID, false
|
||||
}
|
||||
if function_has_comptime_params(function) {
|
||||
return nil, types.INVALID, false
|
||||
}
|
||||
result = type_from_syntax(checker, function.result, function.pkg, function.file)
|
||||
if function.c_abi && types.is_valid(function.error) {
|
||||
return nil, types.INVALID, false
|
||||
}
|
||||
if !function.c_abi && (!function.has_body || function.variadic) {
|
||||
return nil, types.INVALID, false
|
||||
}
|
||||
result = function_channel_type(checker, function)
|
||||
if !types.is_void(result) && !is_runtime_type(checker, result) {
|
||||
return nil, types.INVALID, false
|
||||
}
|
||||
@@ -929,6 +932,7 @@ function_pointer_type_for_template :: proc(
|
||||
checker: ^Checker,
|
||||
template: ast.Function_Id,
|
||||
demanded: ^[dynamic]Spec_Id = nil,
|
||||
demand_spec := true,
|
||||
) -> (types.Type, Spec_Id, bool) {
|
||||
params, result, ok := function_value_signature(checker, template)
|
||||
if !ok {
|
||||
@@ -936,16 +940,20 @@ function_pointer_type_for_template :: proc(
|
||||
}
|
||||
defer delete(params, checker.allocator)
|
||||
function := checker.ast_module.functions[template]
|
||||
function_type := types.function(&checker.module.types, params, result, true, function.variadic)
|
||||
function_type := types.function(&checker.module.types, params, result, function.c_abi, function.variadic)
|
||||
pointer_type := types.pointer(&checker.module.types, function_type, false, true)
|
||||
spec := INVALID_SPEC
|
||||
if demanded == nil {
|
||||
spec = ensure_spec(checker, template, params)
|
||||
if demand_spec {
|
||||
spec = ensure_spec(checker, template, params)
|
||||
} else {
|
||||
spec = find_spec(checker, template, params)
|
||||
}
|
||||
} else {
|
||||
spec = find_spec(checker, template, params)
|
||||
mark_spec_demanded(checker, spec, demanded)
|
||||
}
|
||||
return pointer_type, spec, spec != INVALID_SPEC
|
||||
return pointer_type, spec, spec != INVALID_SPEC || !demand_spec
|
||||
}
|
||||
|
||||
contains_name :: proc(names: []symbol.Id, name: symbol.Id) -> bool {
|
||||
@@ -1391,16 +1399,30 @@ validate_type_nodes :: proc(checker: ^Checker) {
|
||||
}
|
||||
}
|
||||
if item.kind == .Function {
|
||||
if !item.c_abi {
|
||||
source.add(checker.diagnostics, source.Span{}, "only c_func function pointer types are supported")
|
||||
}
|
||||
for param in types.params_for(&checker.module.types, id) {
|
||||
if types.is_void(param.type) || !types.is_c_signature_type(param.type, &checker.module.types) {
|
||||
source.add(checker.diagnostics, source.Span{}, "function pointer parameters must be concrete C signature types")
|
||||
if item.c_abi {
|
||||
if types.kind(item.child, &checker.module.types) == .Fallible {
|
||||
source.add(checker.diagnostics, source.Span{}, "c_func pointer results cannot be fallible")
|
||||
}
|
||||
for param in types.params_for(&checker.module.types, id) {
|
||||
if types.is_void(param.type) || !types.is_c_signature_type(param.type, &checker.module.types) {
|
||||
source.add(checker.diagnostics, source.Span{}, "c_func pointer parameters must be concrete C signature types")
|
||||
}
|
||||
}
|
||||
if !types.is_c_signature_type(item.child, &checker.module.types, true) {
|
||||
source.add(checker.diagnostics, source.Span{}, "c_func pointer results must be concrete C signature types or void")
|
||||
}
|
||||
} else {
|
||||
if item.variadic {
|
||||
source.add(checker.diagnostics, source.Span{}, "native function pointer types do not support variadic parameters")
|
||||
}
|
||||
for param in types.params_for(&checker.module.types, id) {
|
||||
if types.is_void(param.type) || !is_runtime_type(checker, param.type) {
|
||||
source.add(checker.diagnostics, source.Span{}, "native function pointer parameters must be concrete runtime types")
|
||||
}
|
||||
}
|
||||
if !types.is_void(item.child) && !is_runtime_type(checker, item.child) {
|
||||
source.add(checker.diagnostics, source.Span{}, "native function pointer results must be concrete runtime types or void")
|
||||
}
|
||||
}
|
||||
if !types.is_c_signature_type(item.child, &checker.module.types, true) {
|
||||
source.add(checker.diagnostics, source.Span{}, "function pointer results must be concrete C signature types or void")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1597,7 +1619,7 @@ infer_compound_expr :: proc(
|
||||
store := &checker.module.types
|
||||
#partial switch expr.kind {
|
||||
case .Comptime:
|
||||
return infer_comptime_expr_type(checker, expr, pkg, file)
|
||||
return infer_comptime_expr_type(checker, expr, pkg, file, demanded)
|
||||
case .Bool:
|
||||
return types.BOOL
|
||||
case .Not:
|
||||
@@ -3535,13 +3557,13 @@ build_function_value :: proc(
|
||||
id := source.addf(
|
||||
checker.diagnostics,
|
||||
span,
|
||||
"function '%s' cannot be used as a C callback; expected a concrete c_func",
|
||||
"function '%s' cannot be used as a function value; expected a concrete non-comptime signature",
|
||||
symbol_text(checker, function.name),
|
||||
)
|
||||
return invalid_hir_expr(checker, span, id)
|
||||
}
|
||||
defer delete(params, checker.allocator)
|
||||
function_type := types.function(&checker.module.types, params, result, true, function.variadic)
|
||||
function_type := types.function(&checker.module.types, params, result, function.c_abi, function.variadic)
|
||||
pointer_type := types.pointer(&checker.module.types, function_type, false, true)
|
||||
spec := find_spec(checker, template, params)
|
||||
if spec == INVALID_SPEC {
|
||||
@@ -4444,7 +4466,7 @@ build_expr :: proc(
|
||||
last = build_global_reference(checker, global, expr.span, global_reads)
|
||||
} else {
|
||||
template := find_template(checker, expr.name, target_pkg)
|
||||
if template != ast.INVALID_FUNCTION && checker.ast_module.functions[template].c_abi {
|
||||
if template != ast.INVALID_FUNCTION {
|
||||
last = build_function_value(checker, template, expr.span, frame.expected)
|
||||
} else {
|
||||
id := add_unsupported_diagnostic(checker, expr.span, target_pkg, expr.name)
|
||||
|
||||
+1022
-71
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user