comptime-state propagation through generated struct field resolution
This commit is contained in:
@@ -1099,6 +1099,7 @@ type_from_syntax :: proc(
|
||||
pkg := ast.Package_Id(0),
|
||||
file := ast.File_Id(0),
|
||||
depth := 0,
|
||||
active_state: ^Ct_State = nil,
|
||||
) -> types.Type {
|
||||
if depth > 64 {
|
||||
return types.INVALID
|
||||
@@ -1116,9 +1117,9 @@ type_from_syntax :: proc(
|
||||
changed := false
|
||||
#partial switch item.kind {
|
||||
case .Alias:
|
||||
return type_from_syntax(checker, item.child, pkg, file, depth+1)
|
||||
return type_from_syntax(checker, item.child, pkg, file, depth+1, active_state)
|
||||
case .Array:
|
||||
child := type_from_syntax(checker, item.child, pkg, file, depth+1)
|
||||
child := type_from_syntax(checker, item.child, pkg, file, depth+1, active_state)
|
||||
changed = changed || child != item.child
|
||||
item.child = child
|
||||
if item.unresolved_count {
|
||||
@@ -1127,7 +1128,8 @@ type_from_syntax :: proc(
|
||||
if expr_id != ast.INVALID_EXPR && int(expr_id) < len(checker.ast_module.exprs) {
|
||||
span = checker.ast_module.exprs[expr_id].span
|
||||
}
|
||||
constant := eval_integer_constant_in_context(checker, expr_id, pkg, file)
|
||||
constant := eval_integer_constant_in_state(active_state, expr_id) if active_state != nil else
|
||||
eval_integer_constant_in_context(checker, expr_id, pkg, file)
|
||||
if constant.kind == .Value {
|
||||
switch {
|
||||
case constant.value < 0:
|
||||
@@ -1153,14 +1155,14 @@ type_from_syntax :: proc(
|
||||
}
|
||||
return types.intern(store, item)
|
||||
case .Pointer, .Slice, .Optional, .Range, .Fallible:
|
||||
child := type_from_syntax(checker, item.child, pkg, file, depth+1)
|
||||
extra := type_from_syntax(checker, item.extra, pkg, file, depth+1)
|
||||
child := type_from_syntax(checker, item.child, pkg, file, depth+1, active_state)
|
||||
extra := type_from_syntax(checker, item.extra, pkg, file, depth+1, active_state)
|
||||
item.child = child
|
||||
item.extra = extra
|
||||
return types.intern(store, item)
|
||||
case .Distinct, .Enum:
|
||||
child := type_from_syntax(checker, item.child, pkg, file, depth+1)
|
||||
extra := type_from_syntax(checker, item.extra, pkg, file, depth+1)
|
||||
child := type_from_syntax(checker, item.child, pkg, file, depth+1, active_state)
|
||||
extra := type_from_syntax(checker, item.extra, pkg, file, depth+1, active_state)
|
||||
changed = child != item.child || extra != item.extra
|
||||
item.child = child
|
||||
item.extra = extra
|
||||
@@ -1169,13 +1171,13 @@ type_from_syntax :: proc(
|
||||
resolved_params := make([]types.Type, len(params), checker.allocator)
|
||||
defer delete(resolved_params, checker.allocator)
|
||||
for param, index in params {
|
||||
resolved_params[index] = type_from_syntax(checker, param.type, pkg, file, depth+1)
|
||||
resolved_params[index] = type_from_syntax(checker, param.type, pkg, file, depth+1, active_state)
|
||||
}
|
||||
result := type_from_syntax(checker, item.child, pkg, file, depth+1)
|
||||
result := type_from_syntax(checker, item.child, pkg, file, depth+1, active_state)
|
||||
return types.function(store, resolved_params, result, item.c_abi, item.variadic)
|
||||
case .Sum:
|
||||
left := type_from_syntax(checker, item.child, pkg, file, depth+1)
|
||||
right := type_from_syntax(checker, item.extra, pkg, file, depth+1)
|
||||
left := type_from_syntax(checker, item.child, pkg, file, depth+1, active_state)
|
||||
right := type_from_syntax(checker, item.extra, pkg, file, depth+1, active_state)
|
||||
composed, compose_error := types.compose_sum(store, left, right)
|
||||
if compose_error == .Unsupported {
|
||||
source.add(checker.diagnostics, source.Span{}, "only native unbacked enums and tagged unions can be composed with '|'")
|
||||
@@ -2947,7 +2949,7 @@ resolved_call_arg_expected :: proc(
|
||||
return result
|
||||
}
|
||||
|
||||
resolve_generated_struct_type :: proc(checker: ^Checker, expr_id: ast.Expr_Id, pkg: ast.Package_Id, file: ast.File_Id) -> types.Type {
|
||||
resolve_generated_struct_type :: proc(checker: ^Checker, expr_id: ast.Expr_Id, pkg: ast.Package_Id, file: ast.File_Id, active_state: ^Ct_State) -> types.Type {
|
||||
for entry in checker.generated_types {
|
||||
if entry.expr == expr_id && comptime_values_equal(entry.values, checker.current_comptime_values) {
|
||||
return entry.result
|
||||
@@ -2966,7 +2968,7 @@ resolve_generated_struct_type :: proc(checker: ^Checker, expr_id: ast.Expr_Id, p
|
||||
fields := make([]types.Field, len(template_fields), checker.allocator)
|
||||
defer delete(fields, checker.allocator)
|
||||
for field, index in template_fields {
|
||||
resolved := type_from_syntax(checker, field.type, pkg, file)
|
||||
resolved := type_from_syntax(checker, field.type, pkg, file, active_state=active_state)
|
||||
if (!is_runtime_type(checker, resolved) && !is_comptime_value_type(checker, resolved)) || types.is_void(resolved) {
|
||||
if expr.tuple {
|
||||
source.addf(checker.diagnostics, expr.span, "tuple element %d requires a concrete runtime type, got %s", index, type_label(checker, resolved))
|
||||
|
||||
Reference in New Issue
Block a user