diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index aba8514edf..0345132b5e 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -26,7 +26,7 @@ const ( valid_comp_if_platforms = ['amd64', 'aarch64', 'x64', 'x32', 'little_endian', 'big_endian'] valid_comp_if_other = ['js', 'debug', 'prod', 'test', 'glibc', 'prealloc', 'no_bounds_checking'] array_builtin_methods = ['filter', 'clone', 'repeat', 'reverse', 'map', 'slice', 'sort', - 'contains', 'index', 'wait', 'any', 'all'] + 'contains', 'index', 'wait', 'any', 'all', 'first', 'last', 'pop'] ) pub struct Checker { @@ -1388,37 +1388,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { if left_type_sym.kind == .array && method_name in checker.array_builtin_methods { return c.call_array_builtin_method(mut call_expr, left_type, left_type_sym) } else if left_type_sym.kind == .map && method_name in ['clone', 'keys', 'move'] { - mut ret_type := table.void_type - match method_name { - 'clone', 'move' { - if method_name[0] == `m` { - c.fail_if_immutable(call_expr.left) - } - if call_expr.left.is_auto_deref_var() { - ret_type = left_type.deref() - } else { - ret_type = left_type - } - } - 'keys' { - info := left_type_sym.info as table.Map - typ := c.table.find_or_register_array(info.key_type) - ret_type = table.Type(typ) - } - else {} - } - call_expr.receiver_type = left_type.to_ptr() - call_expr.return_type = ret_type - return call_expr.return_type - } else if left_type_sym.kind == .array && method_name in ['first', 'last', 'pop'] { - info := left_type_sym.info as table.Array - call_expr.return_type = info.elem_type - if method_name == 'pop' { - call_expr.receiver_type = left_type.to_ptr() - } else { - call_expr.receiver_type = left_type - } - return call_expr.return_type + return c.call_map_builtin_method(mut call_expr, left_type, left_type_sym) } else if left_type_sym.kind == .array && method_name in ['insert', 'prepend'] { info := left_type_sym.info as table.Array arg_expr := if method_name == 'insert' { @@ -1679,6 +1649,32 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { return table.void_type } +fn (mut c Checker) call_map_builtin_method(mut call_expr ast.CallExpr, left_type table.Type, left_type_sym table.TypeSymbol) table.Type { + method_name := call_expr.name + mut ret_type := table.void_type + match method_name { + 'clone', 'move' { + if method_name[0] == `m` { + c.fail_if_immutable(call_expr.left) + } + if call_expr.left.is_auto_deref_var() { + ret_type = left_type.deref() + } else { + ret_type = left_type + } + } + 'keys' { + info := left_type_sym.info as table.Map + typ := c.table.find_or_register_array(info.key_type) + ret_type = table.Type(typ) + } + else {} + } + call_expr.receiver_type = left_type.to_ptr() + call_expr.return_type = ret_type + return call_expr.return_type +} + fn (mut c Checker) call_array_builtin_method(mut call_expr ast.CallExpr, left_type table.Type, left_type_sym table.TypeSymbol) table.Type { method_name := call_expr.name mut elem_typ := table.void_type @@ -1768,6 +1764,13 @@ fn (mut c Checker) call_array_builtin_method(mut call_expr ast.CallExpr, left_ty call_expr.return_type = table.bool_type } else if method_name == 'index' { call_expr.return_type = table.int_type + } else if method_name in ['first', 'last', 'pop'] { + call_expr.return_type = array_info.elem_type + if method_name == 'pop' { + call_expr.receiver_type = left_type.to_ptr() + } else { + call_expr.receiver_type = left_type + } } return call_expr.return_type }