close some gaps in the type system
This commit is contained in:
@@ -625,14 +625,19 @@ ct_coerce_value :: proc(state: ^Ct_State, id: Ct_Value_Id, expected: types.Type,
|
||||
}
|
||||
if value.kind == .Function {
|
||||
actual_item, actual_ok := types.node(store, value.type)
|
||||
_, _, expected_function, expected_ok := types.function_pointer(expected, store)
|
||||
_, _, expected_function, expected_pointer := types.function_pointer(expected, store)
|
||||
expected_ok := expected_pointer
|
||||
if expected_item, ok := types.node(store, expected); ok && expected_item.kind == .Function {
|
||||
expected_function = expected
|
||||
expected_ok = true
|
||||
}
|
||||
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) {
|
||||
if actual_pointer && expected_pointer && types.equal(actual_function, expected_function) {
|
||||
value.type = expected
|
||||
return ct_add_value(state, value), true
|
||||
}
|
||||
@@ -1522,14 +1527,17 @@ ct_eval_struct_expr :: proc(state: ^Ct_State, expr: ast.Expr, expected: types.Ty
|
||||
if values[index] != INVALID_CT_VALUE {
|
||||
continue
|
||||
}
|
||||
field_default, has_default := find_struct_field_default(checker, struct_type, symbol.Id(field.name))
|
||||
field_default, default_values, has_default := find_struct_field_default(checker, struct_type, symbol.Id(field.name))
|
||||
if !has_default {
|
||||
return INVALID_CT_VALUE, ct_flow(.Normal), ct_failf(state, .Not_Comptime, expr.span, "missing initializer for struct field '%s'", symbol_text(checker, symbol.Id(field.name)))
|
||||
}
|
||||
previous_pkg, previous_file := state.pkg, state.file
|
||||
previous_comptime := checker.current_comptime_values
|
||||
state.pkg, state.file = field_default.pkg, field_default.file
|
||||
checker.current_comptime_values = default_values
|
||||
value, flow, ok := ct_eval_expr(state, field_default.expr, field.type, depth+1)
|
||||
state.pkg, state.file = previous_pkg, previous_file
|
||||
checker.current_comptime_values = previous_comptime
|
||||
if !ok || flow.kind != .Normal {
|
||||
return INVALID_CT_VALUE, flow, ok
|
||||
}
|
||||
@@ -2102,6 +2110,16 @@ ct_eval_binary :: proc(state: ^Ct_State, op: ast.Expr_Kind, left_id, right_id: C
|
||||
left := state.values[left_id]
|
||||
right := state.values[right_id]
|
||||
is_compare := op == .Eq || op == .Ne || op == .Lt || op == .Le || op == .Gt || op == .Ge
|
||||
if left.kind == .Type || right.kind == .Type {
|
||||
if left.kind != .Type || right.kind != .Type || (op != .Eq && op != .Ne) {
|
||||
return INVALID_CT_VALUE, ct_flow(.Normal), ct_fail(state, .Not_Comptime, span, "type values only support '==' and '!=' with another type")
|
||||
}
|
||||
ok := types.equal(types.Type(left.index), types.Type(right.index))
|
||||
if op == .Ne {
|
||||
ok = !ok
|
||||
}
|
||||
return ct_add_value(state, Ct_Value{kind=.Bool, type=types.BOOL, integer=1 if ok else 0}), ct_flow(.Normal), true
|
||||
}
|
||||
if left.kind == .Bool && right.kind == .Bool {
|
||||
if op != .Eq && op != .Ne {
|
||||
return INVALID_CT_VALUE, ct_flow(.Normal), ct_fail(state, .Not_Comptime, span, "bool values only support '==' and '!='")
|
||||
@@ -2897,6 +2915,12 @@ ct_eval_template_call :: proc(
|
||||
if ct_value_references_dead_storage(state, result) {
|
||||
return INVALID_CT_VALUE, ct_flow(.Normal), ct_fail(state, .Not_Comptime, span, "comptime function returned a pointer to expired storage")
|
||||
}
|
||||
if is_type_metatype_syntax(checker, function.result) && result != INVALID_CT_VALUE &&
|
||||
int(result) < len(state.values) && state.values[result].kind == .Type {
|
||||
record_type_factory_origin(
|
||||
checker, types.Type(state.values[result].index), template, comptime_values,
|
||||
)
|
||||
}
|
||||
if types.is_valid(expected) {
|
||||
return ct_coerce_expr_value(state, result, expected, span)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user