aboutsummaryrefslogtreecommitdiff
path: root/src/check_expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/check_expr.cpp')
-rw-r--r--src/check_expr.cpp77
1 files changed, 48 insertions, 29 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 0db12aba0..830b5315d 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -646,11 +646,8 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand
Type *src = base_type(s);
Type *dst = base_type(type);
- if (is_type_untyped_undef(src)) {
- if (type_has_undef(dst)) {
- return 1;
- }
- return -1;
+ if (is_type_untyped_uninit(src)) {
+ return 1;
}
if (is_type_untyped_nil(src)) {
@@ -993,13 +990,13 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ
if (is_type_untyped(operand->type)) {
Type *target_type = type;
if (type == nullptr || is_type_any(type)) {
- if (type == nullptr && is_type_untyped_nil(operand->type)) {
- error(operand->expr, "Use of untyped nil in %.*s", LIT(context_name));
+ if (type == nullptr && is_type_untyped_uninit(operand->type)) {
+ error(operand->expr, "Use of --- in %.*s", LIT(context_name));
operand->mode = Addressing_Invalid;
return;
}
- if (type == nullptr && is_type_untyped_undef(operand->type)) {
- error(operand->expr, "Use of --- in %.*s", LIT(context_name));
+ if (type == nullptr && is_type_untyped_nil(operand->type)) {
+ error(operand->expr, "Use of untyped nil in %.*s", LIT(context_name));
operand->mode = Addressing_Invalid;
return;
}
@@ -1067,7 +1064,7 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ
if (check_is_assignable_to(c, operand, type)) {
if (operand->mode == Addressing_Type && is_type_typeid(type)) {
- add_type_info_type(c, operand->type);
+ add_type_info_type(c, operand->type);
add_type_and_value(c, operand->expr, Addressing_Value, type, exact_value_typeid(operand->type));
}
} else {
@@ -3969,7 +3966,7 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar
case Type_Union:
- if (!is_operand_nil(*operand) && !is_operand_undef(*operand)) {
+ if (!is_operand_nil(*operand) && !is_operand_uninit(*operand)) {
TEMPORARY_ALLOCATOR_GUARD();
isize count = t->Union.variants.count;
@@ -4036,8 +4033,8 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar
error_line("\n\n");
return;
- } else if (is_type_untyped_undef(operand->type) && type_has_undef(target_type)) {
- target_type = t_untyped_undef;
+ } else if (is_type_untyped_uninit(operand->type)) {
+ target_type = t_untyped_uninit;
} else if (!is_type_untyped_nil(operand->type) || !type_has_nil(target_type)) {
begin_error_block();
defer (end_error_block());
@@ -4070,8 +4067,8 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar
default:
- if (is_type_untyped_undef(operand->type) && type_has_undef(target_type)) {
- target_type = t_untyped_undef;
+ if (is_type_untyped_uninit(operand->type)) {
+ target_type = t_untyped_uninit;
} else if (is_type_untyped_nil(operand->type) && type_has_nil(target_type)) {
target_type = t_untyped_nil;
} else {
@@ -4083,8 +4080,8 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar
}
if (is_type_any(target_type) && is_type_untyped(operand->type)) {
- if (is_type_untyped_nil(operand->type) && is_type_untyped_undef(operand->type)) {
-
+ if (is_type_untyped_nil(operand->type) && is_type_untyped_uninit(operand->type)) {
+
} else {
target_type = default_type(operand->type);
}
@@ -5144,8 +5141,20 @@ gb_internal bool check_assignment_arguments(CheckerContext *ctx, Array<Operand>
}
+typedef u32 UnpackFlags;
+enum UnpackFlag : u32 {
+ UnpackFlag_None = 0,
+ UnpackFlag_AllowOk = 1<<0,
+ UnpackFlag_IsVariadic = 1<<1,
+ UnpackFlag_AllowUndef = 1<<2,
+};
+
+
+gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array<Operand> *operands, Slice<Ast *> const &rhs, UnpackFlags flags) {
+ bool allow_ok = (flags & UnpackFlag_AllowOk) != 0;
+ bool is_variadic = (flags & UnpackFlag_IsVariadic) != 0;
+ bool allow_undef = (flags & UnpackFlag_AllowUndef) != 0;
-gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array<Operand> *operands, Slice<Ast *> const &rhs, bool allow_ok, bool is_variadic) {
bool optional_ok = false;
isize tuple_index = 0;
for_array(i, rhs) {
@@ -5184,7 +5193,16 @@ gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize
}
}
- check_expr_base(c, &o, rhs[i], type_hint);
+ Ast *rhs_expr = unparen_expr(rhs[i]);
+ if (allow_undef && rhs_expr != nullptr && rhs_expr->kind == Ast_Uninit) {
+ // NOTE(bill): Just handle this very specific logic here
+ o.type = t_untyped_uninit;
+ o.mode = Addressing_Value;
+ o.expr = rhs[i];
+ add_type_and_value(c, rhs[i], o.mode, o.type, o.value);
+ } else {
+ check_expr_base(c, &o, rhs[i], type_hint);
+ }
if (o.mode == Addressing_NoValue) {
error_operand_no_value(&o);
o.mode = Addressing_Invalid;
@@ -5968,7 +5986,7 @@ gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *op
lhs = populate_proc_parameter_list(c, proc_type, &lhs_count, &is_variadic);
}
if (operand->mode != Addressing_ProcGroup) {
- check_unpack_arguments(c, lhs, lhs_count, &operands, args, false, is_variadic);
+ check_unpack_arguments(c, lhs, lhs_count, &operands, args, is_variadic ? UnpackFlag_IsVariadic : UnpackFlag_None);
}
}
@@ -6025,7 +6043,7 @@ gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *op
isize lhs_count = -1;
bool is_variadic = false;
lhs = populate_proc_parameter_list(c, e->type, &lhs_count, &is_variadic);
- check_unpack_arguments(c, lhs, lhs_count, &operands, args, false, is_variadic);
+ check_unpack_arguments(c, lhs, lhs_count, &operands, args, is_variadic ? UnpackFlag_IsVariadic : UnpackFlag_None);
CallArgumentData data = {};
CallArgumentError err = call_checker(c, call, e->type, e, operands, CallArgumentMode_ShowErrors, &data);
@@ -6101,7 +6119,7 @@ gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *op
}
- check_unpack_arguments(c, lhs, lhs_count, &operands, args, false, false);
+ check_unpack_arguments(c, lhs, lhs_count, &operands, args, UnpackFlag_None);
if (lhs != nullptr) {
gb_free(heap_allocator(), lhs);
@@ -6462,7 +6480,7 @@ gb_internal CallArgumentError check_polymorphic_record_type(CheckerContext *c, O
lhs_count = params->variables.count;
}
- check_unpack_arguments(c, lhs, lhs_count, &operands, ce->args, false, false);
+ check_unpack_arguments(c, lhs, lhs_count, &operands, ce->args, UnpackFlag_None);
}
}
@@ -7146,11 +7164,11 @@ gb_internal bool check_set_index_data(Operand *o, Type *t, bool indirection, i64
}
gb_internal bool ternary_compare_types(Type *x, Type *y) {
- if (is_type_untyped_undef(x) && type_has_undef(y)) {
+ if (is_type_untyped_uninit(x)) {
return true;
} else if (is_type_untyped_nil(x) && type_has_nil(y)) {
return true;
- } else if (is_type_untyped_undef(y) && type_has_undef(x)) {
+ } else if (is_type_untyped_uninit(y)) {
return true;
} else if (is_type_untyped_nil(y) && type_has_nil(x)) {
return true;
@@ -7687,7 +7705,7 @@ gb_internal ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *n
}
o->type = x.type;
- if (is_type_untyped_nil(o->type) || is_type_untyped_undef(o->type)) {
+ if (is_type_untyped_nil(o->type) || is_type_untyped_uninit(o->type)) {
o->type = y.type;
}
@@ -9580,9 +9598,10 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast
check_ident(c, o, node, nullptr, type_hint, false);
case_end;
- case_ast_node(u, Undef, node);
+ case_ast_node(u, Uninit, node);
o->mode = Addressing_Value;
- o->type = t_untyped_undef;
+ o->type = t_untyped_uninit;
+ error(node, "Use of --- outside of variable declaration");
case_end;
@@ -10145,7 +10164,7 @@ gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthan
str = string_append_string(str, bd->name.string);
case_end;
- case_ast_node(ud, Undef, node);
+ case_ast_node(ud, Uninit, node);
str = gb_string_appendc(str, "---");
case_end;