From 14370c74aeaaa73e8cfaacc6568c28fd60be66ea Mon Sep 17 00:00:00 2001 From: vbot Date: Thu, 19 May 2022 10:18:06 +0000 Subject: [PATCH] [v:master] f9079b670 - vfmt: keep selective imported names used for generic calls --- v.c | 1875 +++++++++++++++++++++++++++++-------------------------- v_win.c | 1847 ++++++++++++++++++++++++++++-------------------------- 2 files changed, 1928 insertions(+), 1794 deletions(-) diff --git a/v.c b/v.c index 2a39926..4e6da5b 100644 --- a/v.c +++ b/v.c @@ -1,11 +1,11 @@ -#define V_COMMIT_HASH "9a0f49950" +#define V_COMMIT_HASH "f9079b670" #ifndef V_COMMIT_HASH - #define V_COMMIT_HASH "12ec3b9d5" + #define V_COMMIT_HASH "9a0f49950" #endif #ifndef V_CURRENT_COMMIT_HASH - #define V_CURRENT_COMMIT_HASH "9a0f499" + #define V_CURRENT_COMMIT_HASH "f9079b6" #endif // V comptime_definitions: @@ -7539,6 +7539,7 @@ string winapi_lasterr_str(void); void panic_lasterr(void); void gc_check_leaks(void); VV_LOCAL_SYMBOL void print_libbacktrace(int frames_to_skip); +VV_LOCAL_SYMBOL void eprint_libbacktrace(int frames_to_skip); int proc_pidpath(int , voidptr , int ); int vstrlen(byte* s); int vstrlen_char(char* s); @@ -8031,6 +8032,7 @@ Array_string os__get_lines(void); string os__get_lines_joined(void); string os__get_raw_lines_joined(void); string os__user_os(void); +_option_Array_string os__user_names(void); string os__home_dir(void); string os__expand_tilde_to_home(string path); _option_void os__write_file(string path, string text); @@ -9679,8 +9681,6 @@ void v__checker__Checker_alias_type_decl(v__checker__Checker* c, v__ast__AliasTy void v__checker__Checker_fn_type_decl(v__checker__Checker* c, v__ast__FnTypeDecl node); void v__checker__Checker_sum_type_decl(v__checker__Checker* c, v__ast__SumTypeDecl node); Array_v__ast__InterfaceEmbedding v__checker__Checker_expand_iface_embeds(v__checker__Checker* c, v__ast__InterfaceDecl* idecl, int level, Array_v__ast__InterfaceEmbedding iface_embeds); -VV_LOCAL_SYMBOL void v__checker__Checker_check_div_mod_by_zero(v__checker__Checker* c, v__ast__Expr expr, v__token__Kind op_kind); -v__ast__Type v__checker__Checker_infix_expr(v__checker__Checker* c, v__ast__InfixExpr* node); VV_LOCAL_SYMBOL multi_return_string_v__token__Pos v__checker__Checker_fail_if_immutable(v__checker__Checker* c, v__ast__Expr expr_); VV_LOCAL_SYMBOL bool v__checker__Checker_type_implements(v__checker__Checker* c, v__ast__Type typ, v__ast__Type interface_type, v__token__Pos pos); v__ast__Type v__checker__Checker_check_expr_opt_call(v__checker__Checker* c, v__ast__Expr expr, v__ast__Type ret_type); @@ -9770,6 +9770,8 @@ VV_LOCAL_SYMBOL void v__checker__Checker_for_in_stmt(v__checker__Checker* c, v__ VV_LOCAL_SYMBOL void v__checker__Checker_for_stmt(v__checker__Checker* c, v__ast__ForStmt* node); v__ast__Type v__checker__Checker_if_expr(v__checker__Checker* c, v__ast__IfExpr* node); VV_LOCAL_SYMBOL void v__checker__Checker_smartcast_if_conds(v__checker__Checker* c, v__ast__Expr node, v__ast__Scope* scope); +v__ast__Type v__checker__Checker_infix_expr(v__checker__Checker* c, v__ast__InfixExpr* node); +VV_LOCAL_SYMBOL void v__checker__Checker_check_div_mod_by_zero(v__checker__Checker* c, v__ast__Expr expr, v__token__Kind op_kind); void v__checker__Checker_interface_decl(v__checker__Checker* c, v__ast__InterfaceDecl* node); VV_LOCAL_SYMBOL v__ast__Type v__checker__Checker_resolve_generic_interface(v__checker__Checker* c, v__ast__Type typ, v__ast__Type interface_type, v__token__Pos pos); v__ast__Type v__checker__Checker_match_expr(v__checker__Checker* c, v__ast__MatchExpr* node); @@ -17966,7 +17968,7 @@ VNORETURN VV_LOCAL_SYMBOL void panic_debug(int line_no, string file, string mod, #endif #if defined(CUSTOM_DEFINE_use_libbacktrace) { - print_libbacktrace(1); + eprint_libbacktrace(1); } #else { @@ -18042,7 +18044,7 @@ VNORETURN void _v_panic(string s) { #endif #if defined(CUSTOM_DEFINE_use_libbacktrace) { - print_libbacktrace(1); + eprint_libbacktrace(1); } #else { @@ -18656,7 +18658,15 @@ VV_LOCAL_SYMBOL void __print_assert_failure(VAssertMetaInfo* i) { // Attr: [markused] VV_LOCAL_SYMBOL void v_segmentation_fault_handler(int signal) { eprintln(_SLIT("signal 11: segmentation fault")); - print_backtrace(); + #if defined(CUSTOM_DEFINE_use_libbacktrace) + { + eprint_libbacktrace(1); + } + #else + { + print_backtrace(); + } + #endif _v_exit(139); VUNREACHABLE(); } @@ -18814,6 +18824,10 @@ void gc_check_leaks(void) { VV_LOCAL_SYMBOL void print_libbacktrace(int frames_to_skip) { } +// Attr: [noinline] +__NOINLINE VV_LOCAL_SYMBOL void eprint_libbacktrace(int frames_to_skip) { +} + // Attr: [trusted] // Attr: [noreturn] // Attr: [trusted] @@ -26708,6 +26722,49 @@ string os__user_os(void) { return _t13; } +_option_Array_string os__user_names(void) { + #if defined(_WIN32) + { + os__Result result = os__execute(_SLIT("wmic useraccount get name")); + if (result.exit_code != 0) { + return (_option_Array_string){ .state=2, .err=_v_error( str_intp(3, _MOV((StrIntpData[]){{_SLIT("Failed to get user names. Exited with code "), /*100 &int*/0xfe07, {.d_i32 = result.exit_code}}, {_SLIT(": "), /*115 &string*/0xfe10, {.d_s = result.output}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={EMPTY_STRUCT_INITIALIZATION} }; + } + Array_string users = string_split_into_lines(result.output); + array_delete(&users, users.len - 1); + _option_Array_string _t2; + opt_ok2(&(Array_string[]) { users }, (_option*)(&_t2), sizeof(Array_string)); + return _t2; + } + #else + { + _option_Array_string _t3 = os__read_lines(_SLIT("/etc/passwd")); + if (_t3.state != 0) { /*or block*/ + _option_Array_string _t4; + memcpy(&_t4, &_t3, sizeof(Option)); + return _t4; + } + + Array_string lines = (*(Array_string*)_t3.data); + Array_string users = __new_array_with_default(0, lines.len, sizeof(string), 0); + for (int _t5 = 0; _t5 < lines.len; ++_t5) { + string line = ((string*)lines.data)[_t5]; + _option_int _t6 = string_index(line, _SLIT(":")); + if (_t6.state != 0) { /*or block*/ + IError err = _t6.err; + *(int*) _t6.data = line.len; + } + + int end_name = (*(int*)_t6.data); + array_push((array*)&users, _MOV((string[]){ string_clone(string_substr(line, 0, end_name)) })); + } + _option_Array_string _t8; + opt_ok2(&(Array_string[]) { users }, (_option*)(&_t8), sizeof(Array_string)); + return _t8; + } + #endif + return (_option_Array_string){0}; +} + string os__home_dir(void) { #if defined(_WIN32) { @@ -38182,7 +38239,7 @@ void v__pref__Preferences_fill_with_defaults(v__pref__Preferences* p) { } #endif } - string vhash = _SLIT("12ec3b9d5"); + string vhash = _SLIT("9a0f49950"); p->cache_manager = v__vcache__new_cache_manager(new_array_from_c_array(7, 7, sizeof(string), _MOV((string[7]){string_clone(vhash), str_intp(6, _MOV((StrIntpData[]){{_SLIT0, /*115 &v.pref.Backend*/0xfe10, {.d_s = v__pref__Backend_str(p->backend)}}, {_SLIT(" | "), /*115 &v.pref.OS*/0xfe10, {.d_s = v__pref__OS_str(p->os)}}, {_SLIT(" | "), /*115 &string*/0xfe10, {.d_s = p->ccompiler}}, {_SLIT(" | "), /*115 &bool*/0xfe10, {.d_s = p->is_prod ? _SLIT("true") : _SLIT("false")}}, {_SLIT(" | "), /*115 &bool*/0xfe10, {.d_s = p->sanitize ? _SLIT("true") : _SLIT("false")}}, {_SLIT0, 0, { .d_c = 0 }}})), string_clone(string_trim_space(p->cflags)), string_clone(string_trim_space(p->third_party_option)), string_clone(Array_string_str(p->compile_defines_all)), string_clone(Array_string_str(p->compile_defines)), string_clone(Array_string_str(p->lookup_path))}))); if (string__eq(os__user_os(), _SLIT("windows"))) { p->use_cache = false; @@ -38763,7 +38820,7 @@ multi_return_ref_v__pref__Preferences_string v__pref__parse_args_and_show_errors #endif res->run_only = string_split_any(os__getenv(_SLIT("VTEST_ONLY_FN")), _SLIT(",")); string command = _SLIT(""); - int command_pos = 0; + int command_pos = -1; for (int i = 0; i < args.len; i++) { string arg = (*(string*)/*ee elem_sym */array_get(args, i)); Array_string _t1; @@ -38820,6 +38877,9 @@ multi_return_ref_v__pref__Preferences_string v__pref__parse_args_and_show_errors res->is_help = true; } else if (string__eq(arg, _SLIT("-v"))) { + if (command_pos != -1) { + continue; + } if (args.len > 1) { res->is_verbose = true; } else { @@ -50712,118 +50772,122 @@ bool v__checker__Checker_check_types(v__checker__Checker* c, v__ast__Type got, v bool _t9 = true; return _t9; } - } - if (got_sym->kind == v__ast__Kind__enum_) { - if (v__ast__TypeSymbol_is_number(expected_sym)) { + if (v__checker__Checker_check_types(c, (/* as */ *(v__ast__ArrayFixed*)__as_cast((got_sym->info)._v__ast__ArrayFixed,(got_sym->info)._typ, 441) /*expected idx: 441, name: v.ast.ArrayFixed */ ).elem_type, (/* as */ *(v__ast__ArrayFixed*)__as_cast((expected_sym->info)._v__ast__ArrayFixed,(expected_sym->info)._typ, 441) /*expected idx: 441, name: v.ast.ArrayFixed */ ).elem_type)) { bool _t10 = true; return _t10; } - } else if (got_sym->kind == v__ast__Kind__array_fixed) { - if (v__ast__TypeSymbol_is_number(expected_sym) || v__ast__Type_is_any_kind_of_pointer(expected)) { + } + if (got_sym->kind == v__ast__Kind__enum_) { + if (v__ast__TypeSymbol_is_number(expected_sym)) { bool _t11 = true; return _t11; } - } else if (expected_sym->kind == v__ast__Kind__array_fixed) { - if (v__ast__TypeSymbol_is_number(got_sym) && v__ast__Type_is_any_kind_of_pointer(got)) { + } else if (got_sym->kind == v__ast__Kind__array_fixed) { + if (v__ast__TypeSymbol_is_number(expected_sym) || v__ast__Type_is_any_kind_of_pointer(expected)) { bool _t12 = true; return _t12; + } + } else if (expected_sym->kind == v__ast__Kind__array_fixed) { + if (v__ast__TypeSymbol_is_number(got_sym) && v__ast__Type_is_any_kind_of_pointer(got)) { + bool _t13 = true; + return _t13; } else if (got_sym->kind == v__ast__Kind__array) { v__ast__ArrayFixed info = /* as */ *(v__ast__ArrayFixed*)__as_cast((expected_sym->info)._v__ast__ArrayFixed,(expected_sym->info)._typ, 441) /*expected idx: 441, name: v.ast.ArrayFixed */ ; v__ast__Array info2 = /* as */ *(v__ast__Array*)__as_cast((got_sym->info)._v__ast__Array,(got_sym->info)._typ, 413) /*expected idx: 413, name: v.ast.Array */ ; if (v__checker__Checker_check_types(c, info.elem_type, info2.elem_type)) { - bool _t13 = true; - return _t13; + bool _t14 = true; + return _t14; } } } else if (got_sym->kind == v__ast__Kind__array) { if (v__ast__TypeSymbol_is_number(expected_sym) || v__ast__Type_is_any_kind_of_pointer(expected)) { - bool _t14 = true; - return _t14; - } - } else if (expected_sym->kind == v__ast__Kind__array) { - if (v__ast__TypeSymbol_is_number(got_sym) && v__ast__Type_is_any_kind_of_pointer(got)) { bool _t15 = true; return _t15; } + } else if (expected_sym->kind == v__ast__Kind__array) { + if (v__ast__TypeSymbol_is_number(got_sym) && v__ast__Type_is_any_kind_of_pointer(got)) { + bool _t16 = true; + return _t16; + } } if (expected_sym->kind == v__ast__Kind__enum_ && v__ast__TypeSymbol_is_number(got_sym)) { - bool _t16 = true; - return _t16; + bool _t17 = true; + return _t17; } if (got_is_ptr && exp_is_ptr) { if (v__ast__TypeSymbol_is_number(expected_sym) && v__ast__TypeSymbol_is_number(got_sym)) { - bool _t17 = true; - return _t17; + bool _t18 = true; + return _t18; } } } if (got_is_ptr && exp_is_ptr) { if (v__ast__Type_nr_muls(got) != v__ast__Type_nr_muls(expected)) { - bool _t18 = false; - return _t18; + bool _t19 = false; + return _t19; } } int exp_idx = v__ast__Type_idx(expected); int got_idx = v__ast__Type_idx(got); if (exp_idx == got_idx) { - bool _t19 = true; - return _t19; + bool _t20 = true; + return _t20; } if (exp_idx == _const_v__ast__voidptr_type_idx || exp_idx == _const_v__ast__byteptr_type_idx || (v__ast__Type_is_ptr(expected) && v__ast__Type_idx(v__ast__Type_deref(expected)) == _const_v__ast__byte_type_idx)) { if (v__ast__Type_is_ptr(got) || v__ast__Type_is_pointer(got)) { - bool _t20 = true; - return _t20; - } - } - if (v__ast__Type_is_real_pointer(expected)) { - if (v__ast__Type_alias_eq(got, _const_v__ast__int_literal_type)) { bool _t21 = true; return _t21; } } - if (got_idx == _const_v__ast__voidptr_type_idx || got_idx == _const_v__ast__byteptr_type_idx || (got_idx == _const_v__ast__byte_type_idx && v__ast__Type_is_ptr(got))) { - if (v__ast__Type_is_ptr(expected) || v__ast__Type_is_pointer(expected)) { + if (v__ast__Type_is_real_pointer(expected)) { + if (v__ast__Type_alias_eq(got, _const_v__ast__int_literal_type)) { bool _t22 = true; return _t22; } } + if (got_idx == _const_v__ast__voidptr_type_idx || got_idx == _const_v__ast__byteptr_type_idx || (got_idx == _const_v__ast__byte_type_idx && v__ast__Type_is_ptr(got))) { + if (v__ast__Type_is_ptr(expected) || v__ast__Type_is_pointer(expected)) { + bool _t23 = true; + return _t23; + } + } if (v__ast__Type_alias_eq(expected, _const_v__ast__charptr_type) && v__ast__Type_alias_eq(got, v__ast__Type_ref(_const_v__ast__char_type))) { - bool _t23 = true; - return _t23; + bool _t24 = true; + return _t24; } if (v__ast__Type_has_flag(expected, v__ast__TypeFlag__optional) || v__ast__Type_has_flag(expected, v__ast__TypeFlag__result)) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, got); if (((sym->idx == _const_v__ast__error_type_idx || (v__ast__Type_alias_eq(got, _const_v__ast__none_type) || v__ast__Type_alias_eq(got, _const_v__ast__error_type))) && v__ast__Type_has_flag(expected, v__ast__TypeFlag__optional)) || ((sym->idx == _const_v__ast__error_type_idx || v__ast__Type_alias_eq(got, _const_v__ast__error_type)) && v__ast__Type_has_flag(expected, v__ast__TypeFlag__result))) { - bool _t24 = true; - return _t24; - } else if (!v__checker__Checker_check_basic(c, got, v__ast__Type_clear_flag(v__ast__Type_clear_flag(expected, v__ast__TypeFlag__optional), v__ast__TypeFlag__result))) { - bool _t25 = false; + bool _t25 = true; return _t25; + } else if (!v__checker__Checker_check_basic(c, got, v__ast__Type_clear_flag(v__ast__Type_clear_flag(expected, v__ast__TypeFlag__optional), v__ast__TypeFlag__result))) { + bool _t26 = false; + return _t26; } } if (!v__checker__Checker_check_basic(c, got, expected)) { - bool _t26 = false; - return _t26; + bool _t27 = false; + return _t27; } if (v__ast__Type_is_number(got) && v__ast__Type_is_number(expected)) { if (v__ast__Type_alias_eq(got, _const_v__ast__rune_type) && v__ast__Type_alias_eq(expected, _const_v__ast__byte_type)) { - bool _t27 = true; - return _t27; - } else if (v__ast__Type_alias_eq(expected, _const_v__ast__rune_type) && v__ast__Type_alias_eq(got, _const_v__ast__byte_type)) { bool _t28 = true; return _t28; + } else if (v__ast__Type_alias_eq(expected, _const_v__ast__rune_type) && v__ast__Type_alias_eq(got, _const_v__ast__byte_type)) { + bool _t29 = true; + return _t29; } if (!v__ast__Type_alias_eq(v__checker__Checker_promote_num(c, expected, got), expected)) { - bool _t29 = false; - return _t29; + bool _t30 = false; + return _t30; } } if (v__ast__Type_has_flag(expected, v__ast__TypeFlag__generic)) { - bool _t30 = false; - return _t30; + bool _t31 = false; + return _t31; } - bool _t31 = true; - return _t31; + bool _t32 = true; + return _t32; } _option_void v__checker__Checker_check_expected_call_arg(v__checker__Checker* c, v__ast__Type got, v__ast__Type expected_, v__ast__Language language, v__ast__CallArg arg) { @@ -51171,10 +51235,10 @@ VV_LOCAL_SYMBOL v__ast__Type v__checker__Checker_promote_num(v__checker__Checker v__ast__Type type_hi = left_type; v__ast__Type type_lo = right_type; if (v__ast__Type_idx(type_hi) < v__ast__Type_idx(type_lo)) { - v__ast__Type _var_18612 = type_hi; - v__ast__Type _var_18621 = type_lo; - type_hi = _var_18621; - type_lo = _var_18612; + v__ast__Type _var_18748 = type_hi; + v__ast__Type _var_18757 = type_lo; + type_hi = _var_18757; + type_lo = _var_18748; } int idx_hi = v__ast__Type_idx(type_hi); int idx_lo = v__ast__Type_idx(type_lo); @@ -52067,776 +52131,6 @@ Array_v__ast__InterfaceEmbedding v__checker__Checker_expand_iface_embeds(v__chec return _t11; } -VV_LOCAL_SYMBOL void v__checker__Checker_check_div_mod_by_zero(v__checker__Checker* c, v__ast__Expr expr, v__token__Kind op_kind) { - if (expr._typ == 266 /* v.ast.FloatLiteral */) { - if (string_f64((*expr._v__ast__FloatLiteral).val) == 0.0) { - string oper = (op_kind == v__token__Kind__div ? (_SLIT("division")) : (_SLIT("modulo"))); - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = oper}}, {_SLIT(" by zero"), 0, { .d_c = 0 }}})), (*expr._v__ast__FloatLiteral).pos); - } - } - else if (expr._typ == 273 /* v.ast.IntegerLiteral */) { - if (string_int((*expr._v__ast__IntegerLiteral).val) == 0) { - string oper = (op_kind == v__token__Kind__div ? (_SLIT("division")) : (_SLIT("modulo"))); - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = oper}}, {_SLIT(" by zero"), 0, { .d_c = 0 }}})), (*expr._v__ast__IntegerLiteral).pos); - } - } - else if (expr._typ == 255 /* v.ast.CastExpr */) { - v__checker__Checker_check_div_mod_by_zero(c, (*expr._v__ast__CastExpr).expr, op_kind); - } - - else { - } - ; -} - -v__ast__Type v__checker__Checker_infix_expr(v__checker__Checker* c, v__ast__InfixExpr* node) { -bool v__checker__Checker_infix_expr_defer_0 = false; -v__ast__Type former_expected_type; - former_expected_type = c->expected_type; - v__checker__Checker_infix_expr_defer_0 = true; - v__ast__Type left_type = v__checker__Checker_expr(c, node->left); - node->left_type = left_type; - c->expected_type = left_type; - v__ast__Type right_type = v__checker__Checker_expr(c, node->right); - node->right_type = right_type; - if (v__ast__Type_is_number(left_type) && !v__ast__Type_is_ptr(left_type) && (v__ast__Type_alias_eq(right_type, _const_v__ast__int_literal_type) || v__ast__Type_alias_eq(right_type, _const_v__ast__float_literal_type))) { - node->right_type = left_type; - } - if (v__ast__Type_is_number(right_type) && !v__ast__Type_is_ptr(right_type) && (v__ast__Type_alias_eq(left_type, _const_v__ast__int_literal_type) || v__ast__Type_alias_eq(left_type, _const_v__ast__float_literal_type))) { - node->left_type = right_type; - } - v__ast__TypeSymbol* right_sym = v__ast__Table_sym(c->table, right_type); - v__ast__TypeSymbol* right_final = v__ast__Table_final_sym(c->table, right_type); - v__ast__TypeSymbol* left_sym = v__ast__Table_sym(c->table, left_type); - v__ast__TypeSymbol* left_final = v__ast__Table_final_sym(c->table, left_type); - v__token__Pos left_pos = v__ast__Expr_pos(node->left); - v__token__Pos right_pos = v__ast__Expr_pos(node->right); - v__token__Pos left_right_pos = v__token__Pos_extend(left_pos, right_pos); - if (v__ast__Type_is_any_kind_of_pointer(left_type) && (node->op == v__token__Kind__plus || node->op == v__token__Kind__minus || node->op == v__token__Kind__mul || node->op == v__token__Kind__div || node->op == v__token__Kind__mod || node->op == v__token__Kind__xor || node->op == v__token__Kind__amp || node->op == v__token__Kind__pipe)) { - if (!c->pref->translated && ((v__ast__Type_is_any_kind_of_pointer(right_type) && node->op != v__token__Kind__minus) || (!v__ast__Type_is_any_kind_of_pointer(right_type) && !(node->op == v__token__Kind__plus || node->op == v__token__Kind__minus)))) { - string left_name = v__ast__Table_type_to_str(c->table, left_type); - string right_name = v__ast__Table_type_to_str(c->table, right_type); - v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("invalid operator `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` to `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } else if (node->op == v__token__Kind__plus || node->op == v__token__Kind__minus) { - if (!c->inside_unsafe && !v__ast__Expr_is_auto_deref_var(node->left) && !v__ast__Expr_is_auto_deref_var(node->right)) { - v__checker__Checker_warn(c, _SLIT("pointer arithmetic is only allowed in `unsafe` blocks"), left_right_pos); - } - if (v__ast__Type_alias_eq(left_type, _const_v__ast__voidptr_type) && !c->pref->translated) { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` cannot be used with `voidptr`"), 0, { .d_c = 0 }}})), left_pos); - } - } - } - v__ast__Type return_type = left_type; - if (node->op != v__token__Kind__key_is) { - if (node->left._typ == 268 /* v.ast.Ident */) { - if ((*node->left._v__ast__Ident).is_mut) { - v__checker__Checker_error(c, _SLIT("the `mut` keyword is invalid here"), (*node->left._v__ast__Ident).mut_pos); - } - } - else if (node->left._typ == 288 /* v.ast.SelectorExpr */) { - if ((*node->left._v__ast__SelectorExpr).is_mut) { - v__checker__Checker_error(c, _SLIT("the `mut` keyword is invalid here"), (*node->left._v__ast__SelectorExpr).mut_pos); - } - } - - else { - } - ; - } - if (node->right._typ == 268 /* v.ast.Ident */) { - if ((*node->right._v__ast__Ident).is_mut) { - v__checker__Checker_error(c, _SLIT("the `mut` keyword is invalid here"), (*node->right._v__ast__Ident).mut_pos); - } - } - else if (node->right._typ == 288 /* v.ast.SelectorExpr */) { - if ((*node->right._v__ast__SelectorExpr).is_mut) { - v__checker__Checker_error(c, _SLIT("the `mut` keyword is invalid here"), (*node->right._v__ast__SelectorExpr).mut_pos); - } - } - - else { - } - ; - bool eq_ne = (node->op == v__token__Kind__eq || node->op == v__token__Kind__ne); - switch (node->op) { - case v__token__Kind__eq: - case v__token__Kind__ne: - { - bool is_mismatch = (left_sym->kind == v__ast__Kind__alias && (right_sym->kind == v__ast__Kind__struct_ || right_sym->kind == v__ast__Kind__array || right_sym->kind == v__ast__Kind__sum_type)) || (right_sym->kind == v__ast__Kind__alias && (left_sym->kind == v__ast__Kind__struct_ || left_sym->kind == v__ast__Kind__array || left_sym->kind == v__ast__Kind__sum_type)); - if (is_mismatch) { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("possible type mismatch of compared values of `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` operation"), 0, { .d_c = 0 }}})), left_right_pos); - } else if (Array_int_contains(_const_v__ast__integer_type_idxs, left_type) && Array_int_contains(_const_v__ast__integer_type_idxs, right_type)) { - bool is_left_type_signed = Array_int_contains(_const_v__ast__signed_integer_type_idxs, left_type); - bool is_right_type_signed = Array_int_contains(_const_v__ast__signed_integer_type_idxs, right_type); - if (!is_left_type_signed && (node->right)._typ == 273 /* v.ast.IntegerLiteral */) { - if (string_int((*node->right._v__ast__IntegerLiteral).val) < 0 && Array_int_contains(_const_v__ast__int_promoted_type_idxs, left_type)) { - string lt = v__ast__Table_sym(c->table, left_type)->name; - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = lt}}, {_SLIT("` cannot be compared with negative value"), 0, { .d_c = 0 }}})), (*node->right._v__ast__IntegerLiteral).pos); - } - } else if (!is_right_type_signed && (node->left)._typ == 273 /* v.ast.IntegerLiteral */) { - if (string_int((*node->left._v__ast__IntegerLiteral).val) < 0 && Array_int_contains(_const_v__ast__int_promoted_type_idxs, right_type)) { - string rt = v__ast__Table_sym(c->table, right_type)->name; - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("negative value cannot be compared with `"), /*115 &string*/0xfe10, {.d_s = rt}}, {_SLIT("`"), 0, { .d_c = 0 }}})), (*node->left._v__ast__IntegerLiteral).pos); - } - } else if (is_left_type_signed != is_right_type_signed && left_type != _const_v__ast__int_literal_type_idx && right_type != _const_v__ast__int_literal_type_idx) { - multi_return_int_int mr_24200 = v__ast__Table_type_size(c->table, left_type); - int ls = mr_24200.arg0; - multi_return_int_int mr_24243 = v__ast__Table_type_size(c->table, right_type); - int rs = mr_24243.arg0; - if (!c->pref->translated && ((is_left_type_signed && ls < rs) || (is_right_type_signed && rs < ls))) { - string lt = v__ast__Table_sym(c->table, left_type)->name; - string rt = v__ast__Table_sym(c->table, right_type)->name; - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = lt}}, {_SLIT("` cannot be compared with `"), /*115 &string*/0xfe10, {.d_s = rt}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); - } - } - } - break; - } - case v__token__Kind__key_in: - case v__token__Kind__not_in: - { - - if (right_final->kind == (v__ast__Kind__array)) { - if (!(left_sym->kind == v__ast__Kind__sum_type || left_sym->kind == v__ast__Kind__interface_)) { - v__ast__Type elem_type = v__ast__TypeSymbol_array_info(right_final).elem_type; - _option_void _t1 = v__checker__Checker_check_expected(c, left_type, elem_type); - if (_t1.state != 0 && _t1.err._typ != _IError_None___index) { - IError err = _t1.err; - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("left operand to `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` does not match the array element type: "), /*115 &string*/0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), left_right_pos); - ; - } - - ; - } - } - else if (right_final->kind == (v__ast__Kind__map)) { - v__ast__Map map_info = v__ast__TypeSymbol_map_info(right_final); - _option_void _t2 = v__checker__Checker_check_expected(c, left_type, map_info.key_type); - if (_t2.state != 0 && _t2.err._typ != _IError_None___index) { - IError err = _t2.err; - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("left operand to `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` does not match the map key type: "), /*115 &string*/0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), left_right_pos); - ; - } - - ; - node->left_type = map_info.key_type; - } - else if (right_final->kind == (v__ast__Kind__array_fixed)) { - if (!(left_sym->kind == v__ast__Kind__sum_type || left_sym->kind == v__ast__Kind__interface_)) { - v__ast__Type elem_type = v__ast__TypeSymbol_array_fixed_info(right_final).elem_type; - _option_void _t3 = v__checker__Checker_check_expected(c, left_type, elem_type); - if (_t3.state != 0 && _t3.err._typ != _IError_None___index) { - IError err = _t3.err; - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("left operand to `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` does not match the fixed array element type: "), /*115 &string*/0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), left_right_pos); - ; - } - - ; - } - } - else { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` can only be used with arrays and maps"), 0, { .d_c = 0 }}})), node->pos); - }; - v__ast__Type _t4 = _const_v__ast__bool_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t4; - break; - } - case v__token__Kind__plus: - case v__token__Kind__minus: - case v__token__Kind__mul: - case v__token__Kind__div: - case v__token__Kind__mod: - case v__token__Kind__xor: - case v__token__Kind__amp: - case v__token__Kind__pipe: - { - if ((right_sym->info)._typ == 433 /* v.ast.Alias */ && (/* as */ *(v__ast__Alias*)__as_cast((right_sym->info)._v__ast__Alias,(right_sym->info)._typ, 433) /*expected idx: 433, name: v.ast.Alias */ ).language != v__ast__Language__c && string__eq(c->mod, (*(string*)/*ee elem_sym */array_get(string_split(v__ast__Table_type_to_str(c->table, right_type), _SLIT(".")), 0))) && v__ast__TypeSymbol_is_primitive(v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((right_sym->info)._v__ast__Alias,(right_sym->info)._typ, 433) /*expected idx: 433, name: v.ast.Alias */ ).parent_type))) { - right_sym = v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((right_sym->info)._v__ast__Alias,(right_sym->info)._typ, 433) /*expected idx: 433, name: v.ast.Alias */ ).parent_type); - } - if ((left_sym->info)._typ == 433 /* v.ast.Alias */ && (/* as */ *(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 433) /*expected idx: 433, name: v.ast.Alias */ ).language != v__ast__Language__c && string__eq(c->mod, (*(string*)/*ee elem_sym */array_get(string_split(v__ast__Table_type_to_str(c->table, left_type), _SLIT(".")), 0))) && v__ast__TypeSymbol_is_primitive(v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 433) /*expected idx: 433, name: v.ast.Alias */ ).parent_type))) { - left_sym = v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 433) /*expected idx: 433, name: v.ast.Alias */ ).parent_type); - } - if (c->pref->translated && (node->op == v__token__Kind__plus || node->op == v__token__Kind__minus || node->op == v__token__Kind__mul) && v__ast__Type_is_any_kind_of_pointer(left_type) && v__ast__Type_is_any_kind_of_pointer(right_type)) { - return_type = left_type; - } else if (!c->pref->translated && left_sym->kind == v__ast__Kind__alias && (left_sym->info)._typ == 433 /* v.ast.Alias */ && !(v__ast__TypeSymbol_is_primitive(v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 433) /*expected idx: 433, name: v.ast.Alias */ ).parent_type)))) { - if (v__ast__TypeSymbol_has_method(left_sym, v__token__Kind_str(node->op))) { - _option_v__ast__Fn _t5; - if (_t5 = v__ast__TypeSymbol_find_method(left_sym, v__token__Kind_str(node->op)), _t5.state == 0) { - v__ast__Fn method = *(v__ast__Fn*)_t5.data; - return_type = method.return_type; - } else { - IError err = _t5.err; - return_type = left_type; - } - } else { - string left_name = v__ast__Table_type_to_str(c->table, left_type); - string right_name = v__ast__Table_type_to_str(c->table, right_type); - if (string__eq(left_name, right_name)) { - v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } else { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } - } - } else if (!c->pref->translated && right_sym->kind == v__ast__Kind__alias && (right_sym->info)._typ == 433 /* v.ast.Alias */ && !(v__ast__TypeSymbol_is_primitive(v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((right_sym->info)._v__ast__Alias,(right_sym->info)._typ, 433) /*expected idx: 433, name: v.ast.Alias */ ).parent_type)))) { - if (v__ast__TypeSymbol_has_method(right_sym, v__token__Kind_str(node->op))) { - _option_v__ast__Fn _t6; - if (_t6 = v__ast__TypeSymbol_find_method(right_sym, v__token__Kind_str(node->op)), _t6.state == 0) { - v__ast__Fn method = *(v__ast__Fn*)_t6.data; - return_type = method.return_type; - } else { - IError err = _t6.err; - return_type = right_type; - } - } else { - string left_name = v__ast__Table_type_to_str(c->table, left_type); - string right_name = v__ast__Table_type_to_str(c->table, right_type); - if (string__eq(left_name, right_name)) { - v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } else { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } - } - } - if (!c->pref->translated && (left_sym->kind == v__ast__Kind__array || left_sym->kind == v__ast__Kind__array_fixed || left_sym->kind == v__ast__Kind__map || left_sym->kind == v__ast__Kind__struct_)) { - if (v__ast__TypeSymbol_has_method_with_generic_parent(left_sym, v__token__Kind_str(node->op))) { - _option_v__ast__Fn _t7; - if (_t7 = v__ast__TypeSymbol_find_method_with_generic_parent(left_sym, v__token__Kind_str(node->op)), _t7.state == 0) { - v__ast__Fn method = *(v__ast__Fn*)_t7.data; - return_type = method.return_type; - } else { - IError err = _t7.err; - return_type = left_type; - } - } else { - string left_name = v__ast__Table_type_to_str(c->table, left_type); - string right_name = v__ast__Table_type_to_str(c->table, right_type); - if (string__eq(left_name, right_name)) { - v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } else { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } - } - } else if (!c->pref->translated && (right_sym->kind == v__ast__Kind__array || right_sym->kind == v__ast__Kind__array_fixed || right_sym->kind == v__ast__Kind__map || right_sym->kind == v__ast__Kind__struct_)) { - if (v__ast__TypeSymbol_has_method_with_generic_parent(right_sym, v__token__Kind_str(node->op))) { - _option_v__ast__Fn _t8; - if (_t8 = v__ast__TypeSymbol_find_method_with_generic_parent(right_sym, v__token__Kind_str(node->op)), _t8.state == 0) { - v__ast__Fn method = *(v__ast__Fn*)_t8.data; - return_type = method.return_type; - } else { - IError err = _t8.err; - return_type = right_type; - } - } else { - string left_name = v__ast__Table_type_to_str(c->table, left_type); - string right_name = v__ast__Table_type_to_str(c->table, right_type); - if (string__eq(left_name, right_name)) { - v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } else { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } - } - } else if (v__ast__Expr_is_auto_deref_var(node->left) || v__ast__Expr_is_auto_deref_var(node->right)) { - v__ast__Type deref_left_type = (v__ast__Expr_is_auto_deref_var(node->left) ? (v__ast__Type_deref(left_type)) : (left_type)); - v__ast__Type deref_right_type = (v__ast__Expr_is_auto_deref_var(node->right) ? (v__ast__Type_deref(right_type)) : (right_type)); - string left_name = v__ast__Table_type_to_str(c->table, v__ast__mktyp(deref_left_type)); - string right_name = v__ast__Table_type_to_str(c->table, v__ast__mktyp(deref_right_type)); - if (!string__eq(left_name, right_name)) { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } - } else { - v__ast__Type unaliased_left_type = v__ast__Table_unalias_num_type(c->table, left_type); - v__ast__Type unalias_right_type = v__ast__Table_unalias_num_type(c->table, right_type); - v__ast__Type promoted_type = v__checker__Checker_promote(c, unaliased_left_type, unalias_right_type); - bool is_allowed_pointer_arithmetic = v__ast__Type_is_any_kind_of_pointer(left_type) && v__ast__Type_is_any_kind_of_pointer(right_type) && node->op == v__token__Kind__minus; - if (is_allowed_pointer_arithmetic) { - promoted_type = _const_v__ast__int_type; - } - if (v__ast__Type_idx(promoted_type) == _const_v__ast__void_type_idx) { - string left_name = v__ast__Table_type_to_str(c->table, left_type); - string right_name = v__ast__Table_type_to_str(c->table, right_type); - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } else if (v__ast__Type_has_flag(promoted_type, v__ast__TypeFlag__optional)) { - string s = v__ast__Table_type_to_str(c->table, promoted_type); - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` cannot be used with `"), /*115 &string*/0xfe10, {.d_s = s}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); - } else if (v__ast__Type_is_float(promoted_type)) { - if (node->op == v__token__Kind__mod || node->op == v__token__Kind__xor || node->op == v__token__Kind__amp || node->op == v__token__Kind__pipe) { - string side = (v__ast__Type_alias_eq(left_type, promoted_type) ? (_SLIT("left")) : (_SLIT("right"))); - v__token__Pos pos = (v__ast__Type_alias_eq(left_type, promoted_type) ? (left_pos) : (right_pos)); - string name = (v__ast__Type_alias_eq(left_type, promoted_type) ? (left_sym->name) : (right_sym->name)); - if (node->op == v__token__Kind__mod) { - v__checker__Checker_error(c, _SLIT("float modulo not allowed, use math.fmod() instead"), pos); - } else { - v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = side}}, {_SLIT(" type of `"), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` cannot be non-integer type `"), /*115 &string*/0xfe10, {.d_s = name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), pos); - } - } - } - if (node->op == v__token__Kind__div || node->op == v__token__Kind__mod) { - v__checker__Checker_check_div_mod_by_zero(c, node->right, node->op); - } - return_type = promoted_type; - } - break; - } - case v__token__Kind__gt: - case v__token__Kind__lt: - case v__token__Kind__ge: - case v__token__Kind__le: - { - if ((left_sym->kind == v__ast__Kind__array || left_sym->kind == v__ast__Kind__array_fixed) && (right_sym->kind == v__ast__Kind__array || right_sym->kind == v__ast__Kind__array_fixed)) { - v__checker__Checker_error(c, _SLIT("only `==` and `!=` are defined on arrays"), node->pos); - } else if (left_sym->kind == v__ast__Kind__struct_ && (/* as */ *(v__ast__Struct*)__as_cast((left_sym->info)._v__ast__Struct,(left_sym->info)._typ, 418) /*expected idx: 418, name: v.ast.Struct */ ).generic_types.len > 0) { - v__ast__Type _t9 = _const_v__ast__bool_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t9; - } else if (left_sym->kind == v__ast__Kind__struct_ && right_sym->kind == v__ast__Kind__struct_ && (node->op == v__token__Kind__eq || node->op == v__token__Kind__lt)) { - if (!(v__ast__TypeSymbol_has_method(left_sym, v__token__Kind_str(node->op)) && v__ast__TypeSymbol_has_method(right_sym, v__token__Kind_str(node->op)))) { - string left_name = v__ast__Table_type_to_str(c->table, left_type); - string right_name = v__ast__Table_type_to_str(c->table, right_type); - if (string__eq(left_name, right_name)) { - if (!(node->op == v__token__Kind__lt && c->pref->translated)) { - v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } - } else { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } - } - } - if (left_sym->kind == v__ast__Kind__struct_ && right_sym->kind == v__ast__Kind__struct_) { - if (!v__ast__TypeSymbol_has_method(left_sym, _SLIT("<")) && (node->op == v__token__Kind__ge || node->op == v__token__Kind__le)) { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("cannot use `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` as `<` operator method is not defined"), 0, { .d_c = 0 }}})), left_right_pos); - } else if (!v__ast__TypeSymbol_has_method(left_sym, _SLIT("<")) && node->op == v__token__Kind__gt) { - v__checker__Checker_error(c, _SLIT("cannot use `>` as `<=` operator method is not defined"), left_right_pos); - } - } else if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__generic) && v__ast__Type_has_flag(right_type, v__ast__TypeFlag__generic)) { - v__ast__Type left_gen_type = v__checker__Checker_unwrap_generic(c, left_type); - v__ast__TypeSymbol* gen_sym = v__ast__Table_sym(c->table, left_gen_type); - bool need_overload = (gen_sym->kind == v__ast__Kind__struct_ || gen_sym->kind == v__ast__Kind__interface_); - if (need_overload && !v__ast__TypeSymbol_has_method_with_generic_parent(gen_sym, _SLIT("<")) && (node->op == v__token__Kind__ge || node->op == v__token__Kind__le)) { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("cannot use `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` as `<` operator method is not defined"), 0, { .d_c = 0 }}})), left_right_pos); - } else if (need_overload && !v__ast__TypeSymbol_has_method_with_generic_parent(gen_sym, _SLIT("<")) && node->op == v__token__Kind__gt) { - v__checker__Checker_error(c, _SLIT("cannot use `>` as `<=` operator method is not defined"), left_right_pos); - } - } else if (Array_int_contains(_const_v__ast__integer_type_idxs, left_type) && Array_int_contains(_const_v__ast__integer_type_idxs, right_type)) { - bool is_left_type_signed = Array_int_contains(_const_v__ast__signed_integer_type_idxs, left_type) || left_type == _const_v__ast__int_literal_type_idx; - bool is_right_type_signed = Array_int_contains(_const_v__ast__signed_integer_type_idxs, right_type) || right_type == _const_v__ast__int_literal_type_idx; - if (is_left_type_signed != is_right_type_signed) { - if (is_right_type_signed) { - if ((node->right)._typ == 273 /* v.ast.IntegerLiteral */) { - if (string_int((*node->right._v__ast__IntegerLiteral).val) < 0) { - v__checker__Checker_error(c, _SLIT("unsigned integer cannot be compared with negative value"), (*node->right._v__ast__IntegerLiteral).pos); - } - } - } else if (is_left_type_signed) { - if ((node->left)._typ == 273 /* v.ast.IntegerLiteral */) { - if (string_int((*node->left._v__ast__IntegerLiteral).val) < 0) { - v__checker__Checker_error(c, _SLIT("unsigned integer cannot be compared with negative value"), (*node->left._v__ast__IntegerLiteral).pos); - } - } - } - } - } else if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__optional) || v__ast__Type_has_flag(right_type, v__ast__TypeFlag__optional)) { - v__token__Pos opt_comp_pos = (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__optional) ? (left_pos) : (right_pos)); - v__checker__Checker_error(c, _SLIT("unwrapped optional cannot be compared in an infix expression"), opt_comp_pos); - } - break; - } - case v__token__Kind__left_shift: - { - if (left_final->kind == v__ast__Kind__array) { - if (!node->is_stmt) { - v__checker__Checker_error(c, _SLIT("array append cannot be used in an expression"), node->pos); - } - v__checker__Checker_check_expr_opt_call(c, node->right, right_type); - multi_return_string_v__token__Pos mr_35045 = v__checker__Checker_fail_if_immutable(c, node->left); - node->auto_locked = mr_35045.arg0; - v__ast__Type left_value_type = v__ast__Table_value_type(c->table, v__checker__Checker_unwrap_generic(c, left_type)); - v__ast__TypeSymbol* left_value_sym = v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, left_value_type)); - if (left_value_sym->kind == v__ast__Kind__interface_) { - if (right_final->kind != v__ast__Kind__array) { - if (v__checker__Checker_type_implements(c, right_type, left_value_type, right_pos)) { - if (!v__ast__Type_is_ptr(right_type) && !v__ast__Type_is_pointer(right_type) && !c->inside_unsafe && right_sym->kind != v__ast__Kind__interface_) { - v__checker__Checker_mark_as_referenced(c, &node->right, true); - } - } - } else { - v__checker__Checker_type_implements(c, v__ast__Table_value_type(c->table, right_type), left_value_type, right_pos); - } - v__ast__Type _t10 = _const_v__ast__void_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t10; - } else if (left_value_sym->kind == v__ast__Kind__sum_type) { - if (right_final->kind != v__ast__Kind__array) { - if (!v__ast__Table_is_sumtype_or_in_variant(c->table, left_value_type, v__ast__mktyp(right_type))) { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot append `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` to `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); - } - } else { - v__ast__Type right_value_type = v__ast__Table_value_type(c->table, right_type); - if (!v__ast__Table_is_sumtype_or_in_variant(c->table, left_value_type, v__ast__mktyp(right_value_type))) { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot append `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` to `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); - } - } - v__ast__Type _t11 = _const_v__ast__void_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t11; - } - v__ast__Type unwrapped_right_type = v__checker__Checker_unwrap_generic(c, right_type); - if (v__checker__Checker_check_types(c, unwrapped_right_type, left_value_type)) { - if (!(!v__ast__Type_is_ptr(unwrapped_right_type) && v__ast__Type_is_ptr(left_value_type) && v__ast__Type_share(left_value_type) == v__ast__ShareType__mut_t)) { - v__ast__Type _t12 = _const_v__ast__void_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t12; - } - } else if (v__checker__Checker_check_types(c, unwrapped_right_type, v__checker__Checker_unwrap_generic(c, left_type))) { - v__ast__Type _t13 = _const_v__ast__void_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t13; - } - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot append `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` to `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); - v__ast__Type _t14 = _const_v__ast__void_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t14; - } else { - v__ast__Type _t15 = v__checker__Checker_check_shift(c, node, left_type, right_type); - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t15; - } - break; - } - case v__token__Kind__right_shift: - { - v__ast__Type _t16 = v__checker__Checker_check_shift(c, node, left_type, right_type); - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t16; - break; - } - case v__token__Kind__unsigned_right_shift: - { - int _t17; /* if prepend */ - if (!v__ast__Type_is_int(left_type)) { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("invalid operation: shift on type `"), /*115 &string*/0xfe10, {.d_s = v__ast__Table_sym(c->table, left_type)->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_pos); - _t17 = _const_v__ast__void_type_idx; - } else if (v__ast__Type_is_int_literal(left_type)) { - _t17 = _const_v__ast__u32_type_idx; - } else if (v__ast__Type_is_unsigned(left_type)) { - _t17 = left_type; - } else { - _t17 = v__ast__Type_idx(left_type) + _const_v__ast__u32_type_idx - _const_v__ast__int_type_idx; - } - int modified_left_type = _t17; - if (modified_left_type == 0) { - v__ast__Type _t18 = _const_v__ast__void_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t18; - } - *node = ((v__ast__InfixExpr){ - .or_block = node->or_block, - .left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = {0},.expr = node->left,.typname = v__ast__Table_type_str(c->table, modified_left_type),.pos = node->pos,.typ = modified_left_type,.expr_type = 0,.has_arg = 0,})))), - .right = node->right, - .auto_locked = node->auto_locked, - .ct_left_value = v__ast__empty_comptime_const_expr(), - .ct_right_value = v__ast__empty_comptime_const_expr(), - .pos = node->pos, - .left_type = left_type, - .right_type = right_type, - .op = v__token__Kind__right_shift, - .is_stmt = false, - .ct_left_value_evaled = 0, - .ct_right_value_evaled = 0, - }); - v__ast__Type _t19 = v__checker__Checker_check_shift(c, node, left_type, right_type); - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t19; - break; - } - case v__token__Kind__key_is: - case v__token__Kind__not_is: - { - v__ast__Expr right_expr = node->right; - v__ast__Type _t20 = 0; - if (right_expr._typ == 294 /* v.ast.TypeNode */) { - _t20 = (*right_expr._v__ast__TypeNode).typ; - } - else if (right_expr._typ == 280 /* v.ast.None */) { - _t20 = _const_v__ast__none_type_idx; - } - - else { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("invalid type `"), /*115 &v.ast.Expr*/0xfe10, {.d_s = v__ast__Expr_str(right_expr)}}, {_SLIT("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(right_expr)); - _t20 = ((v__ast__Type)(0)); - } - v__ast__Type typ = _t20; - if (!v__ast__Type_alias_eq(typ, ((v__ast__Type)(0)))) { - v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(c->table, typ); - string op = v__token__Kind_str(node->op); - if (typ_sym->kind == v__ast__Kind__placeholder) { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = op}}, {_SLIT(": type `"), /*115 &string*/0xfe10, {.d_s = typ_sym->name}}, {_SLIT("` does not exist"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(right_expr)); - } - if (left_sym->kind == v__ast__Kind__aggregate) { - v__ast__Type parent_left_type = (/* as */ *(v__ast__Aggregate*)__as_cast((left_sym->info)._v__ast__Aggregate,(left_sym->info)._typ, 431) /*expected idx: 431, name: v.ast.Aggregate */ ).sum_type; - left_sym = v__ast__Table_sym(c->table, parent_left_type); - } - if (!(left_sym->kind == v__ast__Kind__interface_ || left_sym->kind == v__ast__Kind__sum_type)) { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = op}}, {_SLIT("` can only be used with interfaces and sum types"), 0, { .d_c = 0 }}})), node->pos); - } else if ((left_sym->info)._typ == 437 /* v.ast.SumType */) { - if (!Array_v__ast__Type_contains((*left_sym->info._v__ast__SumType).variants, typ)) { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("` has no variant `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); - } - } - } - v__ast__Type _t21 = _const_v__ast__bool_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t21; - break; - } - case v__token__Kind__arrow: - { - if (left_sym->kind == v__ast__Kind__chan) { - v__ast__Chan chan_info = v__ast__TypeSymbol_chan_info(left_sym); - v__ast__Type elem_type = chan_info.elem_type; - if (!v__checker__Checker_check_types(c, right_type, elem_type)) { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot push `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` on `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); - } - if (chan_info.is_mut) { - v__checker__Checker_fail_if_immutable(c, node->right); - } - if (v__ast__Type_is_ptr(elem_type) && !v__ast__Type_is_ptr(right_type)) { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot push non-reference `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` on `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); - } - v__checker__Checker_stmts_ending_with_expression(c, node->or_block.stmts); - } else { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("cannot push on non-channel `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_pos); - } - v__ast__Type _t22 = _const_v__ast__void_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t22; - break; - } - case v__token__Kind__and: - case v__token__Kind__logical_or: - { - if (!c->pref->translated && !c->file->is_translated) { - if (node->left_type != _const_v__ast__bool_type_idx) { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("left operand for `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` is not a boolean"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->left)); - } - if (node->right_type != _const_v__ast__bool_type_idx) { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("right operand for `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` is not a boolean"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->right)); - } - } - if ((node->left)._typ == 272 /* v.ast.InfixExpr */) { - if ((*node->left._v__ast__InfixExpr).op != node->op && ((*node->left._v__ast__InfixExpr).op == v__token__Kind__logical_or || (*node->left._v__ast__InfixExpr).op == v__token__Kind__and)) { - v__checker__Checker_error(c, _SLIT("ambiguous boolean expression. use `()` to ensure correct order of operations"), node->pos); - } - } - break; - } - case v__token__Kind__unknown: - case v__token__Kind__eof: - case v__token__Kind__name: - case v__token__Kind__number: - case v__token__Kind__string: - case v__token__Kind__str_inter: - case v__token__Kind__chartoken: - case v__token__Kind__inc: - case v__token__Kind__dec: - case v__token__Kind__not: - case v__token__Kind__bit_not: - case v__token__Kind__question: - case v__token__Kind__comma: - case v__token__Kind__semicolon: - case v__token__Kind__colon: - case v__token__Kind__hash: - case v__token__Kind__dollar: - case v__token__Kind__at: - case v__token__Kind__str_dollar: - case v__token__Kind__assign: - case v__token__Kind__decl_assign: - case v__token__Kind__plus_assign: - case v__token__Kind__minus_assign: - case v__token__Kind__div_assign: - case v__token__Kind__mult_assign: - case v__token__Kind__xor_assign: - case v__token__Kind__mod_assign: - case v__token__Kind__or_assign: - case v__token__Kind__and_assign: - case v__token__Kind__right_shift_assign: - case v__token__Kind__left_shift_assign: - case v__token__Kind__unsigned_right_shift_assign: - case v__token__Kind__lcbr: - case v__token__Kind__rcbr: - case v__token__Kind__lpar: - case v__token__Kind__rpar: - case v__token__Kind__lsbr: - case v__token__Kind__nilsbr: - case v__token__Kind__rsbr: - case v__token__Kind__comment: - case v__token__Kind__nl: - case v__token__Kind__dot: - case v__token__Kind__dotdot: - case v__token__Kind__ellipsis: - case v__token__Kind__keyword_beg: - case v__token__Kind__key_as: - case v__token__Kind__key_asm: - case v__token__Kind__key_assert: - case v__token__Kind__key_atomic: - case v__token__Kind__key_break: - case v__token__Kind__key_const: - case v__token__Kind__key_continue: - case v__token__Kind__key_defer: - case v__token__Kind__key_else: - case v__token__Kind__key_enum: - case v__token__Kind__key_false: - case v__token__Kind__key_for: - case v__token__Kind__key_fn: - case v__token__Kind__key_global: - case v__token__Kind__key_go: - case v__token__Kind__key_goto: - case v__token__Kind__key_if: - case v__token__Kind__key_import: - case v__token__Kind__key_interface: - case v__token__Kind__key_match: - case v__token__Kind__key_module: - case v__token__Kind__key_mut: - case v__token__Kind__key_shared: - case v__token__Kind__key_lock: - case v__token__Kind__key_rlock: - case v__token__Kind__key_none: - case v__token__Kind__key_return: - case v__token__Kind__key_select: - case v__token__Kind__key_sizeof: - case v__token__Kind__key_isreftype: - case v__token__Kind__key_likely: - case v__token__Kind__key_unlikely: - case v__token__Kind__key_offsetof: - case v__token__Kind__key_struct: - case v__token__Kind__key_true: - case v__token__Kind__key_type: - case v__token__Kind__key_typeof: - case v__token__Kind__key_dump: - case v__token__Kind__key_orelse: - case v__token__Kind__key_union: - case v__token__Kind__key_pub: - case v__token__Kind__key_static: - case v__token__Kind__key_volatile: - case v__token__Kind__key_unsafe: - case v__token__Kind__keyword_end: - case v__token__Kind___end_: - default: - { - break; - } - } - ; - if (v__ast__Type_alias_eq(left_type, _const_v__ast__bool_type) && !(node->op == v__token__Kind__eq || node->op == v__token__Kind__ne || node->op == v__token__Kind__logical_or || node->op == v__token__Kind__and)) { - v__checker__Checker_error(c, _SLIT("bool types only have the following operators defined: `==`, `!=`, `||`, and `&&`"), node->pos); - } else if (v__ast__Type_alias_eq(left_type, _const_v__ast__string_type) && !(node->op == v__token__Kind__plus || node->op == v__token__Kind__eq || node->op == v__token__Kind__ne || node->op == v__token__Kind__lt || node->op == v__token__Kind__gt || node->op == v__token__Kind__le || node->op == v__token__Kind__ge)) { - v__checker__Checker_error(c, _SLIT("string types only have the following operators defined: `==`, `!=`, `<`, `>`, `<=`, `>=`, and `+`"), node->pos); - } else if (left_sym->kind == v__ast__Kind__enum_ && right_sym->kind == v__ast__Kind__enum_ && !eq_ne) { - v__ast__Enum left_enum = /* as */ *(v__ast__Enum*)__as_cast((left_sym->info)._v__ast__Enum,(left_sym->info)._typ, 447) /*expected idx: 447, name: v.ast.Enum */ ; - v__ast__Enum right_enum = /* as */ *(v__ast__Enum*)__as_cast((right_sym->info)._v__ast__Enum,(right_sym->info)._typ, 447) /*expected idx: 447, name: v.ast.Enum */ ; - if (left_enum.is_flag && right_enum.is_flag) { - if (!(node->op == v__token__Kind__pipe || node->op == v__token__Kind__amp)) { - v__checker__Checker_error(c, _SLIT("only `==`, `!=`, `|` and `&` are defined on `[flag]` tagged `enum`, use an explicit cast to `int` if needed"), node->pos); - } - } else if (!c->pref->translated && !c->file->is_translated) { - v__checker__Checker_error(c, _SLIT("only `==` and `!=` are defined on `enum`, use an explicit cast to `int` if needed"), node->pos); - } - } - if (v__ast__Table_type_kind(c->table, left_type) == v__ast__Kind__sum_type && !eq_ne) { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot use operator `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` with `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); - } else if (v__ast__Table_type_kind(c->table, right_type) == v__ast__Kind__sum_type && !eq_ne) { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot use operator `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` with `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); - } - bool left_is_optional = v__ast__Type_has_flag(left_type, v__ast__TypeFlag__optional); - bool right_is_optional = v__ast__Type_has_flag(right_type, v__ast__TypeFlag__optional); - if (left_is_optional && right_is_optional) { - v__checker__Checker_error(c, _SLIT("unwrapped optionals cannot be used in an infix expression"), left_right_pos); - } else if (left_is_optional || right_is_optional) { - v__token__Pos opt_infix_pos = (left_is_optional ? (left_pos) : (right_pos)); - v__checker__Checker_error(c, _SLIT("unwrapped optional cannot be used in an infix expression"), opt_infix_pos); - } - if (!(v__checker__Checker_symmetric_check(c, left_type, right_type) && v__checker__Checker_symmetric_check(c, right_type, left_type)) && !c->pref->translated && !c->file->is_translated && !v__ast__Expr_is_auto_deref_var(node->left) && !v__ast__Expr_is_auto_deref_var(node->right)) { - if (v__ast__Type_alias_eq(left_type, _const_v__ast__void_type) || v__ast__Type_alias_eq(right_type, _const_v__ast__void_type)) { - v__ast__Type _t23 = _const_v__ast__void_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t23; - } - if (v__ast__Type_nr_muls(left_type) > 0 && v__ast__Type_is_int(right_type)) { - v__ast__Type _t24 = return_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t24; - } - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("infix expr: cannot use `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` (right expression) as `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } - v__ast__Type _t25 = (v__token__Kind_is_relational(node->op) ? (_const_v__ast__bool_type) : (return_type)); - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t25; -} - VV_LOCAL_SYMBOL multi_return_string_v__token__Pos v__checker__Checker_fail_if_immutable(v__checker__Checker* c, v__ast__Expr expr_) { string to_lock = _SLIT(""); v__token__Pos pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); @@ -52896,19 +52190,19 @@ VV_LOCAL_SYMBOL multi_return_string_v__token__Pos v__checker__Checker_fail_if_im if (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__shared_f)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("you have to create a handle and `lock` it to modify `shared` "), /*115 &string*/0xfe10, {.d_s = kind}}, {_SLIT(" element"), 0, { .d_c = 0 }}})), v__token__Pos_extend(v__ast__Expr_pos((*expr._v__ast__IndexExpr).left), (*expr._v__ast__IndexExpr).pos)); } - multi_return_string_v__token__Pos mr_45723 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__IndexExpr).left); - to_lock = mr_45723.arg0; - pos = mr_45723.arg1; + multi_return_string_v__token__Pos mr_21955 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__IndexExpr).left); + to_lock = mr_21955.arg0; + pos = mr_21955.arg1; } else if (expr._typ == 283 /* v.ast.ParExpr */) { - multi_return_string_v__token__Pos mr_45792 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__ParExpr).expr); - to_lock = mr_45792.arg0; - pos = mr_45792.arg1; + multi_return_string_v__token__Pos mr_22024 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__ParExpr).expr); + to_lock = mr_22024.arg0; + pos = mr_22024.arg1; } else if (expr._typ == 285 /* v.ast.PrefixExpr */) { - multi_return_string_v__token__Pos mr_45864 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__PrefixExpr).right); - to_lock = mr_45864.arg0; - pos = mr_45864.arg1; + multi_return_string_v__token__Pos mr_22096 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__PrefixExpr).right); + to_lock = mr_22096.arg0; + pos = mr_22096.arg1; } else if (expr._typ == 288 /* v.ast.SelectorExpr */) { if ((*expr._v__ast__SelectorExpr).expr_type == 0) { @@ -52958,9 +52252,9 @@ VV_LOCAL_SYMBOL multi_return_string_v__token__Pos v__checker__Checker_fail_if_im string type_str = v__ast__Table_type_to_str(c->table, (*expr._v__ast__SelectorExpr).expr_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("field `"), /*115 &string*/0xfe10, {.d_s = (*expr._v__ast__SelectorExpr).field_name}}, {_SLIT("` of struct `"), /*115 &string*/0xfe10, {.d_s = type_str}}, {_SLIT("` is immutable"), 0, { .d_c = 0 }}})), (*expr._v__ast__SelectorExpr).pos); } - multi_return_string_v__token__Pos mr_47328 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__SelectorExpr).expr); - to_lock = mr_47328.arg0; - pos = mr_47328.arg1; + multi_return_string_v__token__Pos mr_23560 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__SelectorExpr).expr); + to_lock = mr_23560.arg0; + pos = mr_23560.arg1; } if ((to_lock).len != 0) { explicit_lock_needed = true; @@ -53066,9 +52360,9 @@ VV_LOCAL_SYMBOL multi_return_string_v__token__Pos v__checker__Checker_fail_if_im } else if (expr._typ == 254 /* v.ast.CallExpr */) { if (string__eq((*expr._v__ast__CallExpr).name, _SLIT("slice"))) { - multi_return_string_v__token__Pos mr_49151 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__CallExpr).left); - to_lock = mr_49151.arg0; - pos = mr_49151.arg1; + multi_return_string_v__token__Pos mr_25383 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__CallExpr).left); + to_lock = mr_25383.arg0; + pos = mr_25383.arg1; if ((to_lock).len != 0) { explicit_lock_needed = true; } @@ -53486,9 +52780,9 @@ v__ast__Type v__checker__Checker_selector_expr(v__checker__Checker* c, v__ast__S *(multi_return_v__ast__StructField_Array_v__ast__Type*) _t13.data = (multi_return_v__ast__StructField_Array_v__ast__Type){.arg0=((v__ast__StructField){.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.default_val = (string){.str=(byteptr)"", .is_lit=1},.default_expr = {0},.name = (string){.str=(byteptr)"", .is_lit=1},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.i = 0,.default_expr_typ = 0,.typ = 0,.has_default_expr = 0,.is_pub = 0,.is_mut = 0,.is_global = 0,.is_volatile = 0,}),.arg1=__new_array_with_default(0, 0, sizeof(v__ast__Type), 0)}; } - multi_return_v__ast__StructField_Array_v__ast__Type mr_63245 = (*(multi_return_v__ast__StructField_Array_v__ast__Type*)_t13.data); - field = mr_63245.arg0; - embed_types = mr_63245.arg1; + multi_return_v__ast__StructField_Array_v__ast__Type mr_39477 = (*(multi_return_v__ast__StructField_Array_v__ast__Type*)_t13.data); + field = mr_39477.arg0; + embed_types = mr_39477.arg1; node->from_embed_types = embed_types; if (sym->kind == v__ast__Kind__aggregate || sym->kind == v__ast__Kind__sum_type) { unknown_field_msg = IError_name_table[err._typ]._method_msg(err._object); @@ -53522,9 +52816,9 @@ v__ast__Type v__checker__Checker_selector_expr(v__checker__Checker* c, v__ast__S *(multi_return_v__ast__StructField_Array_v__ast__Type*) _t15.data = (multi_return_v__ast__StructField_Array_v__ast__Type){.arg0=((v__ast__StructField){.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.default_val = (string){.str=(byteptr)"", .is_lit=1},.default_expr = {0},.name = (string){.str=(byteptr)"", .is_lit=1},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.i = 0,.default_expr_typ = 0,.typ = 0,.has_default_expr = 0,.is_pub = 0,.is_mut = 0,.is_global = 0,.is_volatile = 0,}),.arg1=__new_array_with_default(0, 0, sizeof(v__ast__Type), 0)}; } - multi_return_v__ast__StructField_Array_v__ast__Type mr_64076 = (*(multi_return_v__ast__StructField_Array_v__ast__Type*)_t15.data); - field = mr_64076.arg0; - embed_types = mr_64076.arg1; + multi_return_v__ast__StructField_Array_v__ast__Type mr_40308 = (*(multi_return_v__ast__StructField_Array_v__ast__Type*)_t15.data); + field = mr_40308.arg0; + embed_types = mr_40308.arg1; node->from_embed_types = embed_types; } } @@ -54183,6 +53477,9 @@ VV_LOCAL_SYMBOL void v__checker__Checker_hash_stmt(v__checker__Checker* c, v__as } else if (string__eq(node->kind, _SLIT("flag"))) { string flag = node->main; + if (string__eq(flag, _SLIT("flag"))) { + v__checker__Checker_error(c, _SLIT("no argument(s) provided for #flag"), node->pos); + } if (string_contains(flag, _SLIT("@VROOT"))) { _option_string _t8 = v__util__resolve_vmodroot(string_replace(flag, _SLIT("@VROOT"), _SLIT("@VMODROOT")), c->file->path); if (_t8.state != 0) { /*or block*/ @@ -55791,8 +55088,8 @@ v__ast__Type v__checker__Checker_postfix_expr(v__checker__Checker* c, v__ast__Po string typ_str = v__ast__Table_type_to_str(c->table, typ); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("invalid operation: "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" (non-numeric type `"), /*115 &string*/0xfe10, {.d_s = typ_str}}, {_SLIT("`)"), 0, { .d_c = 0 }}})), node->pos); } else { - multi_return_string_v__token__Pos mr_119540 = v__checker__Checker_fail_if_immutable(c, node->expr); - node->auto_locked = mr_119540.arg0; + multi_return_string_v__token__Pos mr_95884 = v__checker__Checker_fail_if_immutable(c, node->expr); + node->auto_locked = mr_95884.arg0; } v__ast__Type _t1 = typ; return _t1; @@ -61096,6 +60393,776 @@ VV_LOCAL_SYMBOL void v__checker__Checker_smartcast_if_conds(v__checker__Checker* } } +v__ast__Type v__checker__Checker_infix_expr(v__checker__Checker* c, v__ast__InfixExpr* node) { +bool v__checker__Checker_infix_expr_defer_0 = false; +v__ast__Type former_expected_type; + former_expected_type = c->expected_type; + v__checker__Checker_infix_expr_defer_0 = true; + v__ast__Type left_type = v__checker__Checker_expr(c, node->left); + node->left_type = left_type; + c->expected_type = left_type; + v__ast__Type right_type = v__checker__Checker_expr(c, node->right); + node->right_type = right_type; + if (v__ast__Type_is_number(left_type) && !v__ast__Type_is_ptr(left_type) && (v__ast__Type_alias_eq(right_type, _const_v__ast__int_literal_type) || v__ast__Type_alias_eq(right_type, _const_v__ast__float_literal_type))) { + node->right_type = left_type; + } + if (v__ast__Type_is_number(right_type) && !v__ast__Type_is_ptr(right_type) && (v__ast__Type_alias_eq(left_type, _const_v__ast__int_literal_type) || v__ast__Type_alias_eq(left_type, _const_v__ast__float_literal_type))) { + node->left_type = right_type; + } + v__ast__TypeSymbol* right_sym = v__ast__Table_sym(c->table, right_type); + v__ast__TypeSymbol* right_final = v__ast__Table_final_sym(c->table, right_type); + v__ast__TypeSymbol* left_sym = v__ast__Table_sym(c->table, left_type); + v__ast__TypeSymbol* left_final = v__ast__Table_final_sym(c->table, left_type); + v__token__Pos left_pos = v__ast__Expr_pos(node->left); + v__token__Pos right_pos = v__ast__Expr_pos(node->right); + v__token__Pos left_right_pos = v__token__Pos_extend(left_pos, right_pos); + if (v__ast__Type_is_any_kind_of_pointer(left_type) && (node->op == v__token__Kind__plus || node->op == v__token__Kind__minus || node->op == v__token__Kind__mul || node->op == v__token__Kind__div || node->op == v__token__Kind__mod || node->op == v__token__Kind__xor || node->op == v__token__Kind__amp || node->op == v__token__Kind__pipe)) { + if (!c->pref->translated && ((v__ast__Type_is_any_kind_of_pointer(right_type) && node->op != v__token__Kind__minus) || (!v__ast__Type_is_any_kind_of_pointer(right_type) && !(node->op == v__token__Kind__plus || node->op == v__token__Kind__minus)))) { + string left_name = v__ast__Table_type_to_str(c->table, left_type); + string right_name = v__ast__Table_type_to_str(c->table, right_type); + v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("invalid operator `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` to `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } else if (node->op == v__token__Kind__plus || node->op == v__token__Kind__minus) { + if (!c->inside_unsafe && !v__ast__Expr_is_auto_deref_var(node->left) && !v__ast__Expr_is_auto_deref_var(node->right)) { + v__checker__Checker_warn(c, _SLIT("pointer arithmetic is only allowed in `unsafe` blocks"), left_right_pos); + } + if (v__ast__Type_alias_eq(left_type, _const_v__ast__voidptr_type) && !c->pref->translated) { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` cannot be used with `voidptr`"), 0, { .d_c = 0 }}})), left_pos); + } + } + } + v__ast__Type return_type = left_type; + if (node->op != v__token__Kind__key_is) { + if (node->left._typ == 268 /* v.ast.Ident */) { + if ((*node->left._v__ast__Ident).is_mut) { + v__checker__Checker_error(c, _SLIT("the `mut` keyword is invalid here"), (*node->left._v__ast__Ident).mut_pos); + } + } + else if (node->left._typ == 288 /* v.ast.SelectorExpr */) { + if ((*node->left._v__ast__SelectorExpr).is_mut) { + v__checker__Checker_error(c, _SLIT("the `mut` keyword is invalid here"), (*node->left._v__ast__SelectorExpr).mut_pos); + } + } + + else { + } + ; + } + if (node->right._typ == 268 /* v.ast.Ident */) { + if ((*node->right._v__ast__Ident).is_mut) { + v__checker__Checker_error(c, _SLIT("the `mut` keyword is invalid here"), (*node->right._v__ast__Ident).mut_pos); + } + } + else if (node->right._typ == 288 /* v.ast.SelectorExpr */) { + if ((*node->right._v__ast__SelectorExpr).is_mut) { + v__checker__Checker_error(c, _SLIT("the `mut` keyword is invalid here"), (*node->right._v__ast__SelectorExpr).mut_pos); + } + } + + else { + } + ; + bool eq_ne = (node->op == v__token__Kind__eq || node->op == v__token__Kind__ne); + switch (node->op) { + case v__token__Kind__eq: + case v__token__Kind__ne: + { + bool is_mismatch = (left_sym->kind == v__ast__Kind__alias && (right_sym->kind == v__ast__Kind__struct_ || right_sym->kind == v__ast__Kind__array || right_sym->kind == v__ast__Kind__sum_type)) || (right_sym->kind == v__ast__Kind__alias && (left_sym->kind == v__ast__Kind__struct_ || left_sym->kind == v__ast__Kind__array || left_sym->kind == v__ast__Kind__sum_type)); + if (is_mismatch) { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("possible type mismatch of compared values of `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` operation"), 0, { .d_c = 0 }}})), left_right_pos); + } else if (Array_int_contains(_const_v__ast__integer_type_idxs, left_type) && Array_int_contains(_const_v__ast__integer_type_idxs, right_type)) { + bool is_left_type_signed = Array_int_contains(_const_v__ast__signed_integer_type_idxs, left_type); + bool is_right_type_signed = Array_int_contains(_const_v__ast__signed_integer_type_idxs, right_type); + if (!is_left_type_signed && (node->right)._typ == 273 /* v.ast.IntegerLiteral */) { + if (string_int((*node->right._v__ast__IntegerLiteral).val) < 0 && Array_int_contains(_const_v__ast__int_promoted_type_idxs, left_type)) { + string lt = v__ast__Table_sym(c->table, left_type)->name; + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = lt}}, {_SLIT("` cannot be compared with negative value"), 0, { .d_c = 0 }}})), (*node->right._v__ast__IntegerLiteral).pos); + } + } else if (!is_right_type_signed && (node->left)._typ == 273 /* v.ast.IntegerLiteral */) { + if (string_int((*node->left._v__ast__IntegerLiteral).val) < 0 && Array_int_contains(_const_v__ast__int_promoted_type_idxs, right_type)) { + string rt = v__ast__Table_sym(c->table, right_type)->name; + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("negative value cannot be compared with `"), /*115 &string*/0xfe10, {.d_s = rt}}, {_SLIT("`"), 0, { .d_c = 0 }}})), (*node->left._v__ast__IntegerLiteral).pos); + } + } else if (is_left_type_signed != is_right_type_signed && left_type != _const_v__ast__int_literal_type_idx && right_type != _const_v__ast__int_literal_type_idx) { + multi_return_int_int mr_3899 = v__ast__Table_type_size(c->table, left_type); + int ls = mr_3899.arg0; + multi_return_int_int mr_3942 = v__ast__Table_type_size(c->table, right_type); + int rs = mr_3942.arg0; + if (!c->pref->translated && ((is_left_type_signed && ls < rs) || (is_right_type_signed && rs < ls))) { + string lt = v__ast__Table_sym(c->table, left_type)->name; + string rt = v__ast__Table_sym(c->table, right_type)->name; + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = lt}}, {_SLIT("` cannot be compared with `"), /*115 &string*/0xfe10, {.d_s = rt}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); + } + } + } + break; + } + case v__token__Kind__key_in: + case v__token__Kind__not_in: + { + + if (right_final->kind == (v__ast__Kind__array)) { + if (!(left_sym->kind == v__ast__Kind__sum_type || left_sym->kind == v__ast__Kind__interface_)) { + v__ast__Type elem_type = v__ast__TypeSymbol_array_info(right_final).elem_type; + _option_void _t1 = v__checker__Checker_check_expected(c, left_type, elem_type); + if (_t1.state != 0 && _t1.err._typ != _IError_None___index) { + IError err = _t1.err; + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("left operand to `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` does not match the array element type: "), /*115 &string*/0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), left_right_pos); + ; + } + + ; + } + } + else if (right_final->kind == (v__ast__Kind__map)) { + v__ast__Map map_info = v__ast__TypeSymbol_map_info(right_final); + _option_void _t2 = v__checker__Checker_check_expected(c, left_type, map_info.key_type); + if (_t2.state != 0 && _t2.err._typ != _IError_None___index) { + IError err = _t2.err; + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("left operand to `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` does not match the map key type: "), /*115 &string*/0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), left_right_pos); + ; + } + + ; + node->left_type = map_info.key_type; + } + else if (right_final->kind == (v__ast__Kind__array_fixed)) { + if (!(left_sym->kind == v__ast__Kind__sum_type || left_sym->kind == v__ast__Kind__interface_)) { + v__ast__Type elem_type = v__ast__TypeSymbol_array_fixed_info(right_final).elem_type; + _option_void _t3 = v__checker__Checker_check_expected(c, left_type, elem_type); + if (_t3.state != 0 && _t3.err._typ != _IError_None___index) { + IError err = _t3.err; + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("left operand to `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` does not match the fixed array element type: "), /*115 &string*/0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), left_right_pos); + ; + } + + ; + } + } + else { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` can only be used with arrays and maps"), 0, { .d_c = 0 }}})), node->pos); + }; + v__ast__Type _t4 = _const_v__ast__bool_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t4; + break; + } + case v__token__Kind__plus: + case v__token__Kind__minus: + case v__token__Kind__mul: + case v__token__Kind__div: + case v__token__Kind__mod: + case v__token__Kind__xor: + case v__token__Kind__amp: + case v__token__Kind__pipe: + { + if ((right_sym->info)._typ == 433 /* v.ast.Alias */ && (/* as */ *(v__ast__Alias*)__as_cast((right_sym->info)._v__ast__Alias,(right_sym->info)._typ, 433) /*expected idx: 433, name: v.ast.Alias */ ).language != v__ast__Language__c && string__eq(c->mod, (*(string*)/*ee elem_sym */array_get(string_split(v__ast__Table_type_to_str(c->table, right_type), _SLIT(".")), 0))) && v__ast__TypeSymbol_is_primitive(v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((right_sym->info)._v__ast__Alias,(right_sym->info)._typ, 433) /*expected idx: 433, name: v.ast.Alias */ ).parent_type))) { + right_sym = v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((right_sym->info)._v__ast__Alias,(right_sym->info)._typ, 433) /*expected idx: 433, name: v.ast.Alias */ ).parent_type); + } + if ((left_sym->info)._typ == 433 /* v.ast.Alias */ && (/* as */ *(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 433) /*expected idx: 433, name: v.ast.Alias */ ).language != v__ast__Language__c && string__eq(c->mod, (*(string*)/*ee elem_sym */array_get(string_split(v__ast__Table_type_to_str(c->table, left_type), _SLIT(".")), 0))) && v__ast__TypeSymbol_is_primitive(v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 433) /*expected idx: 433, name: v.ast.Alias */ ).parent_type))) { + left_sym = v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 433) /*expected idx: 433, name: v.ast.Alias */ ).parent_type); + } + if (c->pref->translated && (node->op == v__token__Kind__plus || node->op == v__token__Kind__minus || node->op == v__token__Kind__mul) && v__ast__Type_is_any_kind_of_pointer(left_type) && v__ast__Type_is_any_kind_of_pointer(right_type)) { + return_type = left_type; + } else if (!c->pref->translated && left_sym->kind == v__ast__Kind__alias && (left_sym->info)._typ == 433 /* v.ast.Alias */ && !(v__ast__TypeSymbol_is_primitive(v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 433) /*expected idx: 433, name: v.ast.Alias */ ).parent_type)))) { + if (v__ast__TypeSymbol_has_method(left_sym, v__token__Kind_str(node->op))) { + _option_v__ast__Fn _t5; + if (_t5 = v__ast__TypeSymbol_find_method(left_sym, v__token__Kind_str(node->op)), _t5.state == 0) { + v__ast__Fn method = *(v__ast__Fn*)_t5.data; + return_type = method.return_type; + } else { + IError err = _t5.err; + return_type = left_type; + } + } else { + string left_name = v__ast__Table_type_to_str(c->table, left_type); + string right_name = v__ast__Table_type_to_str(c->table, right_type); + if (string__eq(left_name, right_name)) { + v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } else { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } + } + } else if (!c->pref->translated && right_sym->kind == v__ast__Kind__alias && (right_sym->info)._typ == 433 /* v.ast.Alias */ && !(v__ast__TypeSymbol_is_primitive(v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((right_sym->info)._v__ast__Alias,(right_sym->info)._typ, 433) /*expected idx: 433, name: v.ast.Alias */ ).parent_type)))) { + if (v__ast__TypeSymbol_has_method(right_sym, v__token__Kind_str(node->op))) { + _option_v__ast__Fn _t6; + if (_t6 = v__ast__TypeSymbol_find_method(right_sym, v__token__Kind_str(node->op)), _t6.state == 0) { + v__ast__Fn method = *(v__ast__Fn*)_t6.data; + return_type = method.return_type; + } else { + IError err = _t6.err; + return_type = right_type; + } + } else { + string left_name = v__ast__Table_type_to_str(c->table, left_type); + string right_name = v__ast__Table_type_to_str(c->table, right_type); + if (string__eq(left_name, right_name)) { + v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } else { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } + } + } + if (!c->pref->translated && (left_sym->kind == v__ast__Kind__array || left_sym->kind == v__ast__Kind__array_fixed || left_sym->kind == v__ast__Kind__map || left_sym->kind == v__ast__Kind__struct_)) { + if (v__ast__TypeSymbol_has_method_with_generic_parent(left_sym, v__token__Kind_str(node->op))) { + _option_v__ast__Fn _t7; + if (_t7 = v__ast__TypeSymbol_find_method_with_generic_parent(left_sym, v__token__Kind_str(node->op)), _t7.state == 0) { + v__ast__Fn method = *(v__ast__Fn*)_t7.data; + return_type = method.return_type; + } else { + IError err = _t7.err; + return_type = left_type; + } + } else { + string left_name = v__ast__Table_type_to_str(c->table, left_type); + string right_name = v__ast__Table_type_to_str(c->table, right_type); + if (string__eq(left_name, right_name)) { + v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } else { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } + } + } else if (!c->pref->translated && (right_sym->kind == v__ast__Kind__array || right_sym->kind == v__ast__Kind__array_fixed || right_sym->kind == v__ast__Kind__map || right_sym->kind == v__ast__Kind__struct_)) { + if (v__ast__TypeSymbol_has_method_with_generic_parent(right_sym, v__token__Kind_str(node->op))) { + _option_v__ast__Fn _t8; + if (_t8 = v__ast__TypeSymbol_find_method_with_generic_parent(right_sym, v__token__Kind_str(node->op)), _t8.state == 0) { + v__ast__Fn method = *(v__ast__Fn*)_t8.data; + return_type = method.return_type; + } else { + IError err = _t8.err; + return_type = right_type; + } + } else { + string left_name = v__ast__Table_type_to_str(c->table, left_type); + string right_name = v__ast__Table_type_to_str(c->table, right_type); + if (string__eq(left_name, right_name)) { + v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } else { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } + } + } else if (v__ast__Expr_is_auto_deref_var(node->left) || v__ast__Expr_is_auto_deref_var(node->right)) { + v__ast__Type deref_left_type = (v__ast__Expr_is_auto_deref_var(node->left) ? (v__ast__Type_deref(left_type)) : (left_type)); + v__ast__Type deref_right_type = (v__ast__Expr_is_auto_deref_var(node->right) ? (v__ast__Type_deref(right_type)) : (right_type)); + string left_name = v__ast__Table_type_to_str(c->table, v__ast__mktyp(deref_left_type)); + string right_name = v__ast__Table_type_to_str(c->table, v__ast__mktyp(deref_right_type)); + if (!string__eq(left_name, right_name)) { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } + } else { + v__ast__Type unaliased_left_type = v__ast__Table_unalias_num_type(c->table, left_type); + v__ast__Type unalias_right_type = v__ast__Table_unalias_num_type(c->table, right_type); + v__ast__Type promoted_type = v__checker__Checker_promote(c, unaliased_left_type, unalias_right_type); + bool is_allowed_pointer_arithmetic = v__ast__Type_is_any_kind_of_pointer(left_type) && v__ast__Type_is_any_kind_of_pointer(right_type) && node->op == v__token__Kind__minus; + if (is_allowed_pointer_arithmetic) { + promoted_type = _const_v__ast__int_type; + } + if (v__ast__Type_idx(promoted_type) == _const_v__ast__void_type_idx) { + string left_name = v__ast__Table_type_to_str(c->table, left_type); + string right_name = v__ast__Table_type_to_str(c->table, right_type); + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } else if (v__ast__Type_has_flag(promoted_type, v__ast__TypeFlag__optional)) { + string s = v__ast__Table_type_to_str(c->table, promoted_type); + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` cannot be used with `"), /*115 &string*/0xfe10, {.d_s = s}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); + } else if (v__ast__Type_is_float(promoted_type)) { + if (node->op == v__token__Kind__mod || node->op == v__token__Kind__xor || node->op == v__token__Kind__amp || node->op == v__token__Kind__pipe) { + string side = (v__ast__Type_alias_eq(left_type, promoted_type) ? (_SLIT("left")) : (_SLIT("right"))); + v__token__Pos pos = (v__ast__Type_alias_eq(left_type, promoted_type) ? (left_pos) : (right_pos)); + string name = (v__ast__Type_alias_eq(left_type, promoted_type) ? (left_sym->name) : (right_sym->name)); + if (node->op == v__token__Kind__mod) { + v__checker__Checker_error(c, _SLIT("float modulo not allowed, use math.fmod() instead"), pos); + } else { + v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = side}}, {_SLIT(" type of `"), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` cannot be non-integer type `"), /*115 &string*/0xfe10, {.d_s = name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), pos); + } + } + } + if (node->op == v__token__Kind__div || node->op == v__token__Kind__mod) { + v__checker__Checker_check_div_mod_by_zero(c, node->right, node->op); + } + return_type = promoted_type; + } + break; + } + case v__token__Kind__gt: + case v__token__Kind__lt: + case v__token__Kind__ge: + case v__token__Kind__le: + { + if ((left_sym->kind == v__ast__Kind__array || left_sym->kind == v__ast__Kind__array_fixed) && (right_sym->kind == v__ast__Kind__array || right_sym->kind == v__ast__Kind__array_fixed)) { + v__checker__Checker_error(c, _SLIT("only `==` and `!=` are defined on arrays"), node->pos); + } else if (left_sym->kind == v__ast__Kind__struct_ && (/* as */ *(v__ast__Struct*)__as_cast((left_sym->info)._v__ast__Struct,(left_sym->info)._typ, 418) /*expected idx: 418, name: v.ast.Struct */ ).generic_types.len > 0) { + v__ast__Type _t9 = _const_v__ast__bool_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t9; + } else if (left_sym->kind == v__ast__Kind__struct_ && right_sym->kind == v__ast__Kind__struct_ && (node->op == v__token__Kind__eq || node->op == v__token__Kind__lt)) { + if (!(v__ast__TypeSymbol_has_method(left_sym, v__token__Kind_str(node->op)) && v__ast__TypeSymbol_has_method(right_sym, v__token__Kind_str(node->op)))) { + string left_name = v__ast__Table_type_to_str(c->table, left_type); + string right_name = v__ast__Table_type_to_str(c->table, right_type); + if (string__eq(left_name, right_name)) { + if (!(node->op == v__token__Kind__lt && c->pref->translated)) { + v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } + } else { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } + } + } + if (left_sym->kind == v__ast__Kind__struct_ && right_sym->kind == v__ast__Kind__struct_) { + if (!v__ast__TypeSymbol_has_method(left_sym, _SLIT("<")) && (node->op == v__token__Kind__ge || node->op == v__token__Kind__le)) { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("cannot use `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` as `<` operator method is not defined"), 0, { .d_c = 0 }}})), left_right_pos); + } else if (!v__ast__TypeSymbol_has_method(left_sym, _SLIT("<")) && node->op == v__token__Kind__gt) { + v__checker__Checker_error(c, _SLIT("cannot use `>` as `<=` operator method is not defined"), left_right_pos); + } + } else if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__generic) && v__ast__Type_has_flag(right_type, v__ast__TypeFlag__generic)) { + v__ast__Type left_gen_type = v__checker__Checker_unwrap_generic(c, left_type); + v__ast__TypeSymbol* gen_sym = v__ast__Table_sym(c->table, left_gen_type); + bool need_overload = (gen_sym->kind == v__ast__Kind__struct_ || gen_sym->kind == v__ast__Kind__interface_); + if (need_overload && !v__ast__TypeSymbol_has_method_with_generic_parent(gen_sym, _SLIT("<")) && (node->op == v__token__Kind__ge || node->op == v__token__Kind__le)) { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("cannot use `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` as `<` operator method is not defined"), 0, { .d_c = 0 }}})), left_right_pos); + } else if (need_overload && !v__ast__TypeSymbol_has_method_with_generic_parent(gen_sym, _SLIT("<")) && node->op == v__token__Kind__gt) { + v__checker__Checker_error(c, _SLIT("cannot use `>` as `<=` operator method is not defined"), left_right_pos); + } + } else if (Array_int_contains(_const_v__ast__integer_type_idxs, left_type) && Array_int_contains(_const_v__ast__integer_type_idxs, right_type)) { + bool is_left_type_signed = Array_int_contains(_const_v__ast__signed_integer_type_idxs, left_type) || left_type == _const_v__ast__int_literal_type_idx; + bool is_right_type_signed = Array_int_contains(_const_v__ast__signed_integer_type_idxs, right_type) || right_type == _const_v__ast__int_literal_type_idx; + if (is_left_type_signed != is_right_type_signed) { + if (is_right_type_signed) { + if ((node->right)._typ == 273 /* v.ast.IntegerLiteral */) { + if (string_int((*node->right._v__ast__IntegerLiteral).val) < 0) { + v__checker__Checker_error(c, _SLIT("unsigned integer cannot be compared with negative value"), (*node->right._v__ast__IntegerLiteral).pos); + } + } + } else if (is_left_type_signed) { + if ((node->left)._typ == 273 /* v.ast.IntegerLiteral */) { + if (string_int((*node->left._v__ast__IntegerLiteral).val) < 0) { + v__checker__Checker_error(c, _SLIT("unsigned integer cannot be compared with negative value"), (*node->left._v__ast__IntegerLiteral).pos); + } + } + } + } + } else if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__optional) || v__ast__Type_has_flag(right_type, v__ast__TypeFlag__optional)) { + v__token__Pos opt_comp_pos = (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__optional) ? (left_pos) : (right_pos)); + v__checker__Checker_error(c, _SLIT("unwrapped optional cannot be compared in an infix expression"), opt_comp_pos); + } + break; + } + case v__token__Kind__left_shift: + { + if (left_final->kind == v__ast__Kind__array) { + if (!node->is_stmt) { + v__checker__Checker_error(c, _SLIT("array append cannot be used in an expression"), node->pos); + } + v__checker__Checker_check_expr_opt_call(c, node->right, right_type); + multi_return_string_v__token__Pos mr_14744 = v__checker__Checker_fail_if_immutable(c, node->left); + node->auto_locked = mr_14744.arg0; + v__ast__Type left_value_type = v__ast__Table_value_type(c->table, v__checker__Checker_unwrap_generic(c, left_type)); + v__ast__TypeSymbol* left_value_sym = v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, left_value_type)); + if (left_value_sym->kind == v__ast__Kind__interface_) { + if (right_final->kind != v__ast__Kind__array) { + if (v__checker__Checker_type_implements(c, right_type, left_value_type, right_pos)) { + if (!v__ast__Type_is_ptr(right_type) && !v__ast__Type_is_pointer(right_type) && !c->inside_unsafe && right_sym->kind != v__ast__Kind__interface_) { + v__checker__Checker_mark_as_referenced(c, &node->right, true); + } + } + } else { + v__checker__Checker_type_implements(c, v__ast__Table_value_type(c->table, right_type), left_value_type, right_pos); + } + v__ast__Type _t10 = _const_v__ast__void_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t10; + } else if (left_value_sym->kind == v__ast__Kind__sum_type) { + if (right_final->kind != v__ast__Kind__array) { + if (!v__ast__Table_is_sumtype_or_in_variant(c->table, left_value_type, v__ast__mktyp(right_type))) { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot append `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` to `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); + } + } else { + v__ast__Type right_value_type = v__ast__Table_value_type(c->table, right_type); + if (!v__ast__Table_is_sumtype_or_in_variant(c->table, left_value_type, v__ast__mktyp(right_value_type))) { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot append `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` to `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); + } + } + v__ast__Type _t11 = _const_v__ast__void_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t11; + } + v__ast__Type unwrapped_right_type = v__checker__Checker_unwrap_generic(c, right_type); + if (v__checker__Checker_check_types(c, unwrapped_right_type, left_value_type)) { + if (!(!v__ast__Type_is_ptr(unwrapped_right_type) && v__ast__Type_is_ptr(left_value_type) && v__ast__Type_share(left_value_type) == v__ast__ShareType__mut_t)) { + v__ast__Type _t12 = _const_v__ast__void_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t12; + } + } else if (v__checker__Checker_check_types(c, unwrapped_right_type, v__checker__Checker_unwrap_generic(c, left_type))) { + v__ast__Type _t13 = _const_v__ast__void_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t13; + } + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot append `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` to `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); + v__ast__Type _t14 = _const_v__ast__void_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t14; + } else { + v__ast__Type _t15 = v__checker__Checker_check_shift(c, node, left_type, right_type); + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t15; + } + break; + } + case v__token__Kind__right_shift: + { + v__ast__Type _t16 = v__checker__Checker_check_shift(c, node, left_type, right_type); + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t16; + break; + } + case v__token__Kind__unsigned_right_shift: + { + int _t17; /* if prepend */ + if (!v__ast__Type_is_int(left_type)) { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("invalid operation: shift on type `"), /*115 &string*/0xfe10, {.d_s = v__ast__Table_sym(c->table, left_type)->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_pos); + _t17 = _const_v__ast__void_type_idx; + } else if (v__ast__Type_is_int_literal(left_type)) { + _t17 = _const_v__ast__u32_type_idx; + } else if (v__ast__Type_is_unsigned(left_type)) { + _t17 = left_type; + } else { + _t17 = v__ast__Type_idx(left_type) + _const_v__ast__u32_type_idx - _const_v__ast__int_type_idx; + } + int modified_left_type = _t17; + if (modified_left_type == 0) { + v__ast__Type _t18 = _const_v__ast__void_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t18; + } + *node = ((v__ast__InfixExpr){ + .or_block = node->or_block, + .left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = {0},.expr = node->left,.typname = v__ast__Table_type_str(c->table, modified_left_type),.pos = node->pos,.typ = modified_left_type,.expr_type = 0,.has_arg = 0,})))), + .right = node->right, + .auto_locked = node->auto_locked, + .ct_left_value = v__ast__empty_comptime_const_expr(), + .ct_right_value = v__ast__empty_comptime_const_expr(), + .pos = node->pos, + .left_type = left_type, + .right_type = right_type, + .op = v__token__Kind__right_shift, + .is_stmt = false, + .ct_left_value_evaled = 0, + .ct_right_value_evaled = 0, + }); + v__ast__Type _t19 = v__checker__Checker_check_shift(c, node, left_type, right_type); + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t19; + break; + } + case v__token__Kind__key_is: + case v__token__Kind__not_is: + { + v__ast__Expr right_expr = node->right; + v__ast__Type _t20 = 0; + if (right_expr._typ == 294 /* v.ast.TypeNode */) { + _t20 = (*right_expr._v__ast__TypeNode).typ; + } + else if (right_expr._typ == 280 /* v.ast.None */) { + _t20 = _const_v__ast__none_type_idx; + } + + else { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("invalid type `"), /*115 &v.ast.Expr*/0xfe10, {.d_s = v__ast__Expr_str(right_expr)}}, {_SLIT("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(right_expr)); + _t20 = ((v__ast__Type)(0)); + } + v__ast__Type typ = _t20; + if (!v__ast__Type_alias_eq(typ, ((v__ast__Type)(0)))) { + v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(c->table, typ); + string op = v__token__Kind_str(node->op); + if (typ_sym->kind == v__ast__Kind__placeholder) { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = op}}, {_SLIT(": type `"), /*115 &string*/0xfe10, {.d_s = typ_sym->name}}, {_SLIT("` does not exist"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(right_expr)); + } + if (left_sym->kind == v__ast__Kind__aggregate) { + v__ast__Type parent_left_type = (/* as */ *(v__ast__Aggregate*)__as_cast((left_sym->info)._v__ast__Aggregate,(left_sym->info)._typ, 431) /*expected idx: 431, name: v.ast.Aggregate */ ).sum_type; + left_sym = v__ast__Table_sym(c->table, parent_left_type); + } + if (!(left_sym->kind == v__ast__Kind__interface_ || left_sym->kind == v__ast__Kind__sum_type)) { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = op}}, {_SLIT("` can only be used with interfaces and sum types"), 0, { .d_c = 0 }}})), node->pos); + } else if ((left_sym->info)._typ == 437 /* v.ast.SumType */) { + if (!Array_v__ast__Type_contains((*left_sym->info._v__ast__SumType).variants, typ)) { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("` has no variant `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); + } + } + } + v__ast__Type _t21 = _const_v__ast__bool_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t21; + break; + } + case v__token__Kind__arrow: + { + if (left_sym->kind == v__ast__Kind__chan) { + v__ast__Chan chan_info = v__ast__TypeSymbol_chan_info(left_sym); + v__ast__Type elem_type = chan_info.elem_type; + if (!v__checker__Checker_check_types(c, right_type, elem_type)) { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot push `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` on `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); + } + if (chan_info.is_mut) { + v__checker__Checker_fail_if_immutable(c, node->right); + } + if (v__ast__Type_is_ptr(elem_type) && !v__ast__Type_is_ptr(right_type)) { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot push non-reference `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` on `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); + } + v__checker__Checker_stmts_ending_with_expression(c, node->or_block.stmts); + } else { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("cannot push on non-channel `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_pos); + } + v__ast__Type _t22 = _const_v__ast__void_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t22; + break; + } + case v__token__Kind__and: + case v__token__Kind__logical_or: + { + if (!c->pref->translated && !c->file->is_translated) { + if (node->left_type != _const_v__ast__bool_type_idx) { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("left operand for `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` is not a boolean"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->left)); + } + if (node->right_type != _const_v__ast__bool_type_idx) { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("right operand for `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` is not a boolean"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->right)); + } + } + if ((node->left)._typ == 272 /* v.ast.InfixExpr */) { + if ((*node->left._v__ast__InfixExpr).op != node->op && ((*node->left._v__ast__InfixExpr).op == v__token__Kind__logical_or || (*node->left._v__ast__InfixExpr).op == v__token__Kind__and)) { + v__checker__Checker_error(c, _SLIT("ambiguous boolean expression. use `()` to ensure correct order of operations"), node->pos); + } + } + break; + } + case v__token__Kind__unknown: + case v__token__Kind__eof: + case v__token__Kind__name: + case v__token__Kind__number: + case v__token__Kind__string: + case v__token__Kind__str_inter: + case v__token__Kind__chartoken: + case v__token__Kind__inc: + case v__token__Kind__dec: + case v__token__Kind__not: + case v__token__Kind__bit_not: + case v__token__Kind__question: + case v__token__Kind__comma: + case v__token__Kind__semicolon: + case v__token__Kind__colon: + case v__token__Kind__hash: + case v__token__Kind__dollar: + case v__token__Kind__at: + case v__token__Kind__str_dollar: + case v__token__Kind__assign: + case v__token__Kind__decl_assign: + case v__token__Kind__plus_assign: + case v__token__Kind__minus_assign: + case v__token__Kind__div_assign: + case v__token__Kind__mult_assign: + case v__token__Kind__xor_assign: + case v__token__Kind__mod_assign: + case v__token__Kind__or_assign: + case v__token__Kind__and_assign: + case v__token__Kind__right_shift_assign: + case v__token__Kind__left_shift_assign: + case v__token__Kind__unsigned_right_shift_assign: + case v__token__Kind__lcbr: + case v__token__Kind__rcbr: + case v__token__Kind__lpar: + case v__token__Kind__rpar: + case v__token__Kind__lsbr: + case v__token__Kind__nilsbr: + case v__token__Kind__rsbr: + case v__token__Kind__comment: + case v__token__Kind__nl: + case v__token__Kind__dot: + case v__token__Kind__dotdot: + case v__token__Kind__ellipsis: + case v__token__Kind__keyword_beg: + case v__token__Kind__key_as: + case v__token__Kind__key_asm: + case v__token__Kind__key_assert: + case v__token__Kind__key_atomic: + case v__token__Kind__key_break: + case v__token__Kind__key_const: + case v__token__Kind__key_continue: + case v__token__Kind__key_defer: + case v__token__Kind__key_else: + case v__token__Kind__key_enum: + case v__token__Kind__key_false: + case v__token__Kind__key_for: + case v__token__Kind__key_fn: + case v__token__Kind__key_global: + case v__token__Kind__key_go: + case v__token__Kind__key_goto: + case v__token__Kind__key_if: + case v__token__Kind__key_import: + case v__token__Kind__key_interface: + case v__token__Kind__key_match: + case v__token__Kind__key_module: + case v__token__Kind__key_mut: + case v__token__Kind__key_shared: + case v__token__Kind__key_lock: + case v__token__Kind__key_rlock: + case v__token__Kind__key_none: + case v__token__Kind__key_return: + case v__token__Kind__key_select: + case v__token__Kind__key_sizeof: + case v__token__Kind__key_isreftype: + case v__token__Kind__key_likely: + case v__token__Kind__key_unlikely: + case v__token__Kind__key_offsetof: + case v__token__Kind__key_struct: + case v__token__Kind__key_true: + case v__token__Kind__key_type: + case v__token__Kind__key_typeof: + case v__token__Kind__key_dump: + case v__token__Kind__key_orelse: + case v__token__Kind__key_union: + case v__token__Kind__key_pub: + case v__token__Kind__key_static: + case v__token__Kind__key_volatile: + case v__token__Kind__key_unsafe: + case v__token__Kind__keyword_end: + case v__token__Kind___end_: + default: + { + break; + } + } + ; + if (v__ast__Type_alias_eq(left_type, _const_v__ast__bool_type) && !(node->op == v__token__Kind__eq || node->op == v__token__Kind__ne || node->op == v__token__Kind__logical_or || node->op == v__token__Kind__and)) { + v__checker__Checker_error(c, _SLIT("bool types only have the following operators defined: `==`, `!=`, `||`, and `&&`"), node->pos); + } else if (v__ast__Type_alias_eq(left_type, _const_v__ast__string_type) && !(node->op == v__token__Kind__plus || node->op == v__token__Kind__eq || node->op == v__token__Kind__ne || node->op == v__token__Kind__lt || node->op == v__token__Kind__gt || node->op == v__token__Kind__le || node->op == v__token__Kind__ge)) { + v__checker__Checker_error(c, _SLIT("string types only have the following operators defined: `==`, `!=`, `<`, `>`, `<=`, `>=`, and `+`"), node->pos); + } else if (left_sym->kind == v__ast__Kind__enum_ && right_sym->kind == v__ast__Kind__enum_ && !eq_ne) { + v__ast__Enum left_enum = /* as */ *(v__ast__Enum*)__as_cast((left_sym->info)._v__ast__Enum,(left_sym->info)._typ, 447) /*expected idx: 447, name: v.ast.Enum */ ; + v__ast__Enum right_enum = /* as */ *(v__ast__Enum*)__as_cast((right_sym->info)._v__ast__Enum,(right_sym->info)._typ, 447) /*expected idx: 447, name: v.ast.Enum */ ; + if (left_enum.is_flag && right_enum.is_flag) { + if (!(node->op == v__token__Kind__pipe || node->op == v__token__Kind__amp)) { + v__checker__Checker_error(c, _SLIT("only `==`, `!=`, `|` and `&` are defined on `[flag]` tagged `enum`, use an explicit cast to `int` if needed"), node->pos); + } + } else if (!c->pref->translated && !c->file->is_translated) { + v__checker__Checker_error(c, _SLIT("only `==` and `!=` are defined on `enum`, use an explicit cast to `int` if needed"), node->pos); + } + } + if (v__ast__Table_type_kind(c->table, left_type) == v__ast__Kind__sum_type && !eq_ne) { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot use operator `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` with `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); + } else if (v__ast__Table_type_kind(c->table, right_type) == v__ast__Kind__sum_type && !eq_ne) { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot use operator `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` with `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); + } + bool left_is_optional = v__ast__Type_has_flag(left_type, v__ast__TypeFlag__optional); + bool right_is_optional = v__ast__Type_has_flag(right_type, v__ast__TypeFlag__optional); + if (left_is_optional && right_is_optional) { + v__checker__Checker_error(c, _SLIT("unwrapped optionals cannot be used in an infix expression"), left_right_pos); + } else if (left_is_optional || right_is_optional) { + v__token__Pos opt_infix_pos = (left_is_optional ? (left_pos) : (right_pos)); + v__checker__Checker_error(c, _SLIT("unwrapped optional cannot be used in an infix expression"), opt_infix_pos); + } + if (!(v__checker__Checker_symmetric_check(c, left_type, right_type) && v__checker__Checker_symmetric_check(c, right_type, left_type)) && !c->pref->translated && !c->file->is_translated && !v__ast__Expr_is_auto_deref_var(node->left) && !v__ast__Expr_is_auto_deref_var(node->right)) { + if (v__ast__Type_alias_eq(left_type, _const_v__ast__void_type) || v__ast__Type_alias_eq(right_type, _const_v__ast__void_type)) { + v__ast__Type _t23 = _const_v__ast__void_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t23; + } + if (v__ast__Type_nr_muls(left_type) > 0 && v__ast__Type_is_int(right_type)) { + v__ast__Type _t24 = return_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t24; + } + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("infix expr: cannot use `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` (right expression) as `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } + v__ast__Type _t25 = (v__token__Kind_is_relational(node->op) ? (_const_v__ast__bool_type) : (return_type)); + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t25; +} + +VV_LOCAL_SYMBOL void v__checker__Checker_check_div_mod_by_zero(v__checker__Checker* c, v__ast__Expr expr, v__token__Kind op_kind) { + if (expr._typ == 266 /* v.ast.FloatLiteral */) { + if (string_f64((*expr._v__ast__FloatLiteral).val) == 0.0) { + string oper = (op_kind == v__token__Kind__div ? (_SLIT("division")) : (_SLIT("modulo"))); + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = oper}}, {_SLIT(" by zero"), 0, { .d_c = 0 }}})), (*expr._v__ast__FloatLiteral).pos); + } + } + else if (expr._typ == 273 /* v.ast.IntegerLiteral */) { + if (string_int((*expr._v__ast__IntegerLiteral).val) == 0) { + string oper = (op_kind == v__token__Kind__div ? (_SLIT("division")) : (_SLIT("modulo"))); + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = oper}}, {_SLIT(" by zero"), 0, { .d_c = 0 }}})), (*expr._v__ast__IntegerLiteral).pos); + } + } + else if (expr._typ == 255 /* v.ast.CastExpr */) { + v__checker__Checker_check_div_mod_by_zero(c, (*expr._v__ast__CastExpr).expr, op_kind); + } + + else { + } + ; +} + void v__checker__Checker_interface_decl(v__checker__Checker* c, v__ast__InterfaceDecl* node) { v__checker__Checker_check_valid_pascal_case(c, node->name, _SLIT("interface name"), node->pos); v__ast__TypeSymbol* decl_sym = v__ast__Table_sym(c->table, node->typ); @@ -74644,6 +74711,9 @@ bool v__gen__c__Gen_write_init_function_defer_0 = false; v__gen__c__Gen_writeln(g, v__gen__c__Gen_as_cast_name_table(g)); v__gen__c__Gen_writeln(g, _SLIT("\tbuiltin_init();")); v__gen__c__Gen_writeln(g, _SLIT("\tvinit_string_literals();")); + if (g->nr_closures > 0) { + v__gen__c__Gen_writeln(g, _SLIT("\t_closure_mtx_init();")); + } for (int _t1 = 0; _t1 < g->table->modules.len; ++_t1) { string mod_name = ((string*)g->table->modules.data)[_t1]; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT("\t{ // Initializations for module "), /*115 &string*/0xfe10, {.d_s = mod_name}}, {_SLIT(" :"), 0, { .d_c = 0 }}}))); @@ -74782,9 +74852,9 @@ VV_LOCAL_SYMBOL void v__gen__c__Gen_write_types(v__gen__c__Gen* g, Array_v__ast_ for (int _t3 = 0; _t3 < (*sym->info._v__ast__Struct).fields.len; ++_t3) { v__ast__StructField field = ((v__ast__StructField*)(*sym->info._v__ast__Struct).fields.data)[_t3]; if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__optional)) { - multi_return_string_string mr_148483 = v__gen__c__Gen_optional_type_name(g, field.typ); - string styp = mr_148483.arg0; - string base = mr_148483.arg1; + multi_return_string_string mr_148548 = v__gen__c__Gen_optional_type_name(g, field.typ); + string styp = mr_148548.arg0; + string base = mr_148548.arg1; sync__RwMutex_lock(&g->done_optionals->mtx); /*lock*/ { if (!Array_string_contains(g->done_optionals->val, base)) { @@ -75079,11 +75149,11 @@ bool v__gen__c__Gen_or_block_defer_0 = false; if (string__eq(g->file->mod.name, _SLIT("main")) && (isnil(g->fn_decl) || g->fn_decl->is_main)) { string err_msg = str_intp(3, _MOV((StrIntpData[]){{_SLIT("IError_name_table["), /*115 &string*/0xfe10, {.d_s = cvar_name}}, {_SLIT(".err._typ]._method_msg("), /*115 &string*/0xfe10, {.d_s = cvar_name}}, {_SLIT(".err._object)"), 0, { .d_c = 0 }}})); if (g->pref->is_debug) { - multi_return_int_string_string_string mr_158266 = v__gen__c__Gen_panic_debug_info(g, or_block.pos); - int paline = mr_158266.arg0; - string pafile = mr_158266.arg1; - string pamod = mr_158266.arg2; - string pafn = mr_158266.arg3; + multi_return_int_string_string_string mr_158331 = v__gen__c__Gen_panic_debug_info(g, or_block.pos); + int paline = mr_158331.arg0; + string pafile = mr_158331.arg1; + string pamod = mr_158331.arg2; + string pafn = mr_158331.arg3; v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_SLIT("panic_debug("), /*100 &int*/0xfe07, {.d_i32 = paline}}, {_SLIT(", tos3(\""), /*115 &string*/0xfe10, {.d_s = pafile}}, {_SLIT("\"), tos3(\""), /*115 &string*/0xfe10, {.d_s = pamod}}, {_SLIT("\"), tos3(\""), /*115 &string*/0xfe10, {.d_s = pafn}}, {_SLIT("\"), "), /*115 &string*/0xfe10, {.d_s = err_msg}}, {_SLIT(" );"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT("\tpanic_optional_not_set( "), /*115 &string*/0xfe10, {.d_s = err_msg}}, {_SLIT(" );"), 0, { .d_c = 0 }}}))); @@ -75106,11 +75176,11 @@ bool v__gen__c__Gen_or_block_defer_0 = false; if (string__eq(g->file->mod.name, _SLIT("main")) && (isnil(g->fn_decl) || g->fn_decl->is_main)) { string err_msg = str_intp(3, _MOV((StrIntpData[]){{_SLIT("IError_name_table["), /*115 &string*/0xfe10, {.d_s = cvar_name}}, {_SLIT(".err._typ]._method_msg("), /*115 &string*/0xfe10, {.d_s = cvar_name}}, {_SLIT(".err._object)"), 0, { .d_c = 0 }}})); if (g->pref->is_debug) { - multi_return_int_string_string_string mr_159533 = v__gen__c__Gen_panic_debug_info(g, or_block.pos); - int paline = mr_159533.arg0; - string pafile = mr_159533.arg1; - string pamod = mr_159533.arg2; - string pafn = mr_159533.arg3; + multi_return_int_string_string_string mr_159598 = v__gen__c__Gen_panic_debug_info(g, or_block.pos); + int paline = mr_159598.arg0; + string pafile = mr_159598.arg1; + string pamod = mr_159598.arg2; + string pafn = mr_159598.arg3; v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_SLIT("panic_debug("), /*100 &int*/0xfe07, {.d_i32 = paline}}, {_SLIT(", tos3(\""), /*115 &string*/0xfe10, {.d_s = pafile}}, {_SLIT("\"), tos3(\""), /*115 &string*/0xfe10, {.d_s = pamod}}, {_SLIT("\"), tos3(\""), /*115 &string*/0xfe10, {.d_s = pafn}}, {_SLIT("\"), "), /*115 &string*/0xfe10, {.d_s = err_msg}}, {_SLIT(");"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT("\tpanic_result_not_set("), /*115 &string*/0xfe10, {.d_s = err_msg}}, {_SLIT(");"), 0, { .d_c = 0 }}}))); @@ -75220,11 +75290,11 @@ VV_LOCAL_SYMBOL string v__gen__c__Gen_type_default(v__gen__c__Gen* g, v__ast__Ty { v__ast__Map info = v__ast__TypeSymbol_map_info(sym); v__ast__TypeSymbol* key_typ = v__ast__Table_sym(g->table, info.key_type); - multi_return_string_string_string_string mr_162143 = v__gen__c__Gen_map_fn_ptrs(g, *key_typ); - string hash_fn = mr_162143.arg0; - string key_eq_fn = mr_162143.arg1; - string clone_fn = mr_162143.arg2; - string free_fn = mr_162143.arg3; + multi_return_string_string_string_string mr_162208 = v__gen__c__Gen_map_fn_ptrs(g, *key_typ); + string hash_fn = mr_162208.arg0; + string key_eq_fn = mr_162208.arg1; + string clone_fn = mr_162208.arg2; + string free_fn = mr_162208.arg3; string noscan_key = v__gen__c__Gen_check_noscan(g, info.key_type); string noscan_value = v__gen__c__Gen_check_noscan(g, info.value_type); string noscan = (noscan_key.len != 0 || noscan_value.len != 0 ? (_SLIT("_noscan")) : (_SLIT(""))); @@ -75755,8 +75825,8 @@ VV_LOCAL_SYMBOL string v__gen__c__Gen_interface_table(v__gen__c__Gen* g) { int params_start_pos = g->out.len; Array_v__ast__Param params = array_clone_to_depth(&method.params, 0); array_set(¶ms, 0, &(v__ast__Param[]) { ((v__ast__Param){(*(v__ast__Param*)/*ee elem_sym */array_get(params, 0)).name,(*(v__ast__Param*)/*ee elem_sym */array_get(params, 0)).pos,(*(v__ast__Param*)/*ee elem_sym */array_get(params, 0)).type_pos,.typ = v__ast__Type_set_nr_muls(st, 1),(*(v__ast__Param*)/*ee elem_sym */array_get(params, 0)).is_mut,(*(v__ast__Param*)/*ee elem_sym */array_get(params, 0)).is_auto_rec,(*(v__ast__Param*)/*ee elem_sym */array_get(params, 0)).is_hidden,}) }); - multi_return_Array_string_Array_string_Array_bool mr_176625 = v__gen__c__Gen_fn_decl_params(g, params, ((voidptr)(0)), false); - Array_string fargs = mr_176625.arg0; + multi_return_Array_string_Array_string_Array_bool mr_176690 = v__gen__c__Gen_fn_decl_params(g, params, ((voidptr)(0)), false); + Array_string fargs = mr_176690.arg0; string parameter_name = strings__Builder_cut_last(&g->out, g->out.len - params_start_pos); if (v__ast__Type_is_ptr(st)) { parameter_name = string_trim_string_left(parameter_name, _SLIT("__shared__")); @@ -75773,8 +75843,8 @@ VV_LOCAL_SYMBOL string v__gen__c__Gen_interface_table(v__gen__c__Gen* g) { *(multi_return_v__ast__Fn_Array_v__ast__Type*) _t26.data = (multi_return_v__ast__Fn_Array_v__ast__Type){.arg0=((v__ast__Fn){.params = __new_array(0, 0, sizeof(v__ast__Param)),.generic_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.name = (string){.str=(byteptr)"", .is_lit=1},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type = 0,.receiver_type = 0,.usages = 0,.ctdefine_idx = 0,.source_fn = 0,.language = 0,.file_mode = 0,.is_variadic = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.no_body = 0,.is_conditional = 0,}),.arg1=__new_array_with_default(0, 0, sizeof(v__ast__Type), 0)}; } - multi_return_v__ast__Fn_Array_v__ast__Type mr_177089 = (*(multi_return_v__ast__Fn_Array_v__ast__Type*)_t26.data); - Array_v__ast__Type embed_types = mr_177089.arg1; + multi_return_v__ast__Fn_Array_v__ast__Type mr_177154 = (*(multi_return_v__ast__Fn_Array_v__ast__Type*)_t26.data); + Array_v__ast__Type embed_types = mr_177154.arg1; if (embed_types.len > 0 && !Array_string_contains(method_names, method.name)) { v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(g->table, (*(v__ast__Type*)array_last(embed_types))); string method_name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = embed_sym->cname}}, {_SLIT("_"), /*115 &string*/0xfe10, {.d_s = method.name}}, {_SLIT0, 0, { .d_c = 0 }}})); @@ -76061,7 +76131,7 @@ VV_LOCAL_SYMBOL string v__gen__c__c_closure_helpers(v__pref__Preferences* pref) if (pref->os != v__pref__OS__windows) { strings__Builder_writeln(&builder, _SLIT("#include ")); } - strings__Builder_write_string(&builder, _SLIT("\n#ifdef _MSC_VER\n\011#define __RETURN_ADDRESS() ((char*)_ReturnAddress())\n#elif defined(__TINYC__) && defined(_WIN32)\n\011#define __RETURN_ADDRESS() ((char*)__builtin_return_address(0))\n#else\n\011#define __RETURN_ADDRESS() ((char*)__builtin_extract_return_addr(__builtin_return_address(0)))\n#endif\n\n#ifdef __V_amd64\nstatic const char __closure_thunk[] = {\n\0110x8f, 0x05, 0xda, 0xff, 0xff, 0xff, // pop QWORD PTR [rip - 0x26] # <_orig_rbp>\n\0110xff, 0x15, 0xe4, 0xff, 0xff, 0xff, // call QWORD PTR [rip - 0x1C] # \n\0110xff, 0x25, 0xce, 0xff, 0xff, 0xff, // jmp QWORD PTR [rip - 0x32] # \n};\n#define __CLOSURE_DATA_OFFSET 20\n#elif defined(__V_x86)\nstatic char __closure_thunk[] = {\n\0110xe8, 0x00, 0x00, 0x00, 0x00, // call 4\n\0110x59, // pop ecx\n\0110x8f, 0x41, 0xeb, // pop DWORD PTR [ecx - 21] # <_orig_rbp>\n\0110xff, 0x51, 0xf3, // call DWORD PTR [ecx - 13] # \n\0110xe8, 0x00, 0x00, 0x00, 0x00, // call 4\n\0110x59, // pop ecx\n\0110xff, 0x61, 0xdf, // jmp DWORD PTR [ecx - 33] # <_orig_rbp>\n};\n\n#define __CLOSURE_DATA_OFFSET 16\n#elif defined(__V_arm64)\nstatic char __closure_thunk[] = {\n\0110x10, 0x00, 0x00, 0x10, // adr x16, start\n\0110x1e, 0x02, 0x1e, 0xf8, // str x30, _orig_x30\n\0110x50, 0xff, 0xff, 0x58, // ldr x16, fn\n\0110x00, 0x02, 0x3f, 0xd6, // blr x16\n\0110x9e, 0xfe, 0xff, 0x58, // ldr x30, _orig_x30\n\0110xc0, 0x03, 0x5f, 0xd6 // ret\n};\n#define __CLOSURE_DATA_OFFSET 24\n#elif defined(__V_arm32)\nstatic char __closure_thunk[] = {\n\0110x18, 0xe0, 0x0f, 0xe5, // str lr, orig_lr\n\0110x14, 0xc0, 0x1f, 0xe5, // ldr ip, fn\n\0110x3c, 0xff, 0x2f, 0xe1, // blx ip\n\0110x24, 0xe0, 0x1f, 0xe5, // ldr lr, orig_lr\n\0110x1e, 0xff, 0x2f, 0xe1 // bx lr\n};\n#define __CLOSURE_DATA_OFFSET 16\n#endif\n\nstatic int _V_PAGE_SIZE = 4096; // pre-initialized to the most common value, in case _vinit is not called (in a DLL, for example)\n\nstatic inline void __closure_set_data(void* closure, void* data) {\n void** p = closure;\n p[-1] = data;\n}\n\nstatic inline void __closure_set_function(void* closure, void* f) {\n void** p = closure;\n p[-2] = f;\n}\n\nstatic void* __closure_create(void* fn, void* data) {\n#ifdef _WIN32\n\011SYSTEM_INFO si;\n\011GetNativeSystemInfo(&si);\n\011uint32_t page_size = si.dwPageSize;\n\011char* p = VirtualAlloc(NULL, page_size * 2, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);\n\011if (p == NULL) return 0;\n#else\n\011uint32_t page_size = sysconf(_SC_PAGESIZE);\n\011int prot = PROT_READ | PROT_WRITE;\n\011int flags = MAP_ANONYMOUS | MAP_PRIVATE;\n\011char* p = mmap(0, page_size * 2, prot, flags, -1, 0);\n\011if (p == MAP_FAILED) return 0;\n#endif\n\n\011void* closure = p + page_size;\n\011memcpy(closure, __closure_thunk, sizeof(__closure_thunk));\n\n#ifdef _WIN32\n\011DWORD _tmp;\n\011VirtualProtect(closure, page_size, PAGE_EXECUTE_READ, &_tmp);\n#else\n\011mprotect(closure, page_size, PROT_READ | PROT_EXEC);\n#endif\n\n\011__closure_set_data(closure, data);\n\011__closure_set_function(closure, fn);\n\011return closure;\n}\n")); + strings__Builder_write_string(&builder, _SLIT("\n#ifdef _MSC_VER\n\011#define __RETURN_ADDRESS() ((char*)_ReturnAddress())\n#elif defined(__TINYC__) && defined(_WIN32)\n\011#define __RETURN_ADDRESS() ((char*)__builtin_return_address(0))\n#else\n\011#define __RETURN_ADDRESS() ((char*)__builtin_extract_return_addr(__builtin_return_address(0)))\n#endif\n\n#define ASSUMED_PAGE_SIZE 0x4000 // 16K\n#define _CLOSURE_SIZE (((3*sizeof(void*) > sizeof(__closure_thunk) ? 3*sizeof(void*) : sizeof(__closure_thunk)) + sizeof(void*) - 1) & ~(sizeof(void*) - 1))\n// equal to `max(3*sizeof(void*), sizeof(__closure_thunk))`, rounded up to the next multiple of `sizeof(void*)`\n\n// refer to https://godbolt.org/z/r7P3EYv6c for a complete assembly\n#ifdef __V_amd64\nstatic const char __closure_thunk[] = {\n\0110x8f, 0x05, 0x0a, 0xc0, 0xff, 0xff, // pop QWORD PTR [rip - return_addr]\n\0110xff, 0x15, 0xfc, 0xbf, 0xff, 0xff, // call QWORD PTR [rip - fn]\n\0110xff, 0x25, 0xfe, 0xbf, 0xff, 0xff // jmp QWORD PTR [rip - return_addr]\n};\n#define __CLOSURE_DATA_OFFSET 0x400C\n#elif defined(__V_x86)\nstatic char __closure_thunk[] = {\n\0110xe8, 0x00, 0x00, 0x00, 0x00, // call 4\n\0110x59, // pop ecx\n\0110x8f, 0x81, 0x03, 0xc0, 0xff, 0xff, // pop DWORD PTR [ecx - 0x3ffd] # \n\0110xff, 0x91, 0xff, 0xbf, 0xff, 0xff, // call DWORD PTR [ecx - 0x4001] # \n\0110xe8, 0x00, 0x00, 0x00, 0x00, // call 4\n\0110x59, // pop ecx\n\0110xff, 0xa1, 0xf1, 0xbf, 0xff, 0xff // jmp DWORD PTR [ecx - 0x400f] # \n};\n#define __CLOSURE_DATA_OFFSET 0x4012\n#elif defined(__V_arm64)\nstatic char __closure_thunk[] = {\n\0110x90, 0x00, 0xfe, 0x10, // adr x16, return_addr\n\0110x1e, 0x02, 0x00, 0xf9, // str x30, [x16]\n\0110x10, 0x00, 0xfe, 0x58, // ldr x16, fn\n\0110x00, 0x02, 0x3f, 0xd6, // blr x16\n\0110x1e, 0x00, 0xfe, 0x58, // ldr x30, return_addr\n\0110xc0, 0x03, 0x5f, 0xd6 // ret\n};\n#define __CLOSURE_DATA_OFFSET 0x4010\n#elif defined(__V_arm32)\n// arm32 needs a small page size because its pc-relative addressing range is just \302\2614095 bytes\n#undef ASSUMED_PAGE_SIZE\n#define ASSUMED_PAGE_SIZE 4080\n#undef _CLOSURE_SIZE\n#define _CLOSURE_SIZE 28\nstatic char __closure_thunk[] = {\n\0110xf0, 0xef, 0x0f, 0xe5, // str lr, return_addr\n\0110xf8, 0xcf, 0x1f, 0xe5, // ldr ip, fn\n\0110x3c, 0xff, 0x2f, 0xe1, // blx ip\n\0110xfc, 0xef, 0x1f, 0xe5, // ldr lr, return_addr\n\0110x1e, 0xff, 0x2f, 0xe1 // bx lr\n};\n#define __CLOSURE_DATA_OFFSET 0xFFC\n#endif\n\nstatic inline void __closure_set_data(char* closure, void* data) {\n void** p = (void**)(closure - ASSUMED_PAGE_SIZE);\n p[0] = data;\n}\n\nstatic inline void __closure_set_function(char* closure, void* f) {\n void** p = (void**)(closure - ASSUMED_PAGE_SIZE);\n p[1] = f;\n}\n\n#ifdef _WIN32\n#include \nstatic SRWLOCK _closure_mtx;\n#define _closure_mtx_init() InitializeSRWLock(&_closure_mtx)\n#define _closure_mtx_lock() AcquireSRWLockExclusive(&_closure_mtx)\n#define _closure_mtx_unlock() ReleaseSRWLockExclusive(&_closure_mtx)\n#else\nstatic pthread_mutex_t _closure_mtx;\n#define _closure_mtx_init() pthread_mutex_init(&_closure_mtx, 0)\n#define _closure_mtx_lock() pthread_mutex_lock(&_closure_mtx)\n#define _closure_mtx_unlock() pthread_mutex_unlock(&_closure_mtx)\n#endif\nstatic char* _closure_ptr = 0;\nstatic int _closure_cap = 0;\n\nstatic void* __closure_create(void* fn, void* data) {\n\011_closure_mtx_lock();\n\011if (_closure_cap == 0) {\n#ifdef _WIN32\n\011\011SYSTEM_INFO si;\n\011\011GetNativeSystemInfo(&si);\n\011\011uint32_t page_size = si.dwPageSize;\n\011\011page_size = page_size * (((ASSUMED_PAGE_SIZE - 1) / page_size) + 1);\n\011\011char* p = VirtualAlloc(NULL, page_size * 2, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);\n\011\011if (p == NULL) return 0;\n#else\n\011\011uint32_t page_size = sysconf(_SC_PAGESIZE);\n\011\011page_size = page_size * (((ASSUMED_PAGE_SIZE - 1) / page_size) + 1);\n\011\011int prot = PROT_READ | PROT_WRITE;\n\011\011int flags = MAP_ANONYMOUS | MAP_PRIVATE;\n\011\011char* p = mmap(0, page_size * 2, prot, flags, -1, 0);\n\011\011if (p == MAP_FAILED) return 0;\n#endif\n\011\011char* x = p + page_size;\n\011\011int remaining = page_size / _CLOSURE_SIZE;\n\011\011_closure_ptr = x;\n\011\011_closure_cap = remaining;\n\011\011while (remaining > 0) {\n\011\011\011memcpy(x, __closure_thunk, sizeof(__closure_thunk));\n\011\011\011remaining--;\n\011\011\011x += _CLOSURE_SIZE;\n\011\011}\n#ifdef _WIN32\n\011\011DWORD _tmp;\n\011\011VirtualProtect(_closure_ptr, page_size, PAGE_EXECUTE_READ, &_tmp);\n#else\n\011\011mprotect(_closure_ptr, page_size, PROT_READ | PROT_EXEC);\n#endif\n\011}\n\011_closure_cap--;\n\011void* closure = _closure_ptr;\n\011_closure_ptr += _CLOSURE_SIZE;\n\011__closure_set_data(closure, data);\n\011__closure_set_function(closure, fn);\n\011_closure_mtx_unlock();\n\011return closure;\n}\n\nstatic void __closure_destroy(void *closure) {\n#ifdef _WIN32\n\011SYSTEM_INFO si;\n\011GetNativeSystemInfo(&si);\n\011uint32_t page_size = si.dwPageSize;\n\011page_size = page_size * (((ASSUMED_PAGE_SIZE - 1) / page_size) + 1);\n\011VirtualFree(closure, page_size * 2, MEM_RELEASE);\n#else\n long page_size = sysconf(_SC_PAGESIZE);\n\011page_size = page_size * (((ASSUMED_PAGE_SIZE - 1) / page_size) + 1);\n munmap((char*)closure - page_size, page_size * 2);\n#endif\n}\n")); string _t1 = strings__Builder_str(&builder); return _t1; } @@ -80876,6 +80946,10 @@ VV_LOCAL_SYMBOL void v__gen__c__Gen_infix_expr_eq_op(v__gen__c__Gen* g, v__ast__ v__gen__c__Gen_expr(g, node.right); v__gen__c__Gen_write(g, _SLIT(")")); } else if (v__ast__Type_idx(left.typ) == v__ast__Type_idx(right.typ) && (left.sym->kind == v__ast__Kind__array || left.sym->kind == v__ast__Kind__array_fixed || left.sym->kind == v__ast__Kind__alias || left.sym->kind == v__ast__Kind__map || left.sym->kind == v__ast__Kind__struct_ || left.sym->kind == v__ast__Kind__sum_type || left.sym->kind == v__ast__Kind__interface_)) { + if (g->pref->translated && !g->is_builtin_mod) { + v__gen__c__Gen_gen_plain_infix_expr(g, node); + return; + } switch (left.sym->kind) { case v__ast__Kind__alias: { @@ -80970,25 +81044,21 @@ VV_LOCAL_SYMBOL void v__gen__c__Gen_infix_expr_eq_op(v__gen__c__Gen* g, v__ast__ } case v__ast__Kind__struct_: { - if (g->pref->translated) { - v__gen__c__Gen_gen_plain_infix_expr(g, node); - } else { - string ptr_typ = v__gen__c__Gen_equality_fn(g, left.unaliased); - if (node.op == v__token__Kind__ne) { - v__gen__c__Gen_write(g, _SLIT("!")); - } - v__gen__c__Gen_write(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = ptr_typ}}, {_SLIT("_struct_eq("), 0, { .d_c = 0 }}}))); - if (v__ast__Type_is_ptr(left.typ)) { - v__gen__c__Gen_write(g, _SLIT("*")); - } - v__gen__c__Gen_expr(g, node.left); - v__gen__c__Gen_write(g, _SLIT(", ")); - if (v__ast__Type_is_ptr(right.typ)) { - v__gen__c__Gen_write(g, _SLIT("*")); - } - v__gen__c__Gen_expr(g, node.right); - v__gen__c__Gen_write(g, _SLIT(")")); + string ptr_typ = v__gen__c__Gen_equality_fn(g, left.unaliased); + if (node.op == v__token__Kind__ne) { + v__gen__c__Gen_write(g, _SLIT("!")); } + v__gen__c__Gen_write(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = ptr_typ}}, {_SLIT("_struct_eq("), 0, { .d_c = 0 }}}))); + if (v__ast__Type_is_ptr(left.typ)) { + v__gen__c__Gen_write(g, _SLIT("*")); + } + v__gen__c__Gen_expr(g, node.left); + v__gen__c__Gen_write(g, _SLIT(", ")); + if (v__ast__Type_is_ptr(right.typ)) { + v__gen__c__Gen_write(g, _SLIT("*")); + } + v__gen__c__Gen_expr(g, node.right); + v__gen__c__Gen_write(g, _SLIT(")")); break; } case v__ast__Kind__sum_type: @@ -81169,7 +81239,7 @@ VV_LOCAL_SYMBOL void v__gen__c__Gen_infix_expr_in_op(v__gen__c__Gen* g, v__ast__ if (right.unaliased_sym->kind == v__ast__Kind__array) { if (left.sym->kind == v__ast__Kind__sum_type || left.sym->kind == v__ast__Kind__interface_) { if ((node.right)._typ == 248 /* v.ast.ArrayInit */) { - if ((*node.right._v__ast__ArrayInit).exprs.len > 0) { + if ((*node.right._v__ast__ArrayInit).exprs.len > 0 && !(v__ast__Table_sym(g->table, (*(v__ast__Type*)/*ee elem_sym */array_get((*node.right._v__ast__ArrayInit).expr_types, 0)))->kind == v__ast__Kind__sum_type || v__ast__Table_sym(g->table, (*(v__ast__Type*)/*ee elem_sym */array_get((*node.right._v__ast__ArrayInit).expr_types, 0)))->kind == v__ast__Kind__interface_)) { Array_v__ast__InfixExpr infix_exprs = __new_array_with_default(0, 0, sizeof(v__ast__InfixExpr), 0); for (int i = 0; i < (*node.right._v__ast__ArrayInit).exprs.len; ++i) { array_push((array*)&infix_exprs, _MOV((v__ast__InfixExpr[]){ ((v__ast__InfixExpr){.or_block = (v__ast__OrExpr){.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},},.left = node.left,.right = (*(v__ast__Expr*)/*ee elem_sym */array_get((*node.right._v__ast__ArrayInit).exprs, i)),.auto_locked = (string){.str=(byteptr)"", .is_lit=1},.ct_left_value = v__ast__empty_comptime_const_expr(),.ct_right_value = v__ast__empty_comptime_const_expr(),.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.left_type = node.left_type,.right_type = (*(v__ast__Type*)/*ee elem_sym */array_get((*node.right._v__ast__ArrayInit).expr_types, i)),.op = v__token__Kind__key_is,.is_stmt = 0,.ct_left_value_evaled = 0,.ct_right_value_evaled = 0,}) })); @@ -81182,9 +81252,18 @@ VV_LOCAL_SYMBOL void v__gen__c__Gen_infix_expr_in_op(v__gen__c__Gen* g, v__ast__ } } if ((node.right)._typ == 248 /* v.ast.ArrayInit */) { + v__ast__Type elem_type = (*node.right._v__ast__ArrayInit).elem_type; + v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(g->table, elem_type); if ((*node.right._v__ast__ArrayInit).exprs.len > 0) { v__gen__c__Gen_write(g, _SLIT("(")); - v__gen__c__Gen_infix_expr_in_optimization(g, node.left, (*node.right._v__ast__ArrayInit)); + if (elem_sym->kind == v__ast__Kind__sum_type && left.sym->kind != v__ast__Kind__sum_type) { + if (Array_v__ast__Type_contains(v__ast__TypeSymbol_sumtype_info(elem_sym).variants, node.left_type)) { + v__ast__CastExpr new_node_left = ((v__ast__CastExpr){.arg = v__ast__EmptyExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__EmptyExpr, (((v__ast__EmptyExpr){.x = 0,})))),.expr = node.left,.typname = (string){.str=(byteptr)"", .is_lit=1},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.typ = elem_type,.expr_type = node.left_type,.has_arg = 0,}); + v__gen__c__Gen_infix_expr_in_optimization(g, v__ast__CastExpr_to_sumtype_v__ast__Expr(&new_node_left), (*node.right._v__ast__ArrayInit)); + } + } else { + v__gen__c__Gen_infix_expr_in_optimization(g, node.left, (*node.right._v__ast__ArrayInit)); + } v__gen__c__Gen_write(g, _SLIT(")")); return; } @@ -89056,7 +89135,7 @@ VV_LOCAL_SYMBOL v__ast__Stmt v__parser__Parser_for_stmt(v__parser__Parser* p) { } v__ast__Scope_register(p->scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.name = key_var_name,.expr = {0},.pos = key_var_pos,.typ = _const_v__ast__int_type,.orig_type = 0,.share = 0,.is_mut = 0,.is_autofree_tmp = 0,.is_arg = 0,.is_auto_deref = 0,.is_inherited = 0,.is_used = 0,.is_changed = 0,.is_or = 0,.is_tmp = true,.is_auto_heap = 0,.is_stack_obj = true,}))))); } else if (v__ast__Scope_known_var(p->scope, val_var_name)) { - v__ast__Stmt _t9 = v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error(p, str_intp(2, _MOV((StrIntpData[]){{_SLIT("redefinition of value iteration variable `"), /*115 &string*/0xfe10, {.d_s = val_var_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})))))); + v__ast__Stmt _t9 = v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, str_intp(3, _MOV((StrIntpData[]){{_SLIT("redefinition of value iteration variable `"), /*115 &string*/0xfe10, {.d_s = val_var_name}}, {_SLIT("`, use `for ("), /*115 &string*/0xfe10, {.d_s = val_var_name}}, {_SLIT(" in array) {` if you want to check for a condition instead"), 0, { .d_c = 0 }}})), val_var_pos)))); return _t9; } v__parser__Parser_check(p, v__token__Kind__key_in); diff --git a/v_win.c b/v_win.c index f852dd4..7375dcf 100644 --- a/v_win.c +++ b/v_win.c @@ -1,11 +1,11 @@ -#define V_COMMIT_HASH "9a0f49950" +#define V_COMMIT_HASH "f9079b670" #ifndef V_COMMIT_HASH - #define V_COMMIT_HASH "12ec3b9d5" + #define V_COMMIT_HASH "9a0f49950" #endif #ifndef V_CURRENT_COMMIT_HASH - #define V_CURRENT_COMMIT_HASH "9a0f499" + #define V_CURRENT_COMMIT_HASH "f9079b6" #endif // V comptime_definitions: @@ -7170,6 +7170,7 @@ VV_LOCAL_SYMBOL void __print_assert_failure(VAssertMetaInfo* i); VV_LOCAL_SYMBOL void v_segmentation_fault_handler(int signal); void gc_check_leaks(void); VV_LOCAL_SYMBOL void print_libbacktrace(int frames_to_skip); +VV_LOCAL_SYMBOL void eprint_libbacktrace(int frames_to_skip); #define _const_symopt_undname 2 #define _const_symopt_deferred_loads 4 #define _const_symopt_no_cpp 8 @@ -8053,6 +8054,7 @@ Array_string os__get_lines(void); string os__get_lines_joined(void); string os__get_raw_lines_joined(void); string os__user_os(void); +_option_Array_string os__user_names(void); string os__home_dir(void); string os__expand_tilde_to_home(string path); _option_void os__write_file(string path, string text); @@ -9434,8 +9436,6 @@ void v__checker__Checker_alias_type_decl(v__checker__Checker* c, v__ast__AliasTy void v__checker__Checker_fn_type_decl(v__checker__Checker* c, v__ast__FnTypeDecl node); void v__checker__Checker_sum_type_decl(v__checker__Checker* c, v__ast__SumTypeDecl node); Array_v__ast__InterfaceEmbedding v__checker__Checker_expand_iface_embeds(v__checker__Checker* c, v__ast__InterfaceDecl* idecl, int level, Array_v__ast__InterfaceEmbedding iface_embeds); -VV_LOCAL_SYMBOL void v__checker__Checker_check_div_mod_by_zero(v__checker__Checker* c, v__ast__Expr expr, v__token__Kind op_kind); -v__ast__Type v__checker__Checker_infix_expr(v__checker__Checker* c, v__ast__InfixExpr* node); VV_LOCAL_SYMBOL multi_return_string_v__token__Pos v__checker__Checker_fail_if_immutable(v__checker__Checker* c, v__ast__Expr expr_); VV_LOCAL_SYMBOL bool v__checker__Checker_type_implements(v__checker__Checker* c, v__ast__Type typ, v__ast__Type interface_type, v__token__Pos pos); v__ast__Type v__checker__Checker_check_expr_opt_call(v__checker__Checker* c, v__ast__Expr expr, v__ast__Type ret_type); @@ -9525,6 +9525,8 @@ VV_LOCAL_SYMBOL void v__checker__Checker_for_in_stmt(v__checker__Checker* c, v__ VV_LOCAL_SYMBOL void v__checker__Checker_for_stmt(v__checker__Checker* c, v__ast__ForStmt* node); v__ast__Type v__checker__Checker_if_expr(v__checker__Checker* c, v__ast__IfExpr* node); VV_LOCAL_SYMBOL void v__checker__Checker_smartcast_if_conds(v__checker__Checker* c, v__ast__Expr node, v__ast__Scope* scope); +v__ast__Type v__checker__Checker_infix_expr(v__checker__Checker* c, v__ast__InfixExpr* node); +VV_LOCAL_SYMBOL void v__checker__Checker_check_div_mod_by_zero(v__checker__Checker* c, v__ast__Expr expr, v__token__Kind op_kind); void v__checker__Checker_interface_decl(v__checker__Checker* c, v__ast__InterfaceDecl* node); VV_LOCAL_SYMBOL v__ast__Type v__checker__Checker_resolve_generic_interface(v__checker__Checker* c, v__ast__Type typ, v__ast__Type interface_type, v__token__Pos pos); v__ast__Type v__checker__Checker_match_expr(v__checker__Checker* c, v__ast__MatchExpr* node); @@ -17992,7 +17994,14 @@ VV_LOCAL_SYMBOL void __print_assert_failure(VAssertMetaInfo* i) { // Attr: [markused] VV_LOCAL_SYMBOL void v_segmentation_fault_handler(int signal) { eprintln(_SLIT("signal 11: segmentation fault")); - print_backtrace(); + #if defined(CUSTOM_DEFINE_use_libbacktrace) + { + } + #else + { + print_backtrace(); + } + #endif _v_exit(139); VUNREACHABLE(); } @@ -18003,6 +18012,10 @@ void gc_check_leaks(void) { VV_LOCAL_SYMBOL void print_libbacktrace(int frames_to_skip) { } +// Attr: [noinline] +__NOINLINE VV_LOCAL_SYMBOL void eprint_libbacktrace(int frames_to_skip) { +} + VV_LOCAL_SYMBOL void restore_codepage(void) { SetConsoleOutputCP(g_original_codepage); } @@ -28324,6 +28337,26 @@ string os__user_os(void) { return _t2; } +_option_Array_string os__user_names(void) { + #if defined(_WIN32) + { + os__Result result = os__execute(_SLIT("wmic useraccount get name")); + if (result.exit_code != 0) { + return (_option_Array_string){ .state=2, .err=_v_error( str_intp(3, _MOV((StrIntpData[]){{_SLIT("Failed to get user names. Exited with code "), /*100 &int*/0xfe07, {.d_i32 = result.exit_code}}, {_SLIT(": "), /*115 &string*/0xfe10, {.d_s = result.output}}, {_SLIT0, 0, { .d_c = 0 }}}))), .data={EMPTY_STRUCT_INITIALIZATION} }; + } + Array_string users = string_split_into_lines(result.output); + array_delete(&users, users.len - 1); + _option_Array_string _t2; + opt_ok2(&(Array_string[]) { users }, (_option*)(&_t2), sizeof(Array_string)); + return _t2; + } + #else + { + } + #endif + return (_option_Array_string){0}; +} + string os__home_dir(void) { #if defined(_WIN32) { @@ -36525,7 +36558,7 @@ void v__pref__Preferences_fill_with_defaults(v__pref__Preferences* p) { if ((p->third_party_option).len == 0) { p->third_party_option = p->cflags; } - string vhash = _SLIT("12ec3b9d5"); + string vhash = _SLIT("9a0f49950"); p->cache_manager = v__vcache__new_cache_manager(new_array_from_c_array(7, 7, sizeof(string), _MOV((string[7]){string_clone(vhash), str_intp(6, _MOV((StrIntpData[]){{_SLIT0, /*115 &v.pref.Backend*/0xfe10, {.d_s = v__pref__Backend_str(p->backend)}}, {_SLIT(" | "), /*115 &v.pref.OS*/0xfe10, {.d_s = v__pref__OS_str(p->os)}}, {_SLIT(" | "), /*115 &string*/0xfe10, {.d_s = p->ccompiler}}, {_SLIT(" | "), /*115 &bool*/0xfe10, {.d_s = p->is_prod ? _SLIT("true") : _SLIT("false")}}, {_SLIT(" | "), /*115 &bool*/0xfe10, {.d_s = p->sanitize ? _SLIT("true") : _SLIT("false")}}, {_SLIT0, 0, { .d_c = 0 }}})), string_clone(string_trim_space(p->cflags)), string_clone(string_trim_space(p->third_party_option)), string_clone(Array_string_str(p->compile_defines_all)), string_clone(Array_string_str(p->compile_defines)), string_clone(Array_string_str(p->lookup_path))}))); if (string__eq(os__user_os(), _SLIT("windows"))) { p->use_cache = false; @@ -36962,7 +36995,7 @@ multi_return_ref_v__pref__Preferences_string v__pref__parse_args_and_show_errors #endif res->run_only = string_split_any(os__getenv(_SLIT("VTEST_ONLY_FN")), _SLIT(",")); string command = _SLIT(""); - int command_pos = 0; + int command_pos = -1; for (int i = 0; i < args.len; i++) { string arg = (*(string*)/*ee elem_sym */array_get(args, i)); Array_string _t1; @@ -37019,6 +37052,9 @@ multi_return_ref_v__pref__Preferences_string v__pref__parse_args_and_show_errors res->is_help = true; } else if (string__eq(arg, _SLIT("-v"))) { + if (command_pos != -1) { + continue; + } if (args.len > 1) { res->is_verbose = true; } else { @@ -48778,118 +48814,122 @@ bool v__checker__Checker_check_types(v__checker__Checker* c, v__ast__Type got, v bool _t9 = true; return _t9; } - } - if (got_sym->kind == v__ast__Kind__enum_) { - if (v__ast__TypeSymbol_is_number(expected_sym)) { + if (v__checker__Checker_check_types(c, (/* as */ *(v__ast__ArrayFixed*)__as_cast((got_sym->info)._v__ast__ArrayFixed,(got_sym->info)._typ, 480) /*expected idx: 480, name: v.ast.ArrayFixed */ ).elem_type, (/* as */ *(v__ast__ArrayFixed*)__as_cast((expected_sym->info)._v__ast__ArrayFixed,(expected_sym->info)._typ, 480) /*expected idx: 480, name: v.ast.ArrayFixed */ ).elem_type)) { bool _t10 = true; return _t10; } - } else if (got_sym->kind == v__ast__Kind__array_fixed) { - if (v__ast__TypeSymbol_is_number(expected_sym) || v__ast__Type_is_any_kind_of_pointer(expected)) { + } + if (got_sym->kind == v__ast__Kind__enum_) { + if (v__ast__TypeSymbol_is_number(expected_sym)) { bool _t11 = true; return _t11; } - } else if (expected_sym->kind == v__ast__Kind__array_fixed) { - if (v__ast__TypeSymbol_is_number(got_sym) && v__ast__Type_is_any_kind_of_pointer(got)) { + } else if (got_sym->kind == v__ast__Kind__array_fixed) { + if (v__ast__TypeSymbol_is_number(expected_sym) || v__ast__Type_is_any_kind_of_pointer(expected)) { bool _t12 = true; return _t12; + } + } else if (expected_sym->kind == v__ast__Kind__array_fixed) { + if (v__ast__TypeSymbol_is_number(got_sym) && v__ast__Type_is_any_kind_of_pointer(got)) { + bool _t13 = true; + return _t13; } else if (got_sym->kind == v__ast__Kind__array) { v__ast__ArrayFixed info = /* as */ *(v__ast__ArrayFixed*)__as_cast((expected_sym->info)._v__ast__ArrayFixed,(expected_sym->info)._typ, 480) /*expected idx: 480, name: v.ast.ArrayFixed */ ; v__ast__Array info2 = /* as */ *(v__ast__Array*)__as_cast((got_sym->info)._v__ast__Array,(got_sym->info)._typ, 452) /*expected idx: 452, name: v.ast.Array */ ; if (v__checker__Checker_check_types(c, info.elem_type, info2.elem_type)) { - bool _t13 = true; - return _t13; + bool _t14 = true; + return _t14; } } } else if (got_sym->kind == v__ast__Kind__array) { if (v__ast__TypeSymbol_is_number(expected_sym) || v__ast__Type_is_any_kind_of_pointer(expected)) { - bool _t14 = true; - return _t14; - } - } else if (expected_sym->kind == v__ast__Kind__array) { - if (v__ast__TypeSymbol_is_number(got_sym) && v__ast__Type_is_any_kind_of_pointer(got)) { bool _t15 = true; return _t15; } + } else if (expected_sym->kind == v__ast__Kind__array) { + if (v__ast__TypeSymbol_is_number(got_sym) && v__ast__Type_is_any_kind_of_pointer(got)) { + bool _t16 = true; + return _t16; + } } if (expected_sym->kind == v__ast__Kind__enum_ && v__ast__TypeSymbol_is_number(got_sym)) { - bool _t16 = true; - return _t16; + bool _t17 = true; + return _t17; } if (got_is_ptr && exp_is_ptr) { if (v__ast__TypeSymbol_is_number(expected_sym) && v__ast__TypeSymbol_is_number(got_sym)) { - bool _t17 = true; - return _t17; + bool _t18 = true; + return _t18; } } } if (got_is_ptr && exp_is_ptr) { if (v__ast__Type_nr_muls(got) != v__ast__Type_nr_muls(expected)) { - bool _t18 = false; - return _t18; + bool _t19 = false; + return _t19; } } int exp_idx = v__ast__Type_idx(expected); int got_idx = v__ast__Type_idx(got); if (exp_idx == got_idx) { - bool _t19 = true; - return _t19; + bool _t20 = true; + return _t20; } if (exp_idx == _const_v__ast__voidptr_type_idx || exp_idx == _const_v__ast__byteptr_type_idx || (v__ast__Type_is_ptr(expected) && v__ast__Type_idx(v__ast__Type_deref(expected)) == _const_v__ast__byte_type_idx)) { if (v__ast__Type_is_ptr(got) || v__ast__Type_is_pointer(got)) { - bool _t20 = true; - return _t20; - } - } - if (v__ast__Type_is_real_pointer(expected)) { - if (v__ast__Type_alias_eq(got, _const_v__ast__int_literal_type)) { bool _t21 = true; return _t21; } } - if (got_idx == _const_v__ast__voidptr_type_idx || got_idx == _const_v__ast__byteptr_type_idx || (got_idx == _const_v__ast__byte_type_idx && v__ast__Type_is_ptr(got))) { - if (v__ast__Type_is_ptr(expected) || v__ast__Type_is_pointer(expected)) { + if (v__ast__Type_is_real_pointer(expected)) { + if (v__ast__Type_alias_eq(got, _const_v__ast__int_literal_type)) { bool _t22 = true; return _t22; } } + if (got_idx == _const_v__ast__voidptr_type_idx || got_idx == _const_v__ast__byteptr_type_idx || (got_idx == _const_v__ast__byte_type_idx && v__ast__Type_is_ptr(got))) { + if (v__ast__Type_is_ptr(expected) || v__ast__Type_is_pointer(expected)) { + bool _t23 = true; + return _t23; + } + } if (v__ast__Type_alias_eq(expected, _const_v__ast__charptr_type) && v__ast__Type_alias_eq(got, v__ast__Type_ref(_const_v__ast__char_type))) { - bool _t23 = true; - return _t23; + bool _t24 = true; + return _t24; } if (v__ast__Type_has_flag(expected, v__ast__TypeFlag__optional) || v__ast__Type_has_flag(expected, v__ast__TypeFlag__result)) { v__ast__TypeSymbol* sym = v__ast__Table_sym(c->table, got); if (((sym->idx == _const_v__ast__error_type_idx || (v__ast__Type_alias_eq(got, _const_v__ast__none_type) || v__ast__Type_alias_eq(got, _const_v__ast__error_type))) && v__ast__Type_has_flag(expected, v__ast__TypeFlag__optional)) || ((sym->idx == _const_v__ast__error_type_idx || v__ast__Type_alias_eq(got, _const_v__ast__error_type)) && v__ast__Type_has_flag(expected, v__ast__TypeFlag__result))) { - bool _t24 = true; - return _t24; - } else if (!v__checker__Checker_check_basic(c, got, v__ast__Type_clear_flag(v__ast__Type_clear_flag(expected, v__ast__TypeFlag__optional), v__ast__TypeFlag__result))) { - bool _t25 = false; + bool _t25 = true; return _t25; + } else if (!v__checker__Checker_check_basic(c, got, v__ast__Type_clear_flag(v__ast__Type_clear_flag(expected, v__ast__TypeFlag__optional), v__ast__TypeFlag__result))) { + bool _t26 = false; + return _t26; } } if (!v__checker__Checker_check_basic(c, got, expected)) { - bool _t26 = false; - return _t26; + bool _t27 = false; + return _t27; } if (v__ast__Type_is_number(got) && v__ast__Type_is_number(expected)) { if (v__ast__Type_alias_eq(got, _const_v__ast__rune_type) && v__ast__Type_alias_eq(expected, _const_v__ast__byte_type)) { - bool _t27 = true; - return _t27; - } else if (v__ast__Type_alias_eq(expected, _const_v__ast__rune_type) && v__ast__Type_alias_eq(got, _const_v__ast__byte_type)) { bool _t28 = true; return _t28; + } else if (v__ast__Type_alias_eq(expected, _const_v__ast__rune_type) && v__ast__Type_alias_eq(got, _const_v__ast__byte_type)) { + bool _t29 = true; + return _t29; } if (!v__ast__Type_alias_eq(v__checker__Checker_promote_num(c, expected, got), expected)) { - bool _t29 = false; - return _t29; + bool _t30 = false; + return _t30; } } if (v__ast__Type_has_flag(expected, v__ast__TypeFlag__generic)) { - bool _t30 = false; - return _t30; + bool _t31 = false; + return _t31; } - bool _t31 = true; - return _t31; + bool _t32 = true; + return _t32; } _option_void v__checker__Checker_check_expected_call_arg(v__checker__Checker* c, v__ast__Type got, v__ast__Type expected_, v__ast__Language language, v__ast__CallArg arg) { @@ -49237,10 +49277,10 @@ VV_LOCAL_SYMBOL v__ast__Type v__checker__Checker_promote_num(v__checker__Checker v__ast__Type type_hi = left_type; v__ast__Type type_lo = right_type; if (v__ast__Type_idx(type_hi) < v__ast__Type_idx(type_lo)) { - v__ast__Type _var_18612 = type_hi; - v__ast__Type _var_18621 = type_lo; - type_hi = _var_18621; - type_lo = _var_18612; + v__ast__Type _var_18748 = type_hi; + v__ast__Type _var_18757 = type_lo; + type_hi = _var_18757; + type_lo = _var_18748; } int idx_hi = v__ast__Type_idx(type_hi); int idx_lo = v__ast__Type_idx(type_lo); @@ -50103,776 +50143,6 @@ Array_v__ast__InterfaceEmbedding v__checker__Checker_expand_iface_embeds(v__chec return _t11; } -VV_LOCAL_SYMBOL void v__checker__Checker_check_div_mod_by_zero(v__checker__Checker* c, v__ast__Expr expr, v__token__Kind op_kind) { - if (expr._typ == 305 /* v.ast.FloatLiteral */) { - if (string_f64((*expr._v__ast__FloatLiteral).val) == 0.0) { - string oper = (op_kind == v__token__Kind__div ? (_SLIT("division")) : (_SLIT("modulo"))); - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = oper}}, {_SLIT(" by zero"), 0, { .d_c = 0 }}})), (*expr._v__ast__FloatLiteral).pos); - } - } - else if (expr._typ == 312 /* v.ast.IntegerLiteral */) { - if (string_int((*expr._v__ast__IntegerLiteral).val) == 0) { - string oper = (op_kind == v__token__Kind__div ? (_SLIT("division")) : (_SLIT("modulo"))); - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = oper}}, {_SLIT(" by zero"), 0, { .d_c = 0 }}})), (*expr._v__ast__IntegerLiteral).pos); - } - } - else if (expr._typ == 294 /* v.ast.CastExpr */) { - v__checker__Checker_check_div_mod_by_zero(c, (*expr._v__ast__CastExpr).expr, op_kind); - } - - else { - } - ; -} - -v__ast__Type v__checker__Checker_infix_expr(v__checker__Checker* c, v__ast__InfixExpr* node) { -bool v__checker__Checker_infix_expr_defer_0 = false; -v__ast__Type former_expected_type; - former_expected_type = c->expected_type; - v__checker__Checker_infix_expr_defer_0 = true; - v__ast__Type left_type = v__checker__Checker_expr(c, node->left); - node->left_type = left_type; - c->expected_type = left_type; - v__ast__Type right_type = v__checker__Checker_expr(c, node->right); - node->right_type = right_type; - if (v__ast__Type_is_number(left_type) && !v__ast__Type_is_ptr(left_type) && (v__ast__Type_alias_eq(right_type, _const_v__ast__int_literal_type) || v__ast__Type_alias_eq(right_type, _const_v__ast__float_literal_type))) { - node->right_type = left_type; - } - if (v__ast__Type_is_number(right_type) && !v__ast__Type_is_ptr(right_type) && (v__ast__Type_alias_eq(left_type, _const_v__ast__int_literal_type) || v__ast__Type_alias_eq(left_type, _const_v__ast__float_literal_type))) { - node->left_type = right_type; - } - v__ast__TypeSymbol* right_sym = v__ast__Table_sym(c->table, right_type); - v__ast__TypeSymbol* right_final = v__ast__Table_final_sym(c->table, right_type); - v__ast__TypeSymbol* left_sym = v__ast__Table_sym(c->table, left_type); - v__ast__TypeSymbol* left_final = v__ast__Table_final_sym(c->table, left_type); - v__token__Pos left_pos = v__ast__Expr_pos(node->left); - v__token__Pos right_pos = v__ast__Expr_pos(node->right); - v__token__Pos left_right_pos = v__token__Pos_extend(left_pos, right_pos); - if (v__ast__Type_is_any_kind_of_pointer(left_type) && (node->op == v__token__Kind__plus || node->op == v__token__Kind__minus || node->op == v__token__Kind__mul || node->op == v__token__Kind__div || node->op == v__token__Kind__mod || node->op == v__token__Kind__xor || node->op == v__token__Kind__amp || node->op == v__token__Kind__pipe)) { - if (!c->pref->translated && ((v__ast__Type_is_any_kind_of_pointer(right_type) && node->op != v__token__Kind__minus) || (!v__ast__Type_is_any_kind_of_pointer(right_type) && !(node->op == v__token__Kind__plus || node->op == v__token__Kind__minus)))) { - string left_name = v__ast__Table_type_to_str(c->table, left_type); - string right_name = v__ast__Table_type_to_str(c->table, right_type); - v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("invalid operator `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` to `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } else if (node->op == v__token__Kind__plus || node->op == v__token__Kind__minus) { - if (!c->inside_unsafe && !v__ast__Expr_is_auto_deref_var(node->left) && !v__ast__Expr_is_auto_deref_var(node->right)) { - v__checker__Checker_warn(c, _SLIT("pointer arithmetic is only allowed in `unsafe` blocks"), left_right_pos); - } - if (v__ast__Type_alias_eq(left_type, _const_v__ast__voidptr_type) && !c->pref->translated) { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` cannot be used with `voidptr`"), 0, { .d_c = 0 }}})), left_pos); - } - } - } - v__ast__Type return_type = left_type; - if (node->op != v__token__Kind__key_is) { - if (node->left._typ == 307 /* v.ast.Ident */) { - if ((*node->left._v__ast__Ident).is_mut) { - v__checker__Checker_error(c, _SLIT("the `mut` keyword is invalid here"), (*node->left._v__ast__Ident).mut_pos); - } - } - else if (node->left._typ == 327 /* v.ast.SelectorExpr */) { - if ((*node->left._v__ast__SelectorExpr).is_mut) { - v__checker__Checker_error(c, _SLIT("the `mut` keyword is invalid here"), (*node->left._v__ast__SelectorExpr).mut_pos); - } - } - - else { - } - ; - } - if (node->right._typ == 307 /* v.ast.Ident */) { - if ((*node->right._v__ast__Ident).is_mut) { - v__checker__Checker_error(c, _SLIT("the `mut` keyword is invalid here"), (*node->right._v__ast__Ident).mut_pos); - } - } - else if (node->right._typ == 327 /* v.ast.SelectorExpr */) { - if ((*node->right._v__ast__SelectorExpr).is_mut) { - v__checker__Checker_error(c, _SLIT("the `mut` keyword is invalid here"), (*node->right._v__ast__SelectorExpr).mut_pos); - } - } - - else { - } - ; - bool eq_ne = (node->op == v__token__Kind__eq || node->op == v__token__Kind__ne); - switch (node->op) { - case v__token__Kind__eq: - case v__token__Kind__ne: - { - bool is_mismatch = (left_sym->kind == v__ast__Kind__alias && (right_sym->kind == v__ast__Kind__struct_ || right_sym->kind == v__ast__Kind__array || right_sym->kind == v__ast__Kind__sum_type)) || (right_sym->kind == v__ast__Kind__alias && (left_sym->kind == v__ast__Kind__struct_ || left_sym->kind == v__ast__Kind__array || left_sym->kind == v__ast__Kind__sum_type)); - if (is_mismatch) { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("possible type mismatch of compared values of `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` operation"), 0, { .d_c = 0 }}})), left_right_pos); - } else if (Array_int_contains(_const_v__ast__integer_type_idxs, left_type) && Array_int_contains(_const_v__ast__integer_type_idxs, right_type)) { - bool is_left_type_signed = Array_int_contains(_const_v__ast__signed_integer_type_idxs, left_type); - bool is_right_type_signed = Array_int_contains(_const_v__ast__signed_integer_type_idxs, right_type); - if (!is_left_type_signed && (node->right)._typ == 312 /* v.ast.IntegerLiteral */) { - if (string_int((*node->right._v__ast__IntegerLiteral).val) < 0 && Array_int_contains(_const_v__ast__int_promoted_type_idxs, left_type)) { - string lt = v__ast__Table_sym(c->table, left_type)->name; - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = lt}}, {_SLIT("` cannot be compared with negative value"), 0, { .d_c = 0 }}})), (*node->right._v__ast__IntegerLiteral).pos); - } - } else if (!is_right_type_signed && (node->left)._typ == 312 /* v.ast.IntegerLiteral */) { - if (string_int((*node->left._v__ast__IntegerLiteral).val) < 0 && Array_int_contains(_const_v__ast__int_promoted_type_idxs, right_type)) { - string rt = v__ast__Table_sym(c->table, right_type)->name; - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("negative value cannot be compared with `"), /*115 &string*/0xfe10, {.d_s = rt}}, {_SLIT("`"), 0, { .d_c = 0 }}})), (*node->left._v__ast__IntegerLiteral).pos); - } - } else if (is_left_type_signed != is_right_type_signed && left_type != _const_v__ast__int_literal_type_idx && right_type != _const_v__ast__int_literal_type_idx) { - multi_return_int_int mr_24200 = v__ast__Table_type_size(c->table, left_type); - int ls = mr_24200.arg0; - multi_return_int_int mr_24243 = v__ast__Table_type_size(c->table, right_type); - int rs = mr_24243.arg0; - if (!c->pref->translated && ((is_left_type_signed && ls < rs) || (is_right_type_signed && rs < ls))) { - string lt = v__ast__Table_sym(c->table, left_type)->name; - string rt = v__ast__Table_sym(c->table, right_type)->name; - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = lt}}, {_SLIT("` cannot be compared with `"), /*115 &string*/0xfe10, {.d_s = rt}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); - } - } - } - break; - } - case v__token__Kind__key_in: - case v__token__Kind__not_in: - { - - if (right_final->kind == (v__ast__Kind__array)) { - if (!(left_sym->kind == v__ast__Kind__sum_type || left_sym->kind == v__ast__Kind__interface_)) { - v__ast__Type elem_type = v__ast__TypeSymbol_array_info(right_final).elem_type; - _option_void _t1 = v__checker__Checker_check_expected(c, left_type, elem_type); - if (_t1.state != 0 && _t1.err._typ != _IError_None___index) { - IError err = _t1.err; - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("left operand to `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` does not match the array element type: "), /*115 &string*/0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), left_right_pos); - ; - } - - ; - } - } - else if (right_final->kind == (v__ast__Kind__map)) { - v__ast__Map map_info = v__ast__TypeSymbol_map_info(right_final); - _option_void _t2 = v__checker__Checker_check_expected(c, left_type, map_info.key_type); - if (_t2.state != 0 && _t2.err._typ != _IError_None___index) { - IError err = _t2.err; - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("left operand to `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` does not match the map key type: "), /*115 &string*/0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), left_right_pos); - ; - } - - ; - node->left_type = map_info.key_type; - } - else if (right_final->kind == (v__ast__Kind__array_fixed)) { - if (!(left_sym->kind == v__ast__Kind__sum_type || left_sym->kind == v__ast__Kind__interface_)) { - v__ast__Type elem_type = v__ast__TypeSymbol_array_fixed_info(right_final).elem_type; - _option_void _t3 = v__checker__Checker_check_expected(c, left_type, elem_type); - if (_t3.state != 0 && _t3.err._typ != _IError_None___index) { - IError err = _t3.err; - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("left operand to `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` does not match the fixed array element type: "), /*115 &string*/0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), left_right_pos); - ; - } - - ; - } - } - else { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` can only be used with arrays and maps"), 0, { .d_c = 0 }}})), node->pos); - }; - v__ast__Type _t4 = _const_v__ast__bool_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t4; - break; - } - case v__token__Kind__plus: - case v__token__Kind__minus: - case v__token__Kind__mul: - case v__token__Kind__div: - case v__token__Kind__mod: - case v__token__Kind__xor: - case v__token__Kind__amp: - case v__token__Kind__pipe: - { - if ((right_sym->info)._typ == 472 /* v.ast.Alias */ && (/* as */ *(v__ast__Alias*)__as_cast((right_sym->info)._v__ast__Alias,(right_sym->info)._typ, 472) /*expected idx: 472, name: v.ast.Alias */ ).language != v__ast__Language__c && string__eq(c->mod, (*(string*)/*ee elem_sym */array_get(string_split(v__ast__Table_type_to_str(c->table, right_type), _SLIT(".")), 0))) && v__ast__TypeSymbol_is_primitive(v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((right_sym->info)._v__ast__Alias,(right_sym->info)._typ, 472) /*expected idx: 472, name: v.ast.Alias */ ).parent_type))) { - right_sym = v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((right_sym->info)._v__ast__Alias,(right_sym->info)._typ, 472) /*expected idx: 472, name: v.ast.Alias */ ).parent_type); - } - if ((left_sym->info)._typ == 472 /* v.ast.Alias */ && (/* as */ *(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 472) /*expected idx: 472, name: v.ast.Alias */ ).language != v__ast__Language__c && string__eq(c->mod, (*(string*)/*ee elem_sym */array_get(string_split(v__ast__Table_type_to_str(c->table, left_type), _SLIT(".")), 0))) && v__ast__TypeSymbol_is_primitive(v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 472) /*expected idx: 472, name: v.ast.Alias */ ).parent_type))) { - left_sym = v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 472) /*expected idx: 472, name: v.ast.Alias */ ).parent_type); - } - if (c->pref->translated && (node->op == v__token__Kind__plus || node->op == v__token__Kind__minus || node->op == v__token__Kind__mul) && v__ast__Type_is_any_kind_of_pointer(left_type) && v__ast__Type_is_any_kind_of_pointer(right_type)) { - return_type = left_type; - } else if (!c->pref->translated && left_sym->kind == v__ast__Kind__alias && (left_sym->info)._typ == 472 /* v.ast.Alias */ && !(v__ast__TypeSymbol_is_primitive(v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 472) /*expected idx: 472, name: v.ast.Alias */ ).parent_type)))) { - if (v__ast__TypeSymbol_has_method(left_sym, v__token__Kind_str(node->op))) { - _option_v__ast__Fn _t5; - if (_t5 = v__ast__TypeSymbol_find_method(left_sym, v__token__Kind_str(node->op)), _t5.state == 0) { - v__ast__Fn method = *(v__ast__Fn*)_t5.data; - return_type = method.return_type; - } else { - IError err = _t5.err; - return_type = left_type; - } - } else { - string left_name = v__ast__Table_type_to_str(c->table, left_type); - string right_name = v__ast__Table_type_to_str(c->table, right_type); - if (string__eq(left_name, right_name)) { - v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } else { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } - } - } else if (!c->pref->translated && right_sym->kind == v__ast__Kind__alias && (right_sym->info)._typ == 472 /* v.ast.Alias */ && !(v__ast__TypeSymbol_is_primitive(v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((right_sym->info)._v__ast__Alias,(right_sym->info)._typ, 472) /*expected idx: 472, name: v.ast.Alias */ ).parent_type)))) { - if (v__ast__TypeSymbol_has_method(right_sym, v__token__Kind_str(node->op))) { - _option_v__ast__Fn _t6; - if (_t6 = v__ast__TypeSymbol_find_method(right_sym, v__token__Kind_str(node->op)), _t6.state == 0) { - v__ast__Fn method = *(v__ast__Fn*)_t6.data; - return_type = method.return_type; - } else { - IError err = _t6.err; - return_type = right_type; - } - } else { - string left_name = v__ast__Table_type_to_str(c->table, left_type); - string right_name = v__ast__Table_type_to_str(c->table, right_type); - if (string__eq(left_name, right_name)) { - v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } else { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } - } - } - if (!c->pref->translated && (left_sym->kind == v__ast__Kind__array || left_sym->kind == v__ast__Kind__array_fixed || left_sym->kind == v__ast__Kind__map || left_sym->kind == v__ast__Kind__struct_)) { - if (v__ast__TypeSymbol_has_method_with_generic_parent(left_sym, v__token__Kind_str(node->op))) { - _option_v__ast__Fn _t7; - if (_t7 = v__ast__TypeSymbol_find_method_with_generic_parent(left_sym, v__token__Kind_str(node->op)), _t7.state == 0) { - v__ast__Fn method = *(v__ast__Fn*)_t7.data; - return_type = method.return_type; - } else { - IError err = _t7.err; - return_type = left_type; - } - } else { - string left_name = v__ast__Table_type_to_str(c->table, left_type); - string right_name = v__ast__Table_type_to_str(c->table, right_type); - if (string__eq(left_name, right_name)) { - v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } else { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } - } - } else if (!c->pref->translated && (right_sym->kind == v__ast__Kind__array || right_sym->kind == v__ast__Kind__array_fixed || right_sym->kind == v__ast__Kind__map || right_sym->kind == v__ast__Kind__struct_)) { - if (v__ast__TypeSymbol_has_method_with_generic_parent(right_sym, v__token__Kind_str(node->op))) { - _option_v__ast__Fn _t8; - if (_t8 = v__ast__TypeSymbol_find_method_with_generic_parent(right_sym, v__token__Kind_str(node->op)), _t8.state == 0) { - v__ast__Fn method = *(v__ast__Fn*)_t8.data; - return_type = method.return_type; - } else { - IError err = _t8.err; - return_type = right_type; - } - } else { - string left_name = v__ast__Table_type_to_str(c->table, left_type); - string right_name = v__ast__Table_type_to_str(c->table, right_type); - if (string__eq(left_name, right_name)) { - v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } else { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } - } - } else if (v__ast__Expr_is_auto_deref_var(node->left) || v__ast__Expr_is_auto_deref_var(node->right)) { - v__ast__Type deref_left_type = (v__ast__Expr_is_auto_deref_var(node->left) ? (v__ast__Type_deref(left_type)) : (left_type)); - v__ast__Type deref_right_type = (v__ast__Expr_is_auto_deref_var(node->right) ? (v__ast__Type_deref(right_type)) : (right_type)); - string left_name = v__ast__Table_type_to_str(c->table, v__ast__mktyp(deref_left_type)); - string right_name = v__ast__Table_type_to_str(c->table, v__ast__mktyp(deref_right_type)); - if (!string__eq(left_name, right_name)) { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } - } else { - v__ast__Type unaliased_left_type = v__ast__Table_unalias_num_type(c->table, left_type); - v__ast__Type unalias_right_type = v__ast__Table_unalias_num_type(c->table, right_type); - v__ast__Type promoted_type = v__checker__Checker_promote(c, unaliased_left_type, unalias_right_type); - bool is_allowed_pointer_arithmetic = v__ast__Type_is_any_kind_of_pointer(left_type) && v__ast__Type_is_any_kind_of_pointer(right_type) && node->op == v__token__Kind__minus; - if (is_allowed_pointer_arithmetic) { - promoted_type = _const_v__ast__int_type; - } - if (v__ast__Type_idx(promoted_type) == _const_v__ast__void_type_idx) { - string left_name = v__ast__Table_type_to_str(c->table, left_type); - string right_name = v__ast__Table_type_to_str(c->table, right_type); - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } else if (v__ast__Type_has_flag(promoted_type, v__ast__TypeFlag__optional)) { - string s = v__ast__Table_type_to_str(c->table, promoted_type); - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` cannot be used with `"), /*115 &string*/0xfe10, {.d_s = s}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); - } else if (v__ast__Type_is_float(promoted_type)) { - if (node->op == v__token__Kind__mod || node->op == v__token__Kind__xor || node->op == v__token__Kind__amp || node->op == v__token__Kind__pipe) { - string side = (v__ast__Type_alias_eq(left_type, promoted_type) ? (_SLIT("left")) : (_SLIT("right"))); - v__token__Pos pos = (v__ast__Type_alias_eq(left_type, promoted_type) ? (left_pos) : (right_pos)); - string name = (v__ast__Type_alias_eq(left_type, promoted_type) ? (left_sym->name) : (right_sym->name)); - if (node->op == v__token__Kind__mod) { - v__checker__Checker_error(c, _SLIT("float modulo not allowed, use math.fmod() instead"), pos); - } else { - v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = side}}, {_SLIT(" type of `"), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` cannot be non-integer type `"), /*115 &string*/0xfe10, {.d_s = name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), pos); - } - } - } - if (node->op == v__token__Kind__div || node->op == v__token__Kind__mod) { - v__checker__Checker_check_div_mod_by_zero(c, node->right, node->op); - } - return_type = promoted_type; - } - break; - } - case v__token__Kind__gt: - case v__token__Kind__lt: - case v__token__Kind__ge: - case v__token__Kind__le: - { - if ((left_sym->kind == v__ast__Kind__array || left_sym->kind == v__ast__Kind__array_fixed) && (right_sym->kind == v__ast__Kind__array || right_sym->kind == v__ast__Kind__array_fixed)) { - v__checker__Checker_error(c, _SLIT("only `==` and `!=` are defined on arrays"), node->pos); - } else if (left_sym->kind == v__ast__Kind__struct_ && (/* as */ *(v__ast__Struct*)__as_cast((left_sym->info)._v__ast__Struct,(left_sym->info)._typ, 457) /*expected idx: 457, name: v.ast.Struct */ ).generic_types.len > 0) { - v__ast__Type _t9 = _const_v__ast__bool_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t9; - } else if (left_sym->kind == v__ast__Kind__struct_ && right_sym->kind == v__ast__Kind__struct_ && (node->op == v__token__Kind__eq || node->op == v__token__Kind__lt)) { - if (!(v__ast__TypeSymbol_has_method(left_sym, v__token__Kind_str(node->op)) && v__ast__TypeSymbol_has_method(right_sym, v__token__Kind_str(node->op)))) { - string left_name = v__ast__Table_type_to_str(c->table, left_type); - string right_name = v__ast__Table_type_to_str(c->table, right_type); - if (string__eq(left_name, right_name)) { - if (!(node->op == v__token__Kind__lt && c->pref->translated)) { - v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } - } else { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } - } - } - if (left_sym->kind == v__ast__Kind__struct_ && right_sym->kind == v__ast__Kind__struct_) { - if (!v__ast__TypeSymbol_has_method(left_sym, _SLIT("<")) && (node->op == v__token__Kind__ge || node->op == v__token__Kind__le)) { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("cannot use `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` as `<` operator method is not defined"), 0, { .d_c = 0 }}})), left_right_pos); - } else if (!v__ast__TypeSymbol_has_method(left_sym, _SLIT("<")) && node->op == v__token__Kind__gt) { - v__checker__Checker_error(c, _SLIT("cannot use `>` as `<=` operator method is not defined"), left_right_pos); - } - } else if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__generic) && v__ast__Type_has_flag(right_type, v__ast__TypeFlag__generic)) { - v__ast__Type left_gen_type = v__checker__Checker_unwrap_generic(c, left_type); - v__ast__TypeSymbol* gen_sym = v__ast__Table_sym(c->table, left_gen_type); - bool need_overload = (gen_sym->kind == v__ast__Kind__struct_ || gen_sym->kind == v__ast__Kind__interface_); - if (need_overload && !v__ast__TypeSymbol_has_method_with_generic_parent(gen_sym, _SLIT("<")) && (node->op == v__token__Kind__ge || node->op == v__token__Kind__le)) { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("cannot use `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` as `<` operator method is not defined"), 0, { .d_c = 0 }}})), left_right_pos); - } else if (need_overload && !v__ast__TypeSymbol_has_method_with_generic_parent(gen_sym, _SLIT("<")) && node->op == v__token__Kind__gt) { - v__checker__Checker_error(c, _SLIT("cannot use `>` as `<=` operator method is not defined"), left_right_pos); - } - } else if (Array_int_contains(_const_v__ast__integer_type_idxs, left_type) && Array_int_contains(_const_v__ast__integer_type_idxs, right_type)) { - bool is_left_type_signed = Array_int_contains(_const_v__ast__signed_integer_type_idxs, left_type) || left_type == _const_v__ast__int_literal_type_idx; - bool is_right_type_signed = Array_int_contains(_const_v__ast__signed_integer_type_idxs, right_type) || right_type == _const_v__ast__int_literal_type_idx; - if (is_left_type_signed != is_right_type_signed) { - if (is_right_type_signed) { - if ((node->right)._typ == 312 /* v.ast.IntegerLiteral */) { - if (string_int((*node->right._v__ast__IntegerLiteral).val) < 0) { - v__checker__Checker_error(c, _SLIT("unsigned integer cannot be compared with negative value"), (*node->right._v__ast__IntegerLiteral).pos); - } - } - } else if (is_left_type_signed) { - if ((node->left)._typ == 312 /* v.ast.IntegerLiteral */) { - if (string_int((*node->left._v__ast__IntegerLiteral).val) < 0) { - v__checker__Checker_error(c, _SLIT("unsigned integer cannot be compared with negative value"), (*node->left._v__ast__IntegerLiteral).pos); - } - } - } - } - } else if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__optional) || v__ast__Type_has_flag(right_type, v__ast__TypeFlag__optional)) { - v__token__Pos opt_comp_pos = (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__optional) ? (left_pos) : (right_pos)); - v__checker__Checker_error(c, _SLIT("unwrapped optional cannot be compared in an infix expression"), opt_comp_pos); - } - break; - } - case v__token__Kind__left_shift: - { - if (left_final->kind == v__ast__Kind__array) { - if (!node->is_stmt) { - v__checker__Checker_error(c, _SLIT("array append cannot be used in an expression"), node->pos); - } - v__checker__Checker_check_expr_opt_call(c, node->right, right_type); - multi_return_string_v__token__Pos mr_35045 = v__checker__Checker_fail_if_immutable(c, node->left); - node->auto_locked = mr_35045.arg0; - v__ast__Type left_value_type = v__ast__Table_value_type(c->table, v__checker__Checker_unwrap_generic(c, left_type)); - v__ast__TypeSymbol* left_value_sym = v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, left_value_type)); - if (left_value_sym->kind == v__ast__Kind__interface_) { - if (right_final->kind != v__ast__Kind__array) { - if (v__checker__Checker_type_implements(c, right_type, left_value_type, right_pos)) { - if (!v__ast__Type_is_ptr(right_type) && !v__ast__Type_is_pointer(right_type) && !c->inside_unsafe && right_sym->kind != v__ast__Kind__interface_) { - v__checker__Checker_mark_as_referenced(c, &node->right, true); - } - } - } else { - v__checker__Checker_type_implements(c, v__ast__Table_value_type(c->table, right_type), left_value_type, right_pos); - } - v__ast__Type _t10 = _const_v__ast__void_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t10; - } else if (left_value_sym->kind == v__ast__Kind__sum_type) { - if (right_final->kind != v__ast__Kind__array) { - if (!v__ast__Table_is_sumtype_or_in_variant(c->table, left_value_type, v__ast__mktyp(right_type))) { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot append `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` to `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); - } - } else { - v__ast__Type right_value_type = v__ast__Table_value_type(c->table, right_type); - if (!v__ast__Table_is_sumtype_or_in_variant(c->table, left_value_type, v__ast__mktyp(right_value_type))) { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot append `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` to `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); - } - } - v__ast__Type _t11 = _const_v__ast__void_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t11; - } - v__ast__Type unwrapped_right_type = v__checker__Checker_unwrap_generic(c, right_type); - if (v__checker__Checker_check_types(c, unwrapped_right_type, left_value_type)) { - if (!(!v__ast__Type_is_ptr(unwrapped_right_type) && v__ast__Type_is_ptr(left_value_type) && v__ast__Type_share(left_value_type) == v__ast__ShareType__mut_t)) { - v__ast__Type _t12 = _const_v__ast__void_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t12; - } - } else if (v__checker__Checker_check_types(c, unwrapped_right_type, v__checker__Checker_unwrap_generic(c, left_type))) { - v__ast__Type _t13 = _const_v__ast__void_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t13; - } - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot append `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` to `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); - v__ast__Type _t14 = _const_v__ast__void_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t14; - } else { - v__ast__Type _t15 = v__checker__Checker_check_shift(c, node, left_type, right_type); - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t15; - } - break; - } - case v__token__Kind__right_shift: - { - v__ast__Type _t16 = v__checker__Checker_check_shift(c, node, left_type, right_type); - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t16; - break; - } - case v__token__Kind__unsigned_right_shift: - { - int _t17; /* if prepend */ - if (!v__ast__Type_is_int(left_type)) { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("invalid operation: shift on type `"), /*115 &string*/0xfe10, {.d_s = v__ast__Table_sym(c->table, left_type)->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_pos); - _t17 = _const_v__ast__void_type_idx; - } else if (v__ast__Type_is_int_literal(left_type)) { - _t17 = _const_v__ast__u32_type_idx; - } else if (v__ast__Type_is_unsigned(left_type)) { - _t17 = left_type; - } else { - _t17 = v__ast__Type_idx(left_type) + _const_v__ast__u32_type_idx - _const_v__ast__int_type_idx; - } - int modified_left_type = _t17; - if (modified_left_type == 0) { - v__ast__Type _t18 = _const_v__ast__void_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t18; - } - *node = ((v__ast__InfixExpr){ - .or_block = node->or_block, - .left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = {0},.expr = node->left,.typname = v__ast__Table_type_str(c->table, modified_left_type),.pos = node->pos,.typ = modified_left_type,.expr_type = 0,.has_arg = 0,})))), - .right = node->right, - .auto_locked = node->auto_locked, - .ct_left_value = v__ast__empty_comptime_const_expr(), - .ct_right_value = v__ast__empty_comptime_const_expr(), - .pos = node->pos, - .left_type = left_type, - .right_type = right_type, - .op = v__token__Kind__right_shift, - .is_stmt = false, - .ct_left_value_evaled = 0, - .ct_right_value_evaled = 0, - }); - v__ast__Type _t19 = v__checker__Checker_check_shift(c, node, left_type, right_type); - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t19; - break; - } - case v__token__Kind__key_is: - case v__token__Kind__not_is: - { - v__ast__Expr right_expr = node->right; - v__ast__Type _t20 = 0; - if (right_expr._typ == 333 /* v.ast.TypeNode */) { - _t20 = (*right_expr._v__ast__TypeNode).typ; - } - else if (right_expr._typ == 319 /* v.ast.None */) { - _t20 = _const_v__ast__none_type_idx; - } - - else { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("invalid type `"), /*115 &v.ast.Expr*/0xfe10, {.d_s = v__ast__Expr_str(right_expr)}}, {_SLIT("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(right_expr)); - _t20 = ((v__ast__Type)(0)); - } - v__ast__Type typ = _t20; - if (!v__ast__Type_alias_eq(typ, ((v__ast__Type)(0)))) { - v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(c->table, typ); - string op = v__token__Kind_str(node->op); - if (typ_sym->kind == v__ast__Kind__placeholder) { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = op}}, {_SLIT(": type `"), /*115 &string*/0xfe10, {.d_s = typ_sym->name}}, {_SLIT("` does not exist"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(right_expr)); - } - if (left_sym->kind == v__ast__Kind__aggregate) { - v__ast__Type parent_left_type = (/* as */ *(v__ast__Aggregate*)__as_cast((left_sym->info)._v__ast__Aggregate,(left_sym->info)._typ, 470) /*expected idx: 470, name: v.ast.Aggregate */ ).sum_type; - left_sym = v__ast__Table_sym(c->table, parent_left_type); - } - if (!(left_sym->kind == v__ast__Kind__interface_ || left_sym->kind == v__ast__Kind__sum_type)) { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = op}}, {_SLIT("` can only be used with interfaces and sum types"), 0, { .d_c = 0 }}})), node->pos); - } else if ((left_sym->info)._typ == 476 /* v.ast.SumType */) { - if (!Array_v__ast__Type_contains((*left_sym->info._v__ast__SumType).variants, typ)) { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("` has no variant `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); - } - } - } - v__ast__Type _t21 = _const_v__ast__bool_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t21; - break; - } - case v__token__Kind__arrow: - { - if (left_sym->kind == v__ast__Kind__chan) { - v__ast__Chan chan_info = v__ast__TypeSymbol_chan_info(left_sym); - v__ast__Type elem_type = chan_info.elem_type; - if (!v__checker__Checker_check_types(c, right_type, elem_type)) { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot push `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` on `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); - } - if (chan_info.is_mut) { - v__checker__Checker_fail_if_immutable(c, node->right); - } - if (v__ast__Type_is_ptr(elem_type) && !v__ast__Type_is_ptr(right_type)) { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot push non-reference `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` on `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); - } - v__checker__Checker_stmts_ending_with_expression(c, node->or_block.stmts); - } else { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("cannot push on non-channel `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_pos); - } - v__ast__Type _t22 = _const_v__ast__void_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t22; - break; - } - case v__token__Kind__and: - case v__token__Kind__logical_or: - { - if (!c->pref->translated && !c->file->is_translated) { - if (node->left_type != _const_v__ast__bool_type_idx) { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("left operand for `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` is not a boolean"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->left)); - } - if (node->right_type != _const_v__ast__bool_type_idx) { - v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("right operand for `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` is not a boolean"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->right)); - } - } - if ((node->left)._typ == 311 /* v.ast.InfixExpr */) { - if ((*node->left._v__ast__InfixExpr).op != node->op && ((*node->left._v__ast__InfixExpr).op == v__token__Kind__logical_or || (*node->left._v__ast__InfixExpr).op == v__token__Kind__and)) { - v__checker__Checker_error(c, _SLIT("ambiguous boolean expression. use `()` to ensure correct order of operations"), node->pos); - } - } - break; - } - case v__token__Kind__unknown: - case v__token__Kind__eof: - case v__token__Kind__name: - case v__token__Kind__number: - case v__token__Kind__string: - case v__token__Kind__str_inter: - case v__token__Kind__chartoken: - case v__token__Kind__inc: - case v__token__Kind__dec: - case v__token__Kind__not: - case v__token__Kind__bit_not: - case v__token__Kind__question: - case v__token__Kind__comma: - case v__token__Kind__semicolon: - case v__token__Kind__colon: - case v__token__Kind__hash: - case v__token__Kind__dollar: - case v__token__Kind__at: - case v__token__Kind__str_dollar: - case v__token__Kind__assign: - case v__token__Kind__decl_assign: - case v__token__Kind__plus_assign: - case v__token__Kind__minus_assign: - case v__token__Kind__div_assign: - case v__token__Kind__mult_assign: - case v__token__Kind__xor_assign: - case v__token__Kind__mod_assign: - case v__token__Kind__or_assign: - case v__token__Kind__and_assign: - case v__token__Kind__right_shift_assign: - case v__token__Kind__left_shift_assign: - case v__token__Kind__unsigned_right_shift_assign: - case v__token__Kind__lcbr: - case v__token__Kind__rcbr: - case v__token__Kind__lpar: - case v__token__Kind__rpar: - case v__token__Kind__lsbr: - case v__token__Kind__nilsbr: - case v__token__Kind__rsbr: - case v__token__Kind__comment: - case v__token__Kind__nl: - case v__token__Kind__dot: - case v__token__Kind__dotdot: - case v__token__Kind__ellipsis: - case v__token__Kind__keyword_beg: - case v__token__Kind__key_as: - case v__token__Kind__key_asm: - case v__token__Kind__key_assert: - case v__token__Kind__key_atomic: - case v__token__Kind__key_break: - case v__token__Kind__key_const: - case v__token__Kind__key_continue: - case v__token__Kind__key_defer: - case v__token__Kind__key_else: - case v__token__Kind__key_enum: - case v__token__Kind__key_false: - case v__token__Kind__key_for: - case v__token__Kind__key_fn: - case v__token__Kind__key_global: - case v__token__Kind__key_go: - case v__token__Kind__key_goto: - case v__token__Kind__key_if: - case v__token__Kind__key_import: - case v__token__Kind__key_interface: - case v__token__Kind__key_match: - case v__token__Kind__key_module: - case v__token__Kind__key_mut: - case v__token__Kind__key_shared: - case v__token__Kind__key_lock: - case v__token__Kind__key_rlock: - case v__token__Kind__key_none: - case v__token__Kind__key_return: - case v__token__Kind__key_select: - case v__token__Kind__key_sizeof: - case v__token__Kind__key_isreftype: - case v__token__Kind__key_likely: - case v__token__Kind__key_unlikely: - case v__token__Kind__key_offsetof: - case v__token__Kind__key_struct: - case v__token__Kind__key_true: - case v__token__Kind__key_type: - case v__token__Kind__key_typeof: - case v__token__Kind__key_dump: - case v__token__Kind__key_orelse: - case v__token__Kind__key_union: - case v__token__Kind__key_pub: - case v__token__Kind__key_static: - case v__token__Kind__key_volatile: - case v__token__Kind__key_unsafe: - case v__token__Kind__keyword_end: - case v__token__Kind___end_: - default: - { - break; - } - } - ; - if (v__ast__Type_alias_eq(left_type, _const_v__ast__bool_type) && !(node->op == v__token__Kind__eq || node->op == v__token__Kind__ne || node->op == v__token__Kind__logical_or || node->op == v__token__Kind__and)) { - v__checker__Checker_error(c, _SLIT("bool types only have the following operators defined: `==`, `!=`, `||`, and `&&`"), node->pos); - } else if (v__ast__Type_alias_eq(left_type, _const_v__ast__string_type) && !(node->op == v__token__Kind__plus || node->op == v__token__Kind__eq || node->op == v__token__Kind__ne || node->op == v__token__Kind__lt || node->op == v__token__Kind__gt || node->op == v__token__Kind__le || node->op == v__token__Kind__ge)) { - v__checker__Checker_error(c, _SLIT("string types only have the following operators defined: `==`, `!=`, `<`, `>`, `<=`, `>=`, and `+`"), node->pos); - } else if (left_sym->kind == v__ast__Kind__enum_ && right_sym->kind == v__ast__Kind__enum_ && !eq_ne) { - v__ast__Enum left_enum = /* as */ *(v__ast__Enum*)__as_cast((left_sym->info)._v__ast__Enum,(left_sym->info)._typ, 486) /*expected idx: 486, name: v.ast.Enum */ ; - v__ast__Enum right_enum = /* as */ *(v__ast__Enum*)__as_cast((right_sym->info)._v__ast__Enum,(right_sym->info)._typ, 486) /*expected idx: 486, name: v.ast.Enum */ ; - if (left_enum.is_flag && right_enum.is_flag) { - if (!(node->op == v__token__Kind__pipe || node->op == v__token__Kind__amp)) { - v__checker__Checker_error(c, _SLIT("only `==`, `!=`, `|` and `&` are defined on `[flag]` tagged `enum`, use an explicit cast to `int` if needed"), node->pos); - } - } else if (!c->pref->translated && !c->file->is_translated) { - v__checker__Checker_error(c, _SLIT("only `==` and `!=` are defined on `enum`, use an explicit cast to `int` if needed"), node->pos); - } - } - if (v__ast__Table_type_kind(c->table, left_type) == v__ast__Kind__sum_type && !eq_ne) { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot use operator `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` with `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); - } else if (v__ast__Table_type_kind(c->table, right_type) == v__ast__Kind__sum_type && !eq_ne) { - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot use operator `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` with `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); - } - bool left_is_optional = v__ast__Type_has_flag(left_type, v__ast__TypeFlag__optional); - bool right_is_optional = v__ast__Type_has_flag(right_type, v__ast__TypeFlag__optional); - if (left_is_optional && right_is_optional) { - v__checker__Checker_error(c, _SLIT("unwrapped optionals cannot be used in an infix expression"), left_right_pos); - } else if (left_is_optional || right_is_optional) { - v__token__Pos opt_infix_pos = (left_is_optional ? (left_pos) : (right_pos)); - v__checker__Checker_error(c, _SLIT("unwrapped optional cannot be used in an infix expression"), opt_infix_pos); - } - if (!(v__checker__Checker_symmetric_check(c, left_type, right_type) && v__checker__Checker_symmetric_check(c, right_type, left_type)) && !c->pref->translated && !c->file->is_translated && !v__ast__Expr_is_auto_deref_var(node->left) && !v__ast__Expr_is_auto_deref_var(node->right)) { - if (v__ast__Type_alias_eq(left_type, _const_v__ast__void_type) || v__ast__Type_alias_eq(right_type, _const_v__ast__void_type)) { - v__ast__Type _t23 = _const_v__ast__void_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t23; - } - if (v__ast__Type_nr_muls(left_type) > 0 && v__ast__Type_is_int(right_type)) { - v__ast__Type _t24 = return_type; - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t24; - } - v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("infix expr: cannot use `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` (right expression) as `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); - } - v__ast__Type _t25 = (v__token__Kind_is_relational(node->op) ? (_const_v__ast__bool_type) : (return_type)); - // Defer begin - if (v__checker__Checker_infix_expr_defer_0) { - c->expected_type = former_expected_type; - } - // Defer end - return _t25; -} - VV_LOCAL_SYMBOL multi_return_string_v__token__Pos v__checker__Checker_fail_if_immutable(v__checker__Checker* c, v__ast__Expr expr_) { string to_lock = _SLIT(""); v__token__Pos pos = ((v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,}); @@ -50932,19 +50202,19 @@ VV_LOCAL_SYMBOL multi_return_string_v__token__Pos v__checker__Checker_fail_if_im if (v__ast__Type_has_flag(elem_type, v__ast__TypeFlag__shared_f)) { v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("you have to create a handle and `lock` it to modify `shared` "), /*115 &string*/0xfe10, {.d_s = kind}}, {_SLIT(" element"), 0, { .d_c = 0 }}})), v__token__Pos_extend(v__ast__Expr_pos((*expr._v__ast__IndexExpr).left), (*expr._v__ast__IndexExpr).pos)); } - multi_return_string_v__token__Pos mr_45723 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__IndexExpr).left); - to_lock = mr_45723.arg0; - pos = mr_45723.arg1; + multi_return_string_v__token__Pos mr_21955 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__IndexExpr).left); + to_lock = mr_21955.arg0; + pos = mr_21955.arg1; } else if (expr._typ == 322 /* v.ast.ParExpr */) { - multi_return_string_v__token__Pos mr_45792 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__ParExpr).expr); - to_lock = mr_45792.arg0; - pos = mr_45792.arg1; + multi_return_string_v__token__Pos mr_22024 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__ParExpr).expr); + to_lock = mr_22024.arg0; + pos = mr_22024.arg1; } else if (expr._typ == 324 /* v.ast.PrefixExpr */) { - multi_return_string_v__token__Pos mr_45864 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__PrefixExpr).right); - to_lock = mr_45864.arg0; - pos = mr_45864.arg1; + multi_return_string_v__token__Pos mr_22096 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__PrefixExpr).right); + to_lock = mr_22096.arg0; + pos = mr_22096.arg1; } else if (expr._typ == 327 /* v.ast.SelectorExpr */) { if ((*expr._v__ast__SelectorExpr).expr_type == 0) { @@ -50994,9 +50264,9 @@ VV_LOCAL_SYMBOL multi_return_string_v__token__Pos v__checker__Checker_fail_if_im string type_str = v__ast__Table_type_to_str(c->table, (*expr._v__ast__SelectorExpr).expr_type); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("field `"), /*115 &string*/0xfe10, {.d_s = (*expr._v__ast__SelectorExpr).field_name}}, {_SLIT("` of struct `"), /*115 &string*/0xfe10, {.d_s = type_str}}, {_SLIT("` is immutable"), 0, { .d_c = 0 }}})), (*expr._v__ast__SelectorExpr).pos); } - multi_return_string_v__token__Pos mr_47328 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__SelectorExpr).expr); - to_lock = mr_47328.arg0; - pos = mr_47328.arg1; + multi_return_string_v__token__Pos mr_23560 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__SelectorExpr).expr); + to_lock = mr_23560.arg0; + pos = mr_23560.arg1; } if ((to_lock).len != 0) { explicit_lock_needed = true; @@ -51102,9 +50372,9 @@ VV_LOCAL_SYMBOL multi_return_string_v__token__Pos v__checker__Checker_fail_if_im } else if (expr._typ == 293 /* v.ast.CallExpr */) { if (string__eq((*expr._v__ast__CallExpr).name, _SLIT("slice"))) { - multi_return_string_v__token__Pos mr_49151 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__CallExpr).left); - to_lock = mr_49151.arg0; - pos = mr_49151.arg1; + multi_return_string_v__token__Pos mr_25383 = v__checker__Checker_fail_if_immutable(c, (*expr._v__ast__CallExpr).left); + to_lock = mr_25383.arg0; + pos = mr_25383.arg1; if ((to_lock).len != 0) { explicit_lock_needed = true; } @@ -51517,9 +50787,9 @@ v__ast__Type v__checker__Checker_selector_expr(v__checker__Checker* c, v__ast__S *(multi_return_v__ast__StructField_Array_v__ast__Type*) _t13.data = (multi_return_v__ast__StructField_Array_v__ast__Type){.arg0=((v__ast__StructField){.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.default_val = (string){.str=(byteptr)"", .is_lit=1},.default_expr = {0},.name = (string){.str=(byteptr)"", .is_lit=1},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.i = 0,.default_expr_typ = 0,.typ = 0,.has_default_expr = 0,.is_pub = 0,.is_mut = 0,.is_global = 0,.is_volatile = 0,}),.arg1=__new_array_with_default(0, 0, sizeof(v__ast__Type), 0)}; } - multi_return_v__ast__StructField_Array_v__ast__Type mr_63245 = (*(multi_return_v__ast__StructField_Array_v__ast__Type*)_t13.data); - field = mr_63245.arg0; - embed_types = mr_63245.arg1; + multi_return_v__ast__StructField_Array_v__ast__Type mr_39477 = (*(multi_return_v__ast__StructField_Array_v__ast__Type*)_t13.data); + field = mr_39477.arg0; + embed_types = mr_39477.arg1; node->from_embed_types = embed_types; if (sym->kind == v__ast__Kind__aggregate || sym->kind == v__ast__Kind__sum_type) { unknown_field_msg = IError_name_table[err._typ]._method_msg(err._object); @@ -51553,9 +50823,9 @@ v__ast__Type v__checker__Checker_selector_expr(v__checker__Checker* c, v__ast__S *(multi_return_v__ast__StructField_Array_v__ast__Type*) _t15.data = (multi_return_v__ast__StructField_Array_v__ast__Type){.arg0=((v__ast__StructField){.comments = __new_array(0, 0, sizeof(v__ast__Comment)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.default_val = (string){.str=(byteptr)"", .is_lit=1},.default_expr = {0},.name = (string){.str=(byteptr)"", .is_lit=1},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.i = 0,.default_expr_typ = 0,.typ = 0,.has_default_expr = 0,.is_pub = 0,.is_mut = 0,.is_global = 0,.is_volatile = 0,}),.arg1=__new_array_with_default(0, 0, sizeof(v__ast__Type), 0)}; } - multi_return_v__ast__StructField_Array_v__ast__Type mr_64076 = (*(multi_return_v__ast__StructField_Array_v__ast__Type*)_t15.data); - field = mr_64076.arg0; - embed_types = mr_64076.arg1; + multi_return_v__ast__StructField_Array_v__ast__Type mr_40308 = (*(multi_return_v__ast__StructField_Array_v__ast__Type*)_t15.data); + field = mr_40308.arg0; + embed_types = mr_40308.arg1; node->from_embed_types = embed_types; } } @@ -52208,6 +51478,9 @@ VV_LOCAL_SYMBOL void v__checker__Checker_hash_stmt(v__checker__Checker* c, v__as } else if (string__eq(node->kind, _SLIT("flag"))) { string flag = node->main; + if (string__eq(flag, _SLIT("flag"))) { + v__checker__Checker_error(c, _SLIT("no argument(s) provided for #flag"), node->pos); + } if (string_contains(flag, _SLIT("@VROOT"))) { _option_string _t8 = v__util__resolve_vmodroot(string_replace(flag, _SLIT("@VROOT"), _SLIT("@VMODROOT")), c->file->path); if (_t8.state != 0) { /*or block*/ @@ -53816,8 +53089,8 @@ v__ast__Type v__checker__Checker_postfix_expr(v__checker__Checker* c, v__ast__Po string typ_str = v__ast__Table_type_to_str(c->table, typ); v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("invalid operation: "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" (non-numeric type `"), /*115 &string*/0xfe10, {.d_s = typ_str}}, {_SLIT("`)"), 0, { .d_c = 0 }}})), node->pos); } else { - multi_return_string_v__token__Pos mr_119540 = v__checker__Checker_fail_if_immutable(c, node->expr); - node->auto_locked = mr_119540.arg0; + multi_return_string_v__token__Pos mr_95884 = v__checker__Checker_fail_if_immutable(c, node->expr); + node->auto_locked = mr_95884.arg0; } v__ast__Type _t1 = typ; return _t1; @@ -59094,6 +58367,776 @@ VV_LOCAL_SYMBOL void v__checker__Checker_smartcast_if_conds(v__checker__Checker* } } +v__ast__Type v__checker__Checker_infix_expr(v__checker__Checker* c, v__ast__InfixExpr* node) { +bool v__checker__Checker_infix_expr_defer_0 = false; +v__ast__Type former_expected_type; + former_expected_type = c->expected_type; + v__checker__Checker_infix_expr_defer_0 = true; + v__ast__Type left_type = v__checker__Checker_expr(c, node->left); + node->left_type = left_type; + c->expected_type = left_type; + v__ast__Type right_type = v__checker__Checker_expr(c, node->right); + node->right_type = right_type; + if (v__ast__Type_is_number(left_type) && !v__ast__Type_is_ptr(left_type) && (v__ast__Type_alias_eq(right_type, _const_v__ast__int_literal_type) || v__ast__Type_alias_eq(right_type, _const_v__ast__float_literal_type))) { + node->right_type = left_type; + } + if (v__ast__Type_is_number(right_type) && !v__ast__Type_is_ptr(right_type) && (v__ast__Type_alias_eq(left_type, _const_v__ast__int_literal_type) || v__ast__Type_alias_eq(left_type, _const_v__ast__float_literal_type))) { + node->left_type = right_type; + } + v__ast__TypeSymbol* right_sym = v__ast__Table_sym(c->table, right_type); + v__ast__TypeSymbol* right_final = v__ast__Table_final_sym(c->table, right_type); + v__ast__TypeSymbol* left_sym = v__ast__Table_sym(c->table, left_type); + v__ast__TypeSymbol* left_final = v__ast__Table_final_sym(c->table, left_type); + v__token__Pos left_pos = v__ast__Expr_pos(node->left); + v__token__Pos right_pos = v__ast__Expr_pos(node->right); + v__token__Pos left_right_pos = v__token__Pos_extend(left_pos, right_pos); + if (v__ast__Type_is_any_kind_of_pointer(left_type) && (node->op == v__token__Kind__plus || node->op == v__token__Kind__minus || node->op == v__token__Kind__mul || node->op == v__token__Kind__div || node->op == v__token__Kind__mod || node->op == v__token__Kind__xor || node->op == v__token__Kind__amp || node->op == v__token__Kind__pipe)) { + if (!c->pref->translated && ((v__ast__Type_is_any_kind_of_pointer(right_type) && node->op != v__token__Kind__minus) || (!v__ast__Type_is_any_kind_of_pointer(right_type) && !(node->op == v__token__Kind__plus || node->op == v__token__Kind__minus)))) { + string left_name = v__ast__Table_type_to_str(c->table, left_type); + string right_name = v__ast__Table_type_to_str(c->table, right_type); + v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("invalid operator `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` to `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } else if (node->op == v__token__Kind__plus || node->op == v__token__Kind__minus) { + if (!c->inside_unsafe && !v__ast__Expr_is_auto_deref_var(node->left) && !v__ast__Expr_is_auto_deref_var(node->right)) { + v__checker__Checker_warn(c, _SLIT("pointer arithmetic is only allowed in `unsafe` blocks"), left_right_pos); + } + if (v__ast__Type_alias_eq(left_type, _const_v__ast__voidptr_type) && !c->pref->translated) { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` cannot be used with `voidptr`"), 0, { .d_c = 0 }}})), left_pos); + } + } + } + v__ast__Type return_type = left_type; + if (node->op != v__token__Kind__key_is) { + if (node->left._typ == 307 /* v.ast.Ident */) { + if ((*node->left._v__ast__Ident).is_mut) { + v__checker__Checker_error(c, _SLIT("the `mut` keyword is invalid here"), (*node->left._v__ast__Ident).mut_pos); + } + } + else if (node->left._typ == 327 /* v.ast.SelectorExpr */) { + if ((*node->left._v__ast__SelectorExpr).is_mut) { + v__checker__Checker_error(c, _SLIT("the `mut` keyword is invalid here"), (*node->left._v__ast__SelectorExpr).mut_pos); + } + } + + else { + } + ; + } + if (node->right._typ == 307 /* v.ast.Ident */) { + if ((*node->right._v__ast__Ident).is_mut) { + v__checker__Checker_error(c, _SLIT("the `mut` keyword is invalid here"), (*node->right._v__ast__Ident).mut_pos); + } + } + else if (node->right._typ == 327 /* v.ast.SelectorExpr */) { + if ((*node->right._v__ast__SelectorExpr).is_mut) { + v__checker__Checker_error(c, _SLIT("the `mut` keyword is invalid here"), (*node->right._v__ast__SelectorExpr).mut_pos); + } + } + + else { + } + ; + bool eq_ne = (node->op == v__token__Kind__eq || node->op == v__token__Kind__ne); + switch (node->op) { + case v__token__Kind__eq: + case v__token__Kind__ne: + { + bool is_mismatch = (left_sym->kind == v__ast__Kind__alias && (right_sym->kind == v__ast__Kind__struct_ || right_sym->kind == v__ast__Kind__array || right_sym->kind == v__ast__Kind__sum_type)) || (right_sym->kind == v__ast__Kind__alias && (left_sym->kind == v__ast__Kind__struct_ || left_sym->kind == v__ast__Kind__array || left_sym->kind == v__ast__Kind__sum_type)); + if (is_mismatch) { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("possible type mismatch of compared values of `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` operation"), 0, { .d_c = 0 }}})), left_right_pos); + } else if (Array_int_contains(_const_v__ast__integer_type_idxs, left_type) && Array_int_contains(_const_v__ast__integer_type_idxs, right_type)) { + bool is_left_type_signed = Array_int_contains(_const_v__ast__signed_integer_type_idxs, left_type); + bool is_right_type_signed = Array_int_contains(_const_v__ast__signed_integer_type_idxs, right_type); + if (!is_left_type_signed && (node->right)._typ == 312 /* v.ast.IntegerLiteral */) { + if (string_int((*node->right._v__ast__IntegerLiteral).val) < 0 && Array_int_contains(_const_v__ast__int_promoted_type_idxs, left_type)) { + string lt = v__ast__Table_sym(c->table, left_type)->name; + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = lt}}, {_SLIT("` cannot be compared with negative value"), 0, { .d_c = 0 }}})), (*node->right._v__ast__IntegerLiteral).pos); + } + } else if (!is_right_type_signed && (node->left)._typ == 312 /* v.ast.IntegerLiteral */) { + if (string_int((*node->left._v__ast__IntegerLiteral).val) < 0 && Array_int_contains(_const_v__ast__int_promoted_type_idxs, right_type)) { + string rt = v__ast__Table_sym(c->table, right_type)->name; + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("negative value cannot be compared with `"), /*115 &string*/0xfe10, {.d_s = rt}}, {_SLIT("`"), 0, { .d_c = 0 }}})), (*node->left._v__ast__IntegerLiteral).pos); + } + } else if (is_left_type_signed != is_right_type_signed && left_type != _const_v__ast__int_literal_type_idx && right_type != _const_v__ast__int_literal_type_idx) { + multi_return_int_int mr_3899 = v__ast__Table_type_size(c->table, left_type); + int ls = mr_3899.arg0; + multi_return_int_int mr_3942 = v__ast__Table_type_size(c->table, right_type); + int rs = mr_3942.arg0; + if (!c->pref->translated && ((is_left_type_signed && ls < rs) || (is_right_type_signed && rs < ls))) { + string lt = v__ast__Table_sym(c->table, left_type)->name; + string rt = v__ast__Table_sym(c->table, right_type)->name; + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = lt}}, {_SLIT("` cannot be compared with `"), /*115 &string*/0xfe10, {.d_s = rt}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); + } + } + } + break; + } + case v__token__Kind__key_in: + case v__token__Kind__not_in: + { + + if (right_final->kind == (v__ast__Kind__array)) { + if (!(left_sym->kind == v__ast__Kind__sum_type || left_sym->kind == v__ast__Kind__interface_)) { + v__ast__Type elem_type = v__ast__TypeSymbol_array_info(right_final).elem_type; + _option_void _t1 = v__checker__Checker_check_expected(c, left_type, elem_type); + if (_t1.state != 0 && _t1.err._typ != _IError_None___index) { + IError err = _t1.err; + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("left operand to `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` does not match the array element type: "), /*115 &string*/0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), left_right_pos); + ; + } + + ; + } + } + else if (right_final->kind == (v__ast__Kind__map)) { + v__ast__Map map_info = v__ast__TypeSymbol_map_info(right_final); + _option_void _t2 = v__checker__Checker_check_expected(c, left_type, map_info.key_type); + if (_t2.state != 0 && _t2.err._typ != _IError_None___index) { + IError err = _t2.err; + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("left operand to `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` does not match the map key type: "), /*115 &string*/0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), left_right_pos); + ; + } + + ; + node->left_type = map_info.key_type; + } + else if (right_final->kind == (v__ast__Kind__array_fixed)) { + if (!(left_sym->kind == v__ast__Kind__sum_type || left_sym->kind == v__ast__Kind__interface_)) { + v__ast__Type elem_type = v__ast__TypeSymbol_array_fixed_info(right_final).elem_type; + _option_void _t3 = v__checker__Checker_check_expected(c, left_type, elem_type); + if (_t3.state != 0 && _t3.err._typ != _IError_None___index) { + IError err = _t3.err; + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("left operand to `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` does not match the fixed array element type: "), /*115 &string*/0xfe10, {.d_s = IError_name_table[err._typ]._method_msg(err._object)}}, {_SLIT0, 0, { .d_c = 0 }}})), left_right_pos); + ; + } + + ; + } + } + else { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` can only be used with arrays and maps"), 0, { .d_c = 0 }}})), node->pos); + }; + v__ast__Type _t4 = _const_v__ast__bool_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t4; + break; + } + case v__token__Kind__plus: + case v__token__Kind__minus: + case v__token__Kind__mul: + case v__token__Kind__div: + case v__token__Kind__mod: + case v__token__Kind__xor: + case v__token__Kind__amp: + case v__token__Kind__pipe: + { + if ((right_sym->info)._typ == 472 /* v.ast.Alias */ && (/* as */ *(v__ast__Alias*)__as_cast((right_sym->info)._v__ast__Alias,(right_sym->info)._typ, 472) /*expected idx: 472, name: v.ast.Alias */ ).language != v__ast__Language__c && string__eq(c->mod, (*(string*)/*ee elem_sym */array_get(string_split(v__ast__Table_type_to_str(c->table, right_type), _SLIT(".")), 0))) && v__ast__TypeSymbol_is_primitive(v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((right_sym->info)._v__ast__Alias,(right_sym->info)._typ, 472) /*expected idx: 472, name: v.ast.Alias */ ).parent_type))) { + right_sym = v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((right_sym->info)._v__ast__Alias,(right_sym->info)._typ, 472) /*expected idx: 472, name: v.ast.Alias */ ).parent_type); + } + if ((left_sym->info)._typ == 472 /* v.ast.Alias */ && (/* as */ *(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 472) /*expected idx: 472, name: v.ast.Alias */ ).language != v__ast__Language__c && string__eq(c->mod, (*(string*)/*ee elem_sym */array_get(string_split(v__ast__Table_type_to_str(c->table, left_type), _SLIT(".")), 0))) && v__ast__TypeSymbol_is_primitive(v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 472) /*expected idx: 472, name: v.ast.Alias */ ).parent_type))) { + left_sym = v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 472) /*expected idx: 472, name: v.ast.Alias */ ).parent_type); + } + if (c->pref->translated && (node->op == v__token__Kind__plus || node->op == v__token__Kind__minus || node->op == v__token__Kind__mul) && v__ast__Type_is_any_kind_of_pointer(left_type) && v__ast__Type_is_any_kind_of_pointer(right_type)) { + return_type = left_type; + } else if (!c->pref->translated && left_sym->kind == v__ast__Kind__alias && (left_sym->info)._typ == 472 /* v.ast.Alias */ && !(v__ast__TypeSymbol_is_primitive(v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((left_sym->info)._v__ast__Alias,(left_sym->info)._typ, 472) /*expected idx: 472, name: v.ast.Alias */ ).parent_type)))) { + if (v__ast__TypeSymbol_has_method(left_sym, v__token__Kind_str(node->op))) { + _option_v__ast__Fn _t5; + if (_t5 = v__ast__TypeSymbol_find_method(left_sym, v__token__Kind_str(node->op)), _t5.state == 0) { + v__ast__Fn method = *(v__ast__Fn*)_t5.data; + return_type = method.return_type; + } else { + IError err = _t5.err; + return_type = left_type; + } + } else { + string left_name = v__ast__Table_type_to_str(c->table, left_type); + string right_name = v__ast__Table_type_to_str(c->table, right_type); + if (string__eq(left_name, right_name)) { + v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } else { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } + } + } else if (!c->pref->translated && right_sym->kind == v__ast__Kind__alias && (right_sym->info)._typ == 472 /* v.ast.Alias */ && !(v__ast__TypeSymbol_is_primitive(v__ast__Table_sym(c->table, (/* as */ *(v__ast__Alias*)__as_cast((right_sym->info)._v__ast__Alias,(right_sym->info)._typ, 472) /*expected idx: 472, name: v.ast.Alias */ ).parent_type)))) { + if (v__ast__TypeSymbol_has_method(right_sym, v__token__Kind_str(node->op))) { + _option_v__ast__Fn _t6; + if (_t6 = v__ast__TypeSymbol_find_method(right_sym, v__token__Kind_str(node->op)), _t6.state == 0) { + v__ast__Fn method = *(v__ast__Fn*)_t6.data; + return_type = method.return_type; + } else { + IError err = _t6.err; + return_type = right_type; + } + } else { + string left_name = v__ast__Table_type_to_str(c->table, left_type); + string right_name = v__ast__Table_type_to_str(c->table, right_type); + if (string__eq(left_name, right_name)) { + v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } else { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } + } + } + if (!c->pref->translated && (left_sym->kind == v__ast__Kind__array || left_sym->kind == v__ast__Kind__array_fixed || left_sym->kind == v__ast__Kind__map || left_sym->kind == v__ast__Kind__struct_)) { + if (v__ast__TypeSymbol_has_method_with_generic_parent(left_sym, v__token__Kind_str(node->op))) { + _option_v__ast__Fn _t7; + if (_t7 = v__ast__TypeSymbol_find_method_with_generic_parent(left_sym, v__token__Kind_str(node->op)), _t7.state == 0) { + v__ast__Fn method = *(v__ast__Fn*)_t7.data; + return_type = method.return_type; + } else { + IError err = _t7.err; + return_type = left_type; + } + } else { + string left_name = v__ast__Table_type_to_str(c->table, left_type); + string right_name = v__ast__Table_type_to_str(c->table, right_type); + if (string__eq(left_name, right_name)) { + v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } else { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } + } + } else if (!c->pref->translated && (right_sym->kind == v__ast__Kind__array || right_sym->kind == v__ast__Kind__array_fixed || right_sym->kind == v__ast__Kind__map || right_sym->kind == v__ast__Kind__struct_)) { + if (v__ast__TypeSymbol_has_method_with_generic_parent(right_sym, v__token__Kind_str(node->op))) { + _option_v__ast__Fn _t8; + if (_t8 = v__ast__TypeSymbol_find_method_with_generic_parent(right_sym, v__token__Kind_str(node->op)), _t8.state == 0) { + v__ast__Fn method = *(v__ast__Fn*)_t8.data; + return_type = method.return_type; + } else { + IError err = _t8.err; + return_type = right_type; + } + } else { + string left_name = v__ast__Table_type_to_str(c->table, left_type); + string right_name = v__ast__Table_type_to_str(c->table, right_type); + if (string__eq(left_name, right_name)) { + v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } else { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } + } + } else if (v__ast__Expr_is_auto_deref_var(node->left) || v__ast__Expr_is_auto_deref_var(node->right)) { + v__ast__Type deref_left_type = (v__ast__Expr_is_auto_deref_var(node->left) ? (v__ast__Type_deref(left_type)) : (left_type)); + v__ast__Type deref_right_type = (v__ast__Expr_is_auto_deref_var(node->right) ? (v__ast__Type_deref(right_type)) : (right_type)); + string left_name = v__ast__Table_type_to_str(c->table, v__ast__mktyp(deref_left_type)); + string right_name = v__ast__Table_type_to_str(c->table, v__ast__mktyp(deref_right_type)); + if (!string__eq(left_name, right_name)) { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } + } else { + v__ast__Type unaliased_left_type = v__ast__Table_unalias_num_type(c->table, left_type); + v__ast__Type unalias_right_type = v__ast__Table_unalias_num_type(c->table, right_type); + v__ast__Type promoted_type = v__checker__Checker_promote(c, unaliased_left_type, unalias_right_type); + bool is_allowed_pointer_arithmetic = v__ast__Type_is_any_kind_of_pointer(left_type) && v__ast__Type_is_any_kind_of_pointer(right_type) && node->op == v__token__Kind__minus; + if (is_allowed_pointer_arithmetic) { + promoted_type = _const_v__ast__int_type; + } + if (v__ast__Type_idx(promoted_type) == _const_v__ast__void_type_idx) { + string left_name = v__ast__Table_type_to_str(c->table, left_type); + string right_name = v__ast__Table_type_to_str(c->table, right_type); + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } else if (v__ast__Type_has_flag(promoted_type, v__ast__TypeFlag__optional)) { + string s = v__ast__Table_type_to_str(c->table, promoted_type); + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` cannot be used with `"), /*115 &string*/0xfe10, {.d_s = s}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); + } else if (v__ast__Type_is_float(promoted_type)) { + if (node->op == v__token__Kind__mod || node->op == v__token__Kind__xor || node->op == v__token__Kind__amp || node->op == v__token__Kind__pipe) { + string side = (v__ast__Type_alias_eq(left_type, promoted_type) ? (_SLIT("left")) : (_SLIT("right"))); + v__token__Pos pos = (v__ast__Type_alias_eq(left_type, promoted_type) ? (left_pos) : (right_pos)); + string name = (v__ast__Type_alias_eq(left_type, promoted_type) ? (left_sym->name) : (right_sym->name)); + if (node->op == v__token__Kind__mod) { + v__checker__Checker_error(c, _SLIT("float modulo not allowed, use math.fmod() instead"), pos); + } else { + v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = side}}, {_SLIT(" type of `"), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` cannot be non-integer type `"), /*115 &string*/0xfe10, {.d_s = name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), pos); + } + } + } + if (node->op == v__token__Kind__div || node->op == v__token__Kind__mod) { + v__checker__Checker_check_div_mod_by_zero(c, node->right, node->op); + } + return_type = promoted_type; + } + break; + } + case v__token__Kind__gt: + case v__token__Kind__lt: + case v__token__Kind__ge: + case v__token__Kind__le: + { + if ((left_sym->kind == v__ast__Kind__array || left_sym->kind == v__ast__Kind__array_fixed) && (right_sym->kind == v__ast__Kind__array || right_sym->kind == v__ast__Kind__array_fixed)) { + v__checker__Checker_error(c, _SLIT("only `==` and `!=` are defined on arrays"), node->pos); + } else if (left_sym->kind == v__ast__Kind__struct_ && (/* as */ *(v__ast__Struct*)__as_cast((left_sym->info)._v__ast__Struct,(left_sym->info)._typ, 457) /*expected idx: 457, name: v.ast.Struct */ ).generic_types.len > 0) { + v__ast__Type _t9 = _const_v__ast__bool_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t9; + } else if (left_sym->kind == v__ast__Kind__struct_ && right_sym->kind == v__ast__Kind__struct_ && (node->op == v__token__Kind__eq || node->op == v__token__Kind__lt)) { + if (!(v__ast__TypeSymbol_has_method(left_sym, v__token__Kind_str(node->op)) && v__ast__TypeSymbol_has_method(right_sym, v__token__Kind_str(node->op)))) { + string left_name = v__ast__Table_type_to_str(c->table, left_type); + string right_name = v__ast__Table_type_to_str(c->table, right_type); + if (string__eq(left_name, right_name)) { + if (!(node->op == v__token__Kind__lt && c->pref->translated)) { + v__checker__Checker_error(c, str_intp(4, _MOV((StrIntpData[]){{_SLIT("undefined operation `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` "), /*115 &string*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT(" `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } + } else { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("mismatched types `"), /*115 &string*/0xfe10, {.d_s = left_name}}, {_SLIT("` and `"), /*115 &string*/0xfe10, {.d_s = right_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } + } + } + if (left_sym->kind == v__ast__Kind__struct_ && right_sym->kind == v__ast__Kind__struct_) { + if (!v__ast__TypeSymbol_has_method(left_sym, _SLIT("<")) && (node->op == v__token__Kind__ge || node->op == v__token__Kind__le)) { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("cannot use `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` as `<` operator method is not defined"), 0, { .d_c = 0 }}})), left_right_pos); + } else if (!v__ast__TypeSymbol_has_method(left_sym, _SLIT("<")) && node->op == v__token__Kind__gt) { + v__checker__Checker_error(c, _SLIT("cannot use `>` as `<=` operator method is not defined"), left_right_pos); + } + } else if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__generic) && v__ast__Type_has_flag(right_type, v__ast__TypeFlag__generic)) { + v__ast__Type left_gen_type = v__checker__Checker_unwrap_generic(c, left_type); + v__ast__TypeSymbol* gen_sym = v__ast__Table_sym(c->table, left_gen_type); + bool need_overload = (gen_sym->kind == v__ast__Kind__struct_ || gen_sym->kind == v__ast__Kind__interface_); + if (need_overload && !v__ast__TypeSymbol_has_method_with_generic_parent(gen_sym, _SLIT("<")) && (node->op == v__token__Kind__ge || node->op == v__token__Kind__le)) { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("cannot use `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` as `<` operator method is not defined"), 0, { .d_c = 0 }}})), left_right_pos); + } else if (need_overload && !v__ast__TypeSymbol_has_method_with_generic_parent(gen_sym, _SLIT("<")) && node->op == v__token__Kind__gt) { + v__checker__Checker_error(c, _SLIT("cannot use `>` as `<=` operator method is not defined"), left_right_pos); + } + } else if (Array_int_contains(_const_v__ast__integer_type_idxs, left_type) && Array_int_contains(_const_v__ast__integer_type_idxs, right_type)) { + bool is_left_type_signed = Array_int_contains(_const_v__ast__signed_integer_type_idxs, left_type) || left_type == _const_v__ast__int_literal_type_idx; + bool is_right_type_signed = Array_int_contains(_const_v__ast__signed_integer_type_idxs, right_type) || right_type == _const_v__ast__int_literal_type_idx; + if (is_left_type_signed != is_right_type_signed) { + if (is_right_type_signed) { + if ((node->right)._typ == 312 /* v.ast.IntegerLiteral */) { + if (string_int((*node->right._v__ast__IntegerLiteral).val) < 0) { + v__checker__Checker_error(c, _SLIT("unsigned integer cannot be compared with negative value"), (*node->right._v__ast__IntegerLiteral).pos); + } + } + } else if (is_left_type_signed) { + if ((node->left)._typ == 312 /* v.ast.IntegerLiteral */) { + if (string_int((*node->left._v__ast__IntegerLiteral).val) < 0) { + v__checker__Checker_error(c, _SLIT("unsigned integer cannot be compared with negative value"), (*node->left._v__ast__IntegerLiteral).pos); + } + } + } + } + } else if (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__optional) || v__ast__Type_has_flag(right_type, v__ast__TypeFlag__optional)) { + v__token__Pos opt_comp_pos = (v__ast__Type_has_flag(left_type, v__ast__TypeFlag__optional) ? (left_pos) : (right_pos)); + v__checker__Checker_error(c, _SLIT("unwrapped optional cannot be compared in an infix expression"), opt_comp_pos); + } + break; + } + case v__token__Kind__left_shift: + { + if (left_final->kind == v__ast__Kind__array) { + if (!node->is_stmt) { + v__checker__Checker_error(c, _SLIT("array append cannot be used in an expression"), node->pos); + } + v__checker__Checker_check_expr_opt_call(c, node->right, right_type); + multi_return_string_v__token__Pos mr_14744 = v__checker__Checker_fail_if_immutable(c, node->left); + node->auto_locked = mr_14744.arg0; + v__ast__Type left_value_type = v__ast__Table_value_type(c->table, v__checker__Checker_unwrap_generic(c, left_type)); + v__ast__TypeSymbol* left_value_sym = v__ast__Table_sym(c->table, v__checker__Checker_unwrap_generic(c, left_value_type)); + if (left_value_sym->kind == v__ast__Kind__interface_) { + if (right_final->kind != v__ast__Kind__array) { + if (v__checker__Checker_type_implements(c, right_type, left_value_type, right_pos)) { + if (!v__ast__Type_is_ptr(right_type) && !v__ast__Type_is_pointer(right_type) && !c->inside_unsafe && right_sym->kind != v__ast__Kind__interface_) { + v__checker__Checker_mark_as_referenced(c, &node->right, true); + } + } + } else { + v__checker__Checker_type_implements(c, v__ast__Table_value_type(c->table, right_type), left_value_type, right_pos); + } + v__ast__Type _t10 = _const_v__ast__void_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t10; + } else if (left_value_sym->kind == v__ast__Kind__sum_type) { + if (right_final->kind != v__ast__Kind__array) { + if (!v__ast__Table_is_sumtype_or_in_variant(c->table, left_value_type, v__ast__mktyp(right_type))) { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot append `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` to `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); + } + } else { + v__ast__Type right_value_type = v__ast__Table_value_type(c->table, right_type); + if (!v__ast__Table_is_sumtype_or_in_variant(c->table, left_value_type, v__ast__mktyp(right_value_type))) { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot append `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` to `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); + } + } + v__ast__Type _t11 = _const_v__ast__void_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t11; + } + v__ast__Type unwrapped_right_type = v__checker__Checker_unwrap_generic(c, right_type); + if (v__checker__Checker_check_types(c, unwrapped_right_type, left_value_type)) { + if (!(!v__ast__Type_is_ptr(unwrapped_right_type) && v__ast__Type_is_ptr(left_value_type) && v__ast__Type_share(left_value_type) == v__ast__ShareType__mut_t)) { + v__ast__Type _t12 = _const_v__ast__void_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t12; + } + } else if (v__checker__Checker_check_types(c, unwrapped_right_type, v__checker__Checker_unwrap_generic(c, left_type))) { + v__ast__Type _t13 = _const_v__ast__void_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t13; + } + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot append `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` to `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); + v__ast__Type _t14 = _const_v__ast__void_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t14; + } else { + v__ast__Type _t15 = v__checker__Checker_check_shift(c, node, left_type, right_type); + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t15; + } + break; + } + case v__token__Kind__right_shift: + { + v__ast__Type _t16 = v__checker__Checker_check_shift(c, node, left_type, right_type); + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t16; + break; + } + case v__token__Kind__unsigned_right_shift: + { + int _t17; /* if prepend */ + if (!v__ast__Type_is_int(left_type)) { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("invalid operation: shift on type `"), /*115 &string*/0xfe10, {.d_s = v__ast__Table_sym(c->table, left_type)->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_pos); + _t17 = _const_v__ast__void_type_idx; + } else if (v__ast__Type_is_int_literal(left_type)) { + _t17 = _const_v__ast__u32_type_idx; + } else if (v__ast__Type_is_unsigned(left_type)) { + _t17 = left_type; + } else { + _t17 = v__ast__Type_idx(left_type) + _const_v__ast__u32_type_idx - _const_v__ast__int_type_idx; + } + int modified_left_type = _t17; + if (modified_left_type == 0) { + v__ast__Type _t18 = _const_v__ast__void_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t18; + } + *node = ((v__ast__InfixExpr){ + .or_block = node->or_block, + .left = v__ast__CastExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__CastExpr, (((v__ast__CastExpr){.arg = {0},.expr = node->left,.typname = v__ast__Table_type_str(c->table, modified_left_type),.pos = node->pos,.typ = modified_left_type,.expr_type = 0,.has_arg = 0,})))), + .right = node->right, + .auto_locked = node->auto_locked, + .ct_left_value = v__ast__empty_comptime_const_expr(), + .ct_right_value = v__ast__empty_comptime_const_expr(), + .pos = node->pos, + .left_type = left_type, + .right_type = right_type, + .op = v__token__Kind__right_shift, + .is_stmt = false, + .ct_left_value_evaled = 0, + .ct_right_value_evaled = 0, + }); + v__ast__Type _t19 = v__checker__Checker_check_shift(c, node, left_type, right_type); + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t19; + break; + } + case v__token__Kind__key_is: + case v__token__Kind__not_is: + { + v__ast__Expr right_expr = node->right; + v__ast__Type _t20 = 0; + if (right_expr._typ == 333 /* v.ast.TypeNode */) { + _t20 = (*right_expr._v__ast__TypeNode).typ; + } + else if (right_expr._typ == 319 /* v.ast.None */) { + _t20 = _const_v__ast__none_type_idx; + } + + else { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("invalid type `"), /*115 &v.ast.Expr*/0xfe10, {.d_s = v__ast__Expr_str(right_expr)}}, {_SLIT("`"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(right_expr)); + _t20 = ((v__ast__Type)(0)); + } + v__ast__Type typ = _t20; + if (!v__ast__Type_alias_eq(typ, ((v__ast__Type)(0)))) { + v__ast__TypeSymbol* typ_sym = v__ast__Table_sym(c->table, typ); + string op = v__token__Kind_str(node->op); + if (typ_sym->kind == v__ast__Kind__placeholder) { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = op}}, {_SLIT(": type `"), /*115 &string*/0xfe10, {.d_s = typ_sym->name}}, {_SLIT("` does not exist"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(right_expr)); + } + if (left_sym->kind == v__ast__Kind__aggregate) { + v__ast__Type parent_left_type = (/* as */ *(v__ast__Aggregate*)__as_cast((left_sym->info)._v__ast__Aggregate,(left_sym->info)._typ, 470) /*expected idx: 470, name: v.ast.Aggregate */ ).sum_type; + left_sym = v__ast__Table_sym(c->table, parent_left_type); + } + if (!(left_sym->kind == v__ast__Kind__interface_ || left_sym->kind == v__ast__Kind__sum_type)) { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = op}}, {_SLIT("` can only be used with interfaces and sum types"), 0, { .d_c = 0 }}})), node->pos); + } else if ((left_sym->info)._typ == 476 /* v.ast.SumType */) { + if (!Array_v__ast__Type_contains((*left_sym->info._v__ast__SumType).variants, typ)) { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("`"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("` has no variant `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); + } + } + } + v__ast__Type _t21 = _const_v__ast__bool_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t21; + break; + } + case v__token__Kind__arrow: + { + if (left_sym->kind == v__ast__Kind__chan) { + v__ast__Chan chan_info = v__ast__TypeSymbol_chan_info(left_sym); + v__ast__Type elem_type = chan_info.elem_type; + if (!v__checker__Checker_check_types(c, right_type, elem_type)) { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot push `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` on `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); + } + if (chan_info.is_mut) { + v__checker__Checker_fail_if_immutable(c, node->right); + } + if (v__ast__Type_is_ptr(elem_type) && !v__ast__Type_is_ptr(right_type)) { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot push non-reference `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` on `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), right_pos); + } + v__checker__Checker_stmts_ending_with_expression(c, node->or_block.stmts); + } else { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("cannot push on non-channel `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_pos); + } + v__ast__Type _t22 = _const_v__ast__void_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t22; + break; + } + case v__token__Kind__and: + case v__token__Kind__logical_or: + { + if (!c->pref->translated && !c->file->is_translated) { + if (node->left_type != _const_v__ast__bool_type_idx) { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("left operand for `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` is not a boolean"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->left)); + } + if (node->right_type != _const_v__ast__bool_type_idx) { + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT("right operand for `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` is not a boolean"), 0, { .d_c = 0 }}})), v__ast__Expr_pos(node->right)); + } + } + if ((node->left)._typ == 311 /* v.ast.InfixExpr */) { + if ((*node->left._v__ast__InfixExpr).op != node->op && ((*node->left._v__ast__InfixExpr).op == v__token__Kind__logical_or || (*node->left._v__ast__InfixExpr).op == v__token__Kind__and)) { + v__checker__Checker_error(c, _SLIT("ambiguous boolean expression. use `()` to ensure correct order of operations"), node->pos); + } + } + break; + } + case v__token__Kind__unknown: + case v__token__Kind__eof: + case v__token__Kind__name: + case v__token__Kind__number: + case v__token__Kind__string: + case v__token__Kind__str_inter: + case v__token__Kind__chartoken: + case v__token__Kind__inc: + case v__token__Kind__dec: + case v__token__Kind__not: + case v__token__Kind__bit_not: + case v__token__Kind__question: + case v__token__Kind__comma: + case v__token__Kind__semicolon: + case v__token__Kind__colon: + case v__token__Kind__hash: + case v__token__Kind__dollar: + case v__token__Kind__at: + case v__token__Kind__str_dollar: + case v__token__Kind__assign: + case v__token__Kind__decl_assign: + case v__token__Kind__plus_assign: + case v__token__Kind__minus_assign: + case v__token__Kind__div_assign: + case v__token__Kind__mult_assign: + case v__token__Kind__xor_assign: + case v__token__Kind__mod_assign: + case v__token__Kind__or_assign: + case v__token__Kind__and_assign: + case v__token__Kind__right_shift_assign: + case v__token__Kind__left_shift_assign: + case v__token__Kind__unsigned_right_shift_assign: + case v__token__Kind__lcbr: + case v__token__Kind__rcbr: + case v__token__Kind__lpar: + case v__token__Kind__rpar: + case v__token__Kind__lsbr: + case v__token__Kind__nilsbr: + case v__token__Kind__rsbr: + case v__token__Kind__comment: + case v__token__Kind__nl: + case v__token__Kind__dot: + case v__token__Kind__dotdot: + case v__token__Kind__ellipsis: + case v__token__Kind__keyword_beg: + case v__token__Kind__key_as: + case v__token__Kind__key_asm: + case v__token__Kind__key_assert: + case v__token__Kind__key_atomic: + case v__token__Kind__key_break: + case v__token__Kind__key_const: + case v__token__Kind__key_continue: + case v__token__Kind__key_defer: + case v__token__Kind__key_else: + case v__token__Kind__key_enum: + case v__token__Kind__key_false: + case v__token__Kind__key_for: + case v__token__Kind__key_fn: + case v__token__Kind__key_global: + case v__token__Kind__key_go: + case v__token__Kind__key_goto: + case v__token__Kind__key_if: + case v__token__Kind__key_import: + case v__token__Kind__key_interface: + case v__token__Kind__key_match: + case v__token__Kind__key_module: + case v__token__Kind__key_mut: + case v__token__Kind__key_shared: + case v__token__Kind__key_lock: + case v__token__Kind__key_rlock: + case v__token__Kind__key_none: + case v__token__Kind__key_return: + case v__token__Kind__key_select: + case v__token__Kind__key_sizeof: + case v__token__Kind__key_isreftype: + case v__token__Kind__key_likely: + case v__token__Kind__key_unlikely: + case v__token__Kind__key_offsetof: + case v__token__Kind__key_struct: + case v__token__Kind__key_true: + case v__token__Kind__key_type: + case v__token__Kind__key_typeof: + case v__token__Kind__key_dump: + case v__token__Kind__key_orelse: + case v__token__Kind__key_union: + case v__token__Kind__key_pub: + case v__token__Kind__key_static: + case v__token__Kind__key_volatile: + case v__token__Kind__key_unsafe: + case v__token__Kind__keyword_end: + case v__token__Kind___end_: + default: + { + break; + } + } + ; + if (v__ast__Type_alias_eq(left_type, _const_v__ast__bool_type) && !(node->op == v__token__Kind__eq || node->op == v__token__Kind__ne || node->op == v__token__Kind__logical_or || node->op == v__token__Kind__and)) { + v__checker__Checker_error(c, _SLIT("bool types only have the following operators defined: `==`, `!=`, `||`, and `&&`"), node->pos); + } else if (v__ast__Type_alias_eq(left_type, _const_v__ast__string_type) && !(node->op == v__token__Kind__plus || node->op == v__token__Kind__eq || node->op == v__token__Kind__ne || node->op == v__token__Kind__lt || node->op == v__token__Kind__gt || node->op == v__token__Kind__le || node->op == v__token__Kind__ge)) { + v__checker__Checker_error(c, _SLIT("string types only have the following operators defined: `==`, `!=`, `<`, `>`, `<=`, `>=`, and `+`"), node->pos); + } else if (left_sym->kind == v__ast__Kind__enum_ && right_sym->kind == v__ast__Kind__enum_ && !eq_ne) { + v__ast__Enum left_enum = /* as */ *(v__ast__Enum*)__as_cast((left_sym->info)._v__ast__Enum,(left_sym->info)._typ, 486) /*expected idx: 486, name: v.ast.Enum */ ; + v__ast__Enum right_enum = /* as */ *(v__ast__Enum*)__as_cast((right_sym->info)._v__ast__Enum,(right_sym->info)._typ, 486) /*expected idx: 486, name: v.ast.Enum */ ; + if (left_enum.is_flag && right_enum.is_flag) { + if (!(node->op == v__token__Kind__pipe || node->op == v__token__Kind__amp)) { + v__checker__Checker_error(c, _SLIT("only `==`, `!=`, `|` and `&` are defined on `[flag]` tagged `enum`, use an explicit cast to `int` if needed"), node->pos); + } + } else if (!c->pref->translated && !c->file->is_translated) { + v__checker__Checker_error(c, _SLIT("only `==` and `!=` are defined on `enum`, use an explicit cast to `int` if needed"), node->pos); + } + } + if (v__ast__Table_type_kind(c->table, left_type) == v__ast__Kind__sum_type && !eq_ne) { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot use operator `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` with `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); + } else if (v__ast__Table_type_kind(c->table, right_type) == v__ast__Kind__sum_type && !eq_ne) { + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("cannot use operator `"), /*115 &v.token.Kind*/0xfe10, {.d_s = v__token__Kind_str(node->op)}}, {_SLIT("` with `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), node->pos); + } + bool left_is_optional = v__ast__Type_has_flag(left_type, v__ast__TypeFlag__optional); + bool right_is_optional = v__ast__Type_has_flag(right_type, v__ast__TypeFlag__optional); + if (left_is_optional && right_is_optional) { + v__checker__Checker_error(c, _SLIT("unwrapped optionals cannot be used in an infix expression"), left_right_pos); + } else if (left_is_optional || right_is_optional) { + v__token__Pos opt_infix_pos = (left_is_optional ? (left_pos) : (right_pos)); + v__checker__Checker_error(c, _SLIT("unwrapped optional cannot be used in an infix expression"), opt_infix_pos); + } + if (!(v__checker__Checker_symmetric_check(c, left_type, right_type) && v__checker__Checker_symmetric_check(c, right_type, left_type)) && !c->pref->translated && !c->file->is_translated && !v__ast__Expr_is_auto_deref_var(node->left) && !v__ast__Expr_is_auto_deref_var(node->right)) { + if (v__ast__Type_alias_eq(left_type, _const_v__ast__void_type) || v__ast__Type_alias_eq(right_type, _const_v__ast__void_type)) { + v__ast__Type _t23 = _const_v__ast__void_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t23; + } + if (v__ast__Type_nr_muls(left_type) > 0 && v__ast__Type_is_int(right_type)) { + v__ast__Type _t24 = return_type; + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t24; + } + v__checker__Checker_error(c, str_intp(3, _MOV((StrIntpData[]){{_SLIT("infix expr: cannot use `"), /*115 &string*/0xfe10, {.d_s = right_sym->name}}, {_SLIT("` (right expression) as `"), /*115 &string*/0xfe10, {.d_s = left_sym->name}}, {_SLIT("`"), 0, { .d_c = 0 }}})), left_right_pos); + } + v__ast__Type _t25 = (v__token__Kind_is_relational(node->op) ? (_const_v__ast__bool_type) : (return_type)); + // Defer begin + if (v__checker__Checker_infix_expr_defer_0) { + c->expected_type = former_expected_type; + } + // Defer end + return _t25; +} + +VV_LOCAL_SYMBOL void v__checker__Checker_check_div_mod_by_zero(v__checker__Checker* c, v__ast__Expr expr, v__token__Kind op_kind) { + if (expr._typ == 305 /* v.ast.FloatLiteral */) { + if (string_f64((*expr._v__ast__FloatLiteral).val) == 0.0) { + string oper = (op_kind == v__token__Kind__div ? (_SLIT("division")) : (_SLIT("modulo"))); + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = oper}}, {_SLIT(" by zero"), 0, { .d_c = 0 }}})), (*expr._v__ast__FloatLiteral).pos); + } + } + else if (expr._typ == 312 /* v.ast.IntegerLiteral */) { + if (string_int((*expr._v__ast__IntegerLiteral).val) == 0) { + string oper = (op_kind == v__token__Kind__div ? (_SLIT("division")) : (_SLIT("modulo"))); + v__checker__Checker_error(c, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = oper}}, {_SLIT(" by zero"), 0, { .d_c = 0 }}})), (*expr._v__ast__IntegerLiteral).pos); + } + } + else if (expr._typ == 294 /* v.ast.CastExpr */) { + v__checker__Checker_check_div_mod_by_zero(c, (*expr._v__ast__CastExpr).expr, op_kind); + } + + else { + } + ; +} + void v__checker__Checker_interface_decl(v__checker__Checker* c, v__ast__InterfaceDecl* node) { v__checker__Checker_check_valid_pascal_case(c, node->name, _SLIT("interface name"), node->pos); v__ast__TypeSymbol* decl_sym = v__ast__Table_sym(c->table, node->typ); @@ -72409,6 +72452,9 @@ bool v__gen__c__Gen_write_init_function_defer_0 = false; v__gen__c__Gen_writeln(g, v__gen__c__Gen_as_cast_name_table(g)); v__gen__c__Gen_writeln(g, _SLIT("\tbuiltin_init();")); v__gen__c__Gen_writeln(g, _SLIT("\tvinit_string_literals();")); + if (g->nr_closures > 0) { + v__gen__c__Gen_writeln(g, _SLIT("\t_closure_mtx_init();")); + } for (int _t1 = 0; _t1 < g->table->modules.len; ++_t1) { string mod_name = ((string*)g->table->modules.data)[_t1]; v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT("\t{ // Initializations for module "), /*115 &string*/0xfe10, {.d_s = mod_name}}, {_SLIT(" :"), 0, { .d_c = 0 }}}))); @@ -72547,9 +72593,9 @@ VV_LOCAL_SYMBOL void v__gen__c__Gen_write_types(v__gen__c__Gen* g, Array_v__ast_ for (int _t3 = 0; _t3 < (*sym->info._v__ast__Struct).fields.len; ++_t3) { v__ast__StructField field = ((v__ast__StructField*)(*sym->info._v__ast__Struct).fields.data)[_t3]; if (v__ast__Type_has_flag(field.typ, v__ast__TypeFlag__optional)) { - multi_return_string_string mr_148483 = v__gen__c__Gen_optional_type_name(g, field.typ); - string styp = mr_148483.arg0; - string base = mr_148483.arg1; + multi_return_string_string mr_148548 = v__gen__c__Gen_optional_type_name(g, field.typ); + string styp = mr_148548.arg0; + string base = mr_148548.arg1; sync__RwMutex_lock(&g->done_optionals->mtx); /*lock*/ { if (!Array_string_contains(g->done_optionals->val, base)) { @@ -72844,11 +72890,11 @@ bool v__gen__c__Gen_or_block_defer_0 = false; if (string__eq(g->file->mod.name, _SLIT("main")) && (isnil(g->fn_decl) || g->fn_decl->is_main)) { string err_msg = str_intp(3, _MOV((StrIntpData[]){{_SLIT("IError_name_table["), /*115 &string*/0xfe10, {.d_s = cvar_name}}, {_SLIT(".err._typ]._method_msg("), /*115 &string*/0xfe10, {.d_s = cvar_name}}, {_SLIT(".err._object)"), 0, { .d_c = 0 }}})); if (g->pref->is_debug) { - multi_return_int_string_string_string mr_158266 = v__gen__c__Gen_panic_debug_info(g, or_block.pos); - int paline = mr_158266.arg0; - string pafile = mr_158266.arg1; - string pamod = mr_158266.arg2; - string pafn = mr_158266.arg3; + multi_return_int_string_string_string mr_158331 = v__gen__c__Gen_panic_debug_info(g, or_block.pos); + int paline = mr_158331.arg0; + string pafile = mr_158331.arg1; + string pamod = mr_158331.arg2; + string pafn = mr_158331.arg3; v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_SLIT("panic_debug("), /*100 &int*/0xfe07, {.d_i32 = paline}}, {_SLIT(", tos3(\""), /*115 &string*/0xfe10, {.d_s = pafile}}, {_SLIT("\"), tos3(\""), /*115 &string*/0xfe10, {.d_s = pamod}}, {_SLIT("\"), tos3(\""), /*115 &string*/0xfe10, {.d_s = pafn}}, {_SLIT("\"), "), /*115 &string*/0xfe10, {.d_s = err_msg}}, {_SLIT(" );"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT("\tpanic_optional_not_set( "), /*115 &string*/0xfe10, {.d_s = err_msg}}, {_SLIT(" );"), 0, { .d_c = 0 }}}))); @@ -72871,11 +72917,11 @@ bool v__gen__c__Gen_or_block_defer_0 = false; if (string__eq(g->file->mod.name, _SLIT("main")) && (isnil(g->fn_decl) || g->fn_decl->is_main)) { string err_msg = str_intp(3, _MOV((StrIntpData[]){{_SLIT("IError_name_table["), /*115 &string*/0xfe10, {.d_s = cvar_name}}, {_SLIT(".err._typ]._method_msg("), /*115 &string*/0xfe10, {.d_s = cvar_name}}, {_SLIT(".err._object)"), 0, { .d_c = 0 }}})); if (g->pref->is_debug) { - multi_return_int_string_string_string mr_159533 = v__gen__c__Gen_panic_debug_info(g, or_block.pos); - int paline = mr_159533.arg0; - string pafile = mr_159533.arg1; - string pamod = mr_159533.arg2; - string pafn = mr_159533.arg3; + multi_return_int_string_string_string mr_159598 = v__gen__c__Gen_panic_debug_info(g, or_block.pos); + int paline = mr_159598.arg0; + string pafile = mr_159598.arg1; + string pamod = mr_159598.arg2; + string pafn = mr_159598.arg3; v__gen__c__Gen_writeln(g, str_intp(6, _MOV((StrIntpData[]){{_SLIT("panic_debug("), /*100 &int*/0xfe07, {.d_i32 = paline}}, {_SLIT(", tos3(\""), /*115 &string*/0xfe10, {.d_s = pafile}}, {_SLIT("\"), tos3(\""), /*115 &string*/0xfe10, {.d_s = pamod}}, {_SLIT("\"), tos3(\""), /*115 &string*/0xfe10, {.d_s = pafn}}, {_SLIT("\"), "), /*115 &string*/0xfe10, {.d_s = err_msg}}, {_SLIT(");"), 0, { .d_c = 0 }}}))); } else { v__gen__c__Gen_writeln(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT("\tpanic_result_not_set("), /*115 &string*/0xfe10, {.d_s = err_msg}}, {_SLIT(");"), 0, { .d_c = 0 }}}))); @@ -72985,11 +73031,11 @@ VV_LOCAL_SYMBOL string v__gen__c__Gen_type_default(v__gen__c__Gen* g, v__ast__Ty { v__ast__Map info = v__ast__TypeSymbol_map_info(sym); v__ast__TypeSymbol* key_typ = v__ast__Table_sym(g->table, info.key_type); - multi_return_string_string_string_string mr_162143 = v__gen__c__Gen_map_fn_ptrs(g, *key_typ); - string hash_fn = mr_162143.arg0; - string key_eq_fn = mr_162143.arg1; - string clone_fn = mr_162143.arg2; - string free_fn = mr_162143.arg3; + multi_return_string_string_string_string mr_162208 = v__gen__c__Gen_map_fn_ptrs(g, *key_typ); + string hash_fn = mr_162208.arg0; + string key_eq_fn = mr_162208.arg1; + string clone_fn = mr_162208.arg2; + string free_fn = mr_162208.arg3; string noscan_key = v__gen__c__Gen_check_noscan(g, info.key_type); string noscan_value = v__gen__c__Gen_check_noscan(g, info.value_type); string noscan = (noscan_key.len != 0 || noscan_value.len != 0 ? (_SLIT("_noscan")) : (_SLIT(""))); @@ -73515,8 +73561,8 @@ VV_LOCAL_SYMBOL string v__gen__c__Gen_interface_table(v__gen__c__Gen* g) { int params_start_pos = g->out.len; Array_v__ast__Param params = array_clone_to_depth(&method.params, 0); array_set(¶ms, 0, &(v__ast__Param[]) { ((v__ast__Param){(*(v__ast__Param*)/*ee elem_sym */array_get(params, 0)).name,(*(v__ast__Param*)/*ee elem_sym */array_get(params, 0)).pos,(*(v__ast__Param*)/*ee elem_sym */array_get(params, 0)).type_pos,.typ = v__ast__Type_set_nr_muls(st, 1),(*(v__ast__Param*)/*ee elem_sym */array_get(params, 0)).is_mut,(*(v__ast__Param*)/*ee elem_sym */array_get(params, 0)).is_auto_rec,(*(v__ast__Param*)/*ee elem_sym */array_get(params, 0)).is_hidden,}) }); - multi_return_Array_string_Array_string_Array_bool mr_176625 = v__gen__c__Gen_fn_decl_params(g, params, ((voidptr)(0)), false); - Array_string fargs = mr_176625.arg0; + multi_return_Array_string_Array_string_Array_bool mr_176690 = v__gen__c__Gen_fn_decl_params(g, params, ((voidptr)(0)), false); + Array_string fargs = mr_176690.arg0; string parameter_name = strings__Builder_cut_last(&g->out, g->out.len - params_start_pos); if (v__ast__Type_is_ptr(st)) { parameter_name = string_trim_string_left(parameter_name, _SLIT("__shared__")); @@ -73533,8 +73579,8 @@ VV_LOCAL_SYMBOL string v__gen__c__Gen_interface_table(v__gen__c__Gen* g) { *(multi_return_v__ast__Fn_Array_v__ast__Type*) _t26.data = (multi_return_v__ast__Fn_Array_v__ast__Type){.arg0=((v__ast__Fn){.params = __new_array(0, 0, sizeof(v__ast__Param)),.generic_names = __new_array(0, 0, sizeof(string)),.attrs = __new_array(0, 0, sizeof(v__ast__Attr)),.mod = (string){.str=(byteptr)"", .is_lit=1},.file = (string){.str=(byteptr)"", .is_lit=1},.name = (string){.str=(byteptr)"", .is_lit=1},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type_pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.return_type = 0,.receiver_type = 0,.usages = 0,.ctdefine_idx = 0,.source_fn = 0,.language = 0,.file_mode = 0,.is_variadic = 0,.is_pub = 0,.is_ctor_new = 0,.is_deprecated = 0,.is_noreturn = 0,.is_unsafe = 0,.is_placeholder = 0,.is_main = 0,.is_test = 0,.is_keep_alive = 0,.is_method = 0,.no_body = 0,.is_conditional = 0,}),.arg1=__new_array_with_default(0, 0, sizeof(v__ast__Type), 0)}; } - multi_return_v__ast__Fn_Array_v__ast__Type mr_177089 = (*(multi_return_v__ast__Fn_Array_v__ast__Type*)_t26.data); - Array_v__ast__Type embed_types = mr_177089.arg1; + multi_return_v__ast__Fn_Array_v__ast__Type mr_177154 = (*(multi_return_v__ast__Fn_Array_v__ast__Type*)_t26.data); + Array_v__ast__Type embed_types = mr_177154.arg1; if (embed_types.len > 0 && !Array_string_contains(method_names, method.name)) { v__ast__TypeSymbol* embed_sym = v__ast__Table_sym(g->table, (*(v__ast__Type*)array_last(embed_types))); string method_name = str_intp(3, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = embed_sym->cname}}, {_SLIT("_"), /*115 &string*/0xfe10, {.d_s = method.name}}, {_SLIT0, 0, { .d_c = 0 }}})); @@ -73821,7 +73867,7 @@ VV_LOCAL_SYMBOL string v__gen__c__c_closure_helpers(v__pref__Preferences* pref) if (pref->os != v__pref__OS__windows) { strings__Builder_writeln(&builder, _SLIT("#include ")); } - strings__Builder_write_string(&builder, _SLIT("\n#ifdef _MSC_VER\n\011#define __RETURN_ADDRESS() ((char*)_ReturnAddress())\n#elif defined(__TINYC__) && defined(_WIN32)\n\011#define __RETURN_ADDRESS() ((char*)__builtin_return_address(0))\n#else\n\011#define __RETURN_ADDRESS() ((char*)__builtin_extract_return_addr(__builtin_return_address(0)))\n#endif\n\n#ifdef __V_amd64\nstatic const char __closure_thunk[] = {\n\0110x8f, 0x05, 0xda, 0xff, 0xff, 0xff, // pop QWORD PTR [rip - 0x26] # <_orig_rbp>\n\0110xff, 0x15, 0xe4, 0xff, 0xff, 0xff, // call QWORD PTR [rip - 0x1C] # \n\0110xff, 0x25, 0xce, 0xff, 0xff, 0xff, // jmp QWORD PTR [rip - 0x32] # \n};\n#define __CLOSURE_DATA_OFFSET 20\n#elif defined(__V_x86)\nstatic char __closure_thunk[] = {\n\0110xe8, 0x00, 0x00, 0x00, 0x00, // call 4\n\0110x59, // pop ecx\n\0110x8f, 0x41, 0xeb, // pop DWORD PTR [ecx - 21] # <_orig_rbp>\n\0110xff, 0x51, 0xf3, // call DWORD PTR [ecx - 13] # \n\0110xe8, 0x00, 0x00, 0x00, 0x00, // call 4\n\0110x59, // pop ecx\n\0110xff, 0x61, 0xdf, // jmp DWORD PTR [ecx - 33] # <_orig_rbp>\n};\n\n#define __CLOSURE_DATA_OFFSET 16\n#elif defined(__V_arm64)\nstatic char __closure_thunk[] = {\n\0110x10, 0x00, 0x00, 0x10, // adr x16, start\n\0110x1e, 0x02, 0x1e, 0xf8, // str x30, _orig_x30\n\0110x50, 0xff, 0xff, 0x58, // ldr x16, fn\n\0110x00, 0x02, 0x3f, 0xd6, // blr x16\n\0110x9e, 0xfe, 0xff, 0x58, // ldr x30, _orig_x30\n\0110xc0, 0x03, 0x5f, 0xd6 // ret\n};\n#define __CLOSURE_DATA_OFFSET 24\n#elif defined(__V_arm32)\nstatic char __closure_thunk[] = {\n\0110x18, 0xe0, 0x0f, 0xe5, // str lr, orig_lr\n\0110x14, 0xc0, 0x1f, 0xe5, // ldr ip, fn\n\0110x3c, 0xff, 0x2f, 0xe1, // blx ip\n\0110x24, 0xe0, 0x1f, 0xe5, // ldr lr, orig_lr\n\0110x1e, 0xff, 0x2f, 0xe1 // bx lr\n};\n#define __CLOSURE_DATA_OFFSET 16\n#endif\n\nstatic int _V_PAGE_SIZE = 4096; // pre-initialized to the most common value, in case _vinit is not called (in a DLL, for example)\n\nstatic inline void __closure_set_data(void* closure, void* data) {\n void** p = closure;\n p[-1] = data;\n}\n\nstatic inline void __closure_set_function(void* closure, void* f) {\n void** p = closure;\n p[-2] = f;\n}\n\nstatic void* __closure_create(void* fn, void* data) {\n#ifdef _WIN32\n\011SYSTEM_INFO si;\n\011GetNativeSystemInfo(&si);\n\011uint32_t page_size = si.dwPageSize;\n\011char* p = VirtualAlloc(NULL, page_size * 2, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);\n\011if (p == NULL) return 0;\n#else\n\011uint32_t page_size = sysconf(_SC_PAGESIZE);\n\011int prot = PROT_READ | PROT_WRITE;\n\011int flags = MAP_ANONYMOUS | MAP_PRIVATE;\n\011char* p = mmap(0, page_size * 2, prot, flags, -1, 0);\n\011if (p == MAP_FAILED) return 0;\n#endif\n\n\011void* closure = p + page_size;\n\011memcpy(closure, __closure_thunk, sizeof(__closure_thunk));\n\n#ifdef _WIN32\n\011DWORD _tmp;\n\011VirtualProtect(closure, page_size, PAGE_EXECUTE_READ, &_tmp);\n#else\n\011mprotect(closure, page_size, PROT_READ | PROT_EXEC);\n#endif\n\n\011__closure_set_data(closure, data);\n\011__closure_set_function(closure, fn);\n\011return closure;\n}\n")); + strings__Builder_write_string(&builder, _SLIT("\n#ifdef _MSC_VER\n\011#define __RETURN_ADDRESS() ((char*)_ReturnAddress())\n#elif defined(__TINYC__) && defined(_WIN32)\n\011#define __RETURN_ADDRESS() ((char*)__builtin_return_address(0))\n#else\n\011#define __RETURN_ADDRESS() ((char*)__builtin_extract_return_addr(__builtin_return_address(0)))\n#endif\n\n#define ASSUMED_PAGE_SIZE 0x4000 // 16K\n#define _CLOSURE_SIZE (((3*sizeof(void*) > sizeof(__closure_thunk) ? 3*sizeof(void*) : sizeof(__closure_thunk)) + sizeof(void*) - 1) & ~(sizeof(void*) - 1))\n// equal to `max(3*sizeof(void*), sizeof(__closure_thunk))`, rounded up to the next multiple of `sizeof(void*)`\n\n// refer to https://godbolt.org/z/r7P3EYv6c for a complete assembly\n#ifdef __V_amd64\nstatic const char __closure_thunk[] = {\n\0110x8f, 0x05, 0x0a, 0xc0, 0xff, 0xff, // pop QWORD PTR [rip - return_addr]\n\0110xff, 0x15, 0xfc, 0xbf, 0xff, 0xff, // call QWORD PTR [rip - fn]\n\0110xff, 0x25, 0xfe, 0xbf, 0xff, 0xff // jmp QWORD PTR [rip - return_addr]\n};\n#define __CLOSURE_DATA_OFFSET 0x400C\n#elif defined(__V_x86)\nstatic char __closure_thunk[] = {\n\0110xe8, 0x00, 0x00, 0x00, 0x00, // call 4\n\0110x59, // pop ecx\n\0110x8f, 0x81, 0x03, 0xc0, 0xff, 0xff, // pop DWORD PTR [ecx - 0x3ffd] # \n\0110xff, 0x91, 0xff, 0xbf, 0xff, 0xff, // call DWORD PTR [ecx - 0x4001] # \n\0110xe8, 0x00, 0x00, 0x00, 0x00, // call 4\n\0110x59, // pop ecx\n\0110xff, 0xa1, 0xf1, 0xbf, 0xff, 0xff // jmp DWORD PTR [ecx - 0x400f] # \n};\n#define __CLOSURE_DATA_OFFSET 0x4012\n#elif defined(__V_arm64)\nstatic char __closure_thunk[] = {\n\0110x90, 0x00, 0xfe, 0x10, // adr x16, return_addr\n\0110x1e, 0x02, 0x00, 0xf9, // str x30, [x16]\n\0110x10, 0x00, 0xfe, 0x58, // ldr x16, fn\n\0110x00, 0x02, 0x3f, 0xd6, // blr x16\n\0110x1e, 0x00, 0xfe, 0x58, // ldr x30, return_addr\n\0110xc0, 0x03, 0x5f, 0xd6 // ret\n};\n#define __CLOSURE_DATA_OFFSET 0x4010\n#elif defined(__V_arm32)\n// arm32 needs a small page size because its pc-relative addressing range is just \302\2614095 bytes\n#undef ASSUMED_PAGE_SIZE\n#define ASSUMED_PAGE_SIZE 4080\n#undef _CLOSURE_SIZE\n#define _CLOSURE_SIZE 28\nstatic char __closure_thunk[] = {\n\0110xf0, 0xef, 0x0f, 0xe5, // str lr, return_addr\n\0110xf8, 0xcf, 0x1f, 0xe5, // ldr ip, fn\n\0110x3c, 0xff, 0x2f, 0xe1, // blx ip\n\0110xfc, 0xef, 0x1f, 0xe5, // ldr lr, return_addr\n\0110x1e, 0xff, 0x2f, 0xe1 // bx lr\n};\n#define __CLOSURE_DATA_OFFSET 0xFFC\n#endif\n\nstatic inline void __closure_set_data(char* closure, void* data) {\n void** p = (void**)(closure - ASSUMED_PAGE_SIZE);\n p[0] = data;\n}\n\nstatic inline void __closure_set_function(char* closure, void* f) {\n void** p = (void**)(closure - ASSUMED_PAGE_SIZE);\n p[1] = f;\n}\n\n#ifdef _WIN32\n#include \nstatic SRWLOCK _closure_mtx;\n#define _closure_mtx_init() InitializeSRWLock(&_closure_mtx)\n#define _closure_mtx_lock() AcquireSRWLockExclusive(&_closure_mtx)\n#define _closure_mtx_unlock() ReleaseSRWLockExclusive(&_closure_mtx)\n#else\nstatic pthread_mutex_t _closure_mtx;\n#define _closure_mtx_init() pthread_mutex_init(&_closure_mtx, 0)\n#define _closure_mtx_lock() pthread_mutex_lock(&_closure_mtx)\n#define _closure_mtx_unlock() pthread_mutex_unlock(&_closure_mtx)\n#endif\nstatic char* _closure_ptr = 0;\nstatic int _closure_cap = 0;\n\nstatic void* __closure_create(void* fn, void* data) {\n\011_closure_mtx_lock();\n\011if (_closure_cap == 0) {\n#ifdef _WIN32\n\011\011SYSTEM_INFO si;\n\011\011GetNativeSystemInfo(&si);\n\011\011uint32_t page_size = si.dwPageSize;\n\011\011page_size = page_size * (((ASSUMED_PAGE_SIZE - 1) / page_size) + 1);\n\011\011char* p = VirtualAlloc(NULL, page_size * 2, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);\n\011\011if (p == NULL) return 0;\n#else\n\011\011uint32_t page_size = sysconf(_SC_PAGESIZE);\n\011\011page_size = page_size * (((ASSUMED_PAGE_SIZE - 1) / page_size) + 1);\n\011\011int prot = PROT_READ | PROT_WRITE;\n\011\011int flags = MAP_ANONYMOUS | MAP_PRIVATE;\n\011\011char* p = mmap(0, page_size * 2, prot, flags, -1, 0);\n\011\011if (p == MAP_FAILED) return 0;\n#endif\n\011\011char* x = p + page_size;\n\011\011int remaining = page_size / _CLOSURE_SIZE;\n\011\011_closure_ptr = x;\n\011\011_closure_cap = remaining;\n\011\011while (remaining > 0) {\n\011\011\011memcpy(x, __closure_thunk, sizeof(__closure_thunk));\n\011\011\011remaining--;\n\011\011\011x += _CLOSURE_SIZE;\n\011\011}\n#ifdef _WIN32\n\011\011DWORD _tmp;\n\011\011VirtualProtect(_closure_ptr, page_size, PAGE_EXECUTE_READ, &_tmp);\n#else\n\011\011mprotect(_closure_ptr, page_size, PROT_READ | PROT_EXEC);\n#endif\n\011}\n\011_closure_cap--;\n\011void* closure = _closure_ptr;\n\011_closure_ptr += _CLOSURE_SIZE;\n\011__closure_set_data(closure, data);\n\011__closure_set_function(closure, fn);\n\011_closure_mtx_unlock();\n\011return closure;\n}\n\nstatic void __closure_destroy(void *closure) {\n#ifdef _WIN32\n\011SYSTEM_INFO si;\n\011GetNativeSystemInfo(&si);\n\011uint32_t page_size = si.dwPageSize;\n\011page_size = page_size * (((ASSUMED_PAGE_SIZE - 1) / page_size) + 1);\n\011VirtualFree(closure, page_size * 2, MEM_RELEASE);\n#else\n long page_size = sysconf(_SC_PAGESIZE);\n\011page_size = page_size * (((ASSUMED_PAGE_SIZE - 1) / page_size) + 1);\n munmap((char*)closure - page_size, page_size * 2);\n#endif\n}\n")); string _t1 = strings__Builder_str(&builder); return _t1; } @@ -78590,6 +78636,10 @@ VV_LOCAL_SYMBOL void v__gen__c__Gen_infix_expr_eq_op(v__gen__c__Gen* g, v__ast__ v__gen__c__Gen_expr(g, node.right); v__gen__c__Gen_write(g, _SLIT(")")); } else if (v__ast__Type_idx(left.typ) == v__ast__Type_idx(right.typ) && (left.sym->kind == v__ast__Kind__array || left.sym->kind == v__ast__Kind__array_fixed || left.sym->kind == v__ast__Kind__alias || left.sym->kind == v__ast__Kind__map || left.sym->kind == v__ast__Kind__struct_ || left.sym->kind == v__ast__Kind__sum_type || left.sym->kind == v__ast__Kind__interface_)) { + if (g->pref->translated && !g->is_builtin_mod) { + v__gen__c__Gen_gen_plain_infix_expr(g, node); + return; + } switch (left.sym->kind) { case v__ast__Kind__alias: { @@ -78684,25 +78734,21 @@ VV_LOCAL_SYMBOL void v__gen__c__Gen_infix_expr_eq_op(v__gen__c__Gen* g, v__ast__ } case v__ast__Kind__struct_: { - if (g->pref->translated) { - v__gen__c__Gen_gen_plain_infix_expr(g, node); - } else { - string ptr_typ = v__gen__c__Gen_equality_fn(g, left.unaliased); - if (node.op == v__token__Kind__ne) { - v__gen__c__Gen_write(g, _SLIT("!")); - } - v__gen__c__Gen_write(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = ptr_typ}}, {_SLIT("_struct_eq("), 0, { .d_c = 0 }}}))); - if (v__ast__Type_is_ptr(left.typ)) { - v__gen__c__Gen_write(g, _SLIT("*")); - } - v__gen__c__Gen_expr(g, node.left); - v__gen__c__Gen_write(g, _SLIT(", ")); - if (v__ast__Type_is_ptr(right.typ)) { - v__gen__c__Gen_write(g, _SLIT("*")); - } - v__gen__c__Gen_expr(g, node.right); - v__gen__c__Gen_write(g, _SLIT(")")); + string ptr_typ = v__gen__c__Gen_equality_fn(g, left.unaliased); + if (node.op == v__token__Kind__ne) { + v__gen__c__Gen_write(g, _SLIT("!")); } + v__gen__c__Gen_write(g, str_intp(2, _MOV((StrIntpData[]){{_SLIT0, /*115 &string*/0xfe10, {.d_s = ptr_typ}}, {_SLIT("_struct_eq("), 0, { .d_c = 0 }}}))); + if (v__ast__Type_is_ptr(left.typ)) { + v__gen__c__Gen_write(g, _SLIT("*")); + } + v__gen__c__Gen_expr(g, node.left); + v__gen__c__Gen_write(g, _SLIT(", ")); + if (v__ast__Type_is_ptr(right.typ)) { + v__gen__c__Gen_write(g, _SLIT("*")); + } + v__gen__c__Gen_expr(g, node.right); + v__gen__c__Gen_write(g, _SLIT(")")); break; } case v__ast__Kind__sum_type: @@ -78883,7 +78929,7 @@ VV_LOCAL_SYMBOL void v__gen__c__Gen_infix_expr_in_op(v__gen__c__Gen* g, v__ast__ if (right.unaliased_sym->kind == v__ast__Kind__array) { if (left.sym->kind == v__ast__Kind__sum_type || left.sym->kind == v__ast__Kind__interface_) { if ((node.right)._typ == 287 /* v.ast.ArrayInit */) { - if ((*node.right._v__ast__ArrayInit).exprs.len > 0) { + if ((*node.right._v__ast__ArrayInit).exprs.len > 0 && !(v__ast__Table_sym(g->table, (*(v__ast__Type*)/*ee elem_sym */array_get((*node.right._v__ast__ArrayInit).expr_types, 0)))->kind == v__ast__Kind__sum_type || v__ast__Table_sym(g->table, (*(v__ast__Type*)/*ee elem_sym */array_get((*node.right._v__ast__ArrayInit).expr_types, 0)))->kind == v__ast__Kind__interface_)) { Array_v__ast__InfixExpr infix_exprs = __new_array_with_default(0, 0, sizeof(v__ast__InfixExpr), 0); for (int i = 0; i < (*node.right._v__ast__ArrayInit).exprs.len; ++i) { array_push((array*)&infix_exprs, _MOV((v__ast__InfixExpr[]){ ((v__ast__InfixExpr){.or_block = (v__ast__OrExpr){.stmts = __new_array(0, 0, sizeof(v__ast__Stmt)),.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},},.left = node.left,.right = (*(v__ast__Expr*)/*ee elem_sym */array_get((*node.right._v__ast__ArrayInit).exprs, i)),.auto_locked = (string){.str=(byteptr)"", .is_lit=1},.ct_left_value = v__ast__empty_comptime_const_expr(),.ct_right_value = v__ast__empty_comptime_const_expr(),.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.left_type = node.left_type,.right_type = (*(v__ast__Type*)/*ee elem_sym */array_get((*node.right._v__ast__ArrayInit).expr_types, i)),.op = v__token__Kind__key_is,.is_stmt = 0,.ct_left_value_evaled = 0,.ct_right_value_evaled = 0,}) })); @@ -78896,9 +78942,18 @@ VV_LOCAL_SYMBOL void v__gen__c__Gen_infix_expr_in_op(v__gen__c__Gen* g, v__ast__ } } if ((node.right)._typ == 287 /* v.ast.ArrayInit */) { + v__ast__Type elem_type = (*node.right._v__ast__ArrayInit).elem_type; + v__ast__TypeSymbol* elem_sym = v__ast__Table_sym(g->table, elem_type); if ((*node.right._v__ast__ArrayInit).exprs.len > 0) { v__gen__c__Gen_write(g, _SLIT("(")); - v__gen__c__Gen_infix_expr_in_optimization(g, node.left, (*node.right._v__ast__ArrayInit)); + if (elem_sym->kind == v__ast__Kind__sum_type && left.sym->kind != v__ast__Kind__sum_type) { + if (Array_v__ast__Type_contains(v__ast__TypeSymbol_sumtype_info(elem_sym).variants, node.left_type)) { + v__ast__CastExpr new_node_left = ((v__ast__CastExpr){.arg = v__ast__EmptyExpr_to_sumtype_v__ast__Expr(ADDR(v__ast__EmptyExpr, (((v__ast__EmptyExpr){.x = 0,})))),.expr = node.left,.typname = (string){.str=(byteptr)"", .is_lit=1},.pos = (v__token__Pos){.len = 0,.line_nr = 0,.pos = 0,.col = 0,.last_line = 0,},.typ = elem_type,.expr_type = node.left_type,.has_arg = 0,}); + v__gen__c__Gen_infix_expr_in_optimization(g, v__ast__CastExpr_to_sumtype_v__ast__Expr(&new_node_left), (*node.right._v__ast__ArrayInit)); + } + } else { + v__gen__c__Gen_infix_expr_in_optimization(g, node.left, (*node.right._v__ast__ArrayInit)); + } v__gen__c__Gen_write(g, _SLIT(")")); return; } @@ -86700,7 +86755,7 @@ VV_LOCAL_SYMBOL v__ast__Stmt v__parser__Parser_for_stmt(v__parser__Parser* p) { } v__ast__Scope_register(p->scope, v__ast__Var_to_sumtype_v__ast__ScopeObject(ADDR(v__ast__Var, (((v__ast__Var){.smartcasts = __new_array(0, 0, sizeof(v__ast__Type)),.name = key_var_name,.expr = {0},.pos = key_var_pos,.typ = _const_v__ast__int_type,.orig_type = 0,.share = 0,.is_mut = 0,.is_autofree_tmp = 0,.is_arg = 0,.is_auto_deref = 0,.is_inherited = 0,.is_used = 0,.is_changed = 0,.is_or = 0,.is_tmp = true,.is_auto_heap = 0,.is_stack_obj = true,}))))); } else if (v__ast__Scope_known_var(p->scope, val_var_name)) { - v__ast__Stmt _t9 = v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error(p, str_intp(2, _MOV((StrIntpData[]){{_SLIT("redefinition of value iteration variable `"), /*115 &string*/0xfe10, {.d_s = val_var_name}}, {_SLIT("`"), 0, { .d_c = 0 }}})))))); + v__ast__Stmt _t9 = v__ast__NodeError_to_sumtype_v__ast__Stmt(ADDR(v__ast__NodeError, (v__parser__Parser_error_with_pos(p, str_intp(3, _MOV((StrIntpData[]){{_SLIT("redefinition of value iteration variable `"), /*115 &string*/0xfe10, {.d_s = val_var_name}}, {_SLIT("`, use `for ("), /*115 &string*/0xfe10, {.d_s = val_var_name}}, {_SLIT(" in array) {` if you want to check for a condition instead"), 0, { .d_c = 0 }}})), val_var_pos)))); return _t9; } v__parser__Parser_check(p, v__token__Kind__key_in);