From 34da4c97eab823d810efdf6fe1a257f06767bcb3 Mon Sep 17 00:00:00 2001 From: yuyi Date: Mon, 8 Jan 2024 23:59:58 +0800 Subject: [PATCH] ast: add has_option_or_result() and cleanup all the related calls (#20434) --- vlib/v/ast/types.v | 9 +++++++-- vlib/v/checker/check_types.v | 2 +- vlib/v/checker/checker.v | 15 +++++++-------- vlib/v/checker/if.v | 4 ++-- vlib/v/checker/infix.v | 2 +- vlib/v/checker/return.v | 2 +- vlib/v/checker/str.v | 4 ++-- vlib/v/gen/c/assign.v | 6 +++--- vlib/v/gen/c/auto_str_methods.v | 2 +- vlib/v/gen/c/cgen.v | 9 ++++----- vlib/v/gen/c/comptime.v | 11 ++++------- vlib/v/gen/c/fn.v | 4 ++-- vlib/v/gen/c/if.v | 5 ++--- vlib/v/gen/c/match.v | 2 +- vlib/v/gen/c/str_intp.v | 4 ++-- vlib/v/gen/wasm/gen.v | 2 +- vlib/v/parser/struct.v | 2 +- 17 files changed, 42 insertions(+), 43 deletions(-) diff --git a/vlib/v/ast/types.v b/vlib/v/ast/types.v index cff92d992b..f873b381fe 100644 --- a/vlib/v/ast/types.v +++ b/vlib/v/ast/types.v @@ -395,6 +395,11 @@ pub fn (t Type) has_flag(flag TypeFlag) bool { return int(t) & (1 << (int(flag) + 24)) > 0 } +@[inline] +pub fn (t Type) has_option_or_result() bool { + return u32(t) & 0x0300_0000 != 0 +} + // debug returns a verbose representation of the information in ts, useful for tracing/debugging pub fn (ts TypeSymbol) debug() []string { mut res := []string{} @@ -708,7 +713,7 @@ pub fn mktyp(typ Type) Type { // returns TypeSymbol kind only if there are no type modifiers pub fn (t &Table) type_kind(typ Type) Kind { - if typ.nr_muls() > 0 || typ.has_flag(.option) || typ.has_flag(.result) { + if typ.nr_muls() > 0 || typ.has_option_or_result() { return Kind.placeholder } return t.sym(typ).kind @@ -1036,7 +1041,7 @@ pub fn (t &TypeSymbol) is_builtin() bool { // type_size returns the size and alignment (in bytes) of `typ`, similarly to C's `sizeof()` and `alignof()`. pub fn (t &Table) type_size(typ Type) (int, int) { - if typ.has_flag(.option) || typ.has_flag(.result) { + if typ.has_option_or_result() { return t.type_size(ast.error_type_idx) } if typ.nr_muls() > 0 { diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 6a7f80654e..80cd7d9494 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -146,7 +146,7 @@ fn (mut c Checker) check_types(got ast.Type, expected ast.Type) bool { if expected == ast.charptr_type && got == ast.char_type.ref() { return true } - if expected.has_flag(.option) || expected.has_flag(.result) { + if expected.has_option_or_result() { sym := c.table.sym(got) if ((sym.idx == ast.error_type_idx || got in [ast.none_type, ast.error_type]) && expected.has_flag(.option)) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index c8ef0c0eae..68281f4dda 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1147,11 +1147,11 @@ fn (mut c Checker) check_expr_option_or_result_call(expr ast.Expr, ret_type ast. mut expr_ret_type := expr.return_type if expr_ret_type != 0 && c.table.sym(expr_ret_type).kind == .alias { unaliased_ret_type := c.table.unaliased_type(expr_ret_type) - if unaliased_ret_type.has_flag(.option) || unaliased_ret_type.has_flag(.result) { + if unaliased_ret_type.has_option_or_result() { expr_ret_type = unaliased_ret_type } } - if expr_ret_type.has_flag(.option) || expr_ret_type.has_flag(.result) { + if expr_ret_type.has_option_or_result() { return_modifier_kind := if expr_ret_type.has_flag(.option) { 'an Option' } else { @@ -1179,7 +1179,7 @@ fn (mut c Checker) check_expr_option_or_result_call(expr ast.Expr, ret_type ast. } ast.SelectorExpr { if c.table.sym(ret_type).kind != .chan { - if expr.typ.has_flag(.option) || expr.typ.has_flag(.result) { + if expr.typ.has_option_or_result() { with_modifier_kind := if expr.typ.has_flag(.option) { 'an Option' } else { @@ -2671,11 +2671,11 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type { mut ret_type := c.call_expr(mut node) if ret_type != 0 && c.table.sym(ret_type).kind == .alias { unaliased_type := c.table.unaliased_type(ret_type) - if unaliased_type.has_flag(.option) || unaliased_type.has_flag(.result) { + if unaliased_type.has_option_or_result() { ret_type = unaliased_type } } - if !ret_type.has_flag(.option) && !ret_type.has_flag(.result) { + if !ret_type.has_option_or_result() { c.expr_or_block_err(node.or_block.kind, node.name, node.or_block.pos, false) } @@ -3586,8 +3586,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type { if c.inside_interface_deref && c.table.is_interface_var(obj) { typ = typ.deref() } - is_option := typ.has_flag(.option) || typ.has_flag(.result) - || node.or_expr.kind != .absent + is_option := typ.has_option_or_result() || node.or_expr.kind != .absent node.kind = .variable node.info = ast.IdentVar{ typ: typ @@ -4297,7 +4296,7 @@ fn (mut c Checker) check_index(typ_sym &ast.TypeSymbol, index ast.Expr, index_ty } } } - if index_type.has_flag(.option) || index_type.has_flag(.result) { + if index_type.has_option_or_result() { type_str := if typ_sym.kind == .string { '(type `${typ_sym.name}`)' } else { diff --git a/vlib/v/checker/if.v b/vlib/v/checker/if.v index 9e94928cdb..fb671e8213 100644 --- a/vlib/v/checker/if.v +++ b/vlib/v/checker/if.v @@ -381,7 +381,7 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { node.is_expr = true node.typ = c.expected_type } - if c.expected_type.has_flag(.option) || c.expected_type.has_flag(.result) { + if c.expected_type.has_option_or_result() { if node.typ == ast.void_type { node.is_expr = true node.typ = c.expected_type @@ -447,7 +447,7 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { if is_noreturn_callexpr(stmt.expr) { continue } - if (node.typ.has_flag(.option) || node.typ.has_flag(.result)) + if (node.typ.has_option_or_result()) && c.table.sym(stmt.typ).kind == .struct_ && c.type_implements(stmt.typ, ast.error_type, node.pos) { stmt.expr = ast.CastExpr{ diff --git a/vlib/v/checker/infix.v b/vlib/v/checker/infix.v index a7bcf0608a..27cb2e220f 100644 --- a/vlib/v/checker/infix.v +++ b/vlib/v/checker/infix.v @@ -397,7 +397,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { left_name := c.table.type_to_str(unwrapped_left_type) right_name := c.table.type_to_str(unwrapped_right_type) c.error('mismatched types `${left_name}` and `${right_name}`', left_right_pos) - } else if promoted_type.has_flag(.option) || promoted_type.has_flag(.result) { + } else if promoted_type.has_option_or_result() { s := c.table.type_to_str(promoted_type) c.error('`${node.op}` cannot be used with `${s}`', node.pos) } else if promoted_type.is_float() { diff --git a/vlib/v/checker/return.v b/vlib/v/checker/return.v index 592d62a6ac..1ecec7611f 100644 --- a/vlib/v/checker/return.v +++ b/vlib/v/checker/return.v @@ -29,7 +29,7 @@ fn (mut c Checker) return_stmt(mut node ast.Return) { mut expected_type := c.unwrap_generic(c.expected_type) if expected_type != 0 && c.table.sym(expected_type).kind == .alias { unaliased_type := c.table.unaliased_type(expected_type) - if unaliased_type.has_flag(.option) || unaliased_type.has_flag(.result) { + if unaliased_type.has_option_or_result() { expected_type = unaliased_type } } diff --git a/vlib/v/checker/str.v b/vlib/v/checker/str.v index 9b9f901faf..f8f07b6ad9 100644 --- a/vlib/v/checker/str.v +++ b/vlib/v/checker/str.v @@ -7,7 +7,7 @@ import v.ast import v.token fn (mut c Checker) get_default_fmt(ftyp ast.Type, typ ast.Type) u8 { - if ftyp.has_flag(.option) || ftyp.has_flag(.result) { + if ftyp.has_option_or_result() { return `s` } else if typ.is_float() { return `g` @@ -32,7 +32,7 @@ fn (mut c Checker) get_default_fmt(ftyp ast.Type, typ ast.Type) u8 { } if ftyp in [ast.string_type, ast.bool_type] || sym.kind in [.enum_, .array, .array_fixed, .struct_, .map, .multi_return, .sum_type, .interface_, .none_] - || ftyp.has_flag(.option) || ftyp.has_flag(.result) || sym.has_method('str') { + || ftyp.has_option_or_result() || sym.has_method('str') { return `s` } else { return `_` diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index ed64f5320b..ff081da27b 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -330,7 +330,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { } // TODO: no buffer fiddling ast.AnonFn { - if !(var_type.has_flag(.option) || var_type.has_flag(.result)) { + if !var_type.has_option_or_result() { if blank_assign { g.write('{') } @@ -376,8 +376,8 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { g.is_assign_lhs = true g.assign_op = node.op - g.left_is_opt = var_type.has_flag(.option) || var_type.has_flag(.result) - g.right_is_opt = val_type.has_flag(.option) || val_type.has_flag(.result) + g.left_is_opt = var_type.has_option_or_result() + g.right_is_opt = val_type.has_option_or_result() defer { g.left_is_opt = false g.right_is_opt = false diff --git a/vlib/v/gen/c/auto_str_methods.v b/vlib/v/gen/c/auto_str_methods.v index 2134ee21a4..e5786dc536 100644 --- a/vlib/v/gen/c/auto_str_methods.v +++ b/vlib/v/gen/c/auto_str_methods.v @@ -1094,7 +1094,7 @@ fn struct_auto_str_func(sym &ast.TypeSymbol, lang ast.Language, _field_type ast. return '${fn_name}(${deref}it.${final_field_name}${sufix})', false } else { mut method_str := '' - if !field_type.is_ptr() && (field_type.has_flag(.option) || field_type.has_flag(.result)) { + if !field_type.is_ptr() && field_type.has_option_or_result() { method_str = '(*(${sym.name}*)it.${final_field_name}.data)' } else { method_str = 'it.${final_field_name}' diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 2165af0856..3f2e986fca 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -2559,7 +2559,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ got_deref_type := got_type.deref() deref_sym := g.table.sym(got_deref_type) deref_will_match := expected_type in [got_type, got_deref_type, deref_sym.parent_idx] - got_is_opt_or_res := got_type.has_flag(.option) || got_type.has_flag(.result) + got_is_opt_or_res := got_type.has_option_or_result() if deref_will_match || got_is_opt_or_res || expr.is_auto_deref_var() { g.write('*') } @@ -3701,8 +3701,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { } // if node expr is a root ident and an optional - mut is_opt_or_res := node.expr is ast.Ident - && (node.expr_type.has_flag(.option) || node.expr_type.has_flag(.result)) + mut is_opt_or_res := node.expr is ast.Ident && node.expr_type.has_option_or_result() if is_opt_or_res { opt_base_typ := g.base_type(node.expr_type) g.write('(*(${opt_base_typ}*)') @@ -4957,7 +4956,7 @@ fn (mut g Gen) return_stmt(node ast.Return) { mut fn_ret_type := g.fn_decl.return_type if sym.kind == .alias { unaliased_type := g.table.unaliased_type(fn_ret_type) - if unaliased_type.has_flag(.option) || unaliased_type.has_flag(.result) { + if unaliased_type.has_option_or_result() { fn_ret_type = unaliased_type } } @@ -6521,7 +6520,7 @@ fn c_fn_name(name_ string) string { fn (mut g Gen) type_default(typ_ ast.Type) string { typ := g.unwrap_generic(typ_) - if typ.has_flag(.option) || typ.has_flag(.result) { + if typ.has_option_or_result() { return '{0}' } // Always set pointers to 0 diff --git a/vlib/v/gen/c/comptime.v b/vlib/v/gen/c/comptime.v index 265f7dccf9..72d853a616 100644 --- a/vlib/v/gen/c/comptime.v +++ b/vlib/v/gen/c/comptime.v @@ -150,8 +150,7 @@ fn (mut g Gen) comptime_call(mut node ast.ComptimeCall) { } } - if !g.inside_call && node.or_block.kind != .block - && (m.return_type.has_flag(.option) || m.return_type.has_flag(.result)) { + if !g.inside_call && node.or_block.kind != .block && m.return_type.has_option_or_result() { g.write('(*(${g.base_type(m.return_type)}*)') } // TODO: check argument types @@ -212,12 +211,10 @@ fn (mut g Gen) comptime_call(mut node ast.ComptimeCall) { } } g.write(')') - if !g.inside_call && node.or_block.kind != .block - && (m.return_type.has_flag(.option) || m.return_type.has_flag(.result)) { + if !g.inside_call && node.or_block.kind != .block && m.return_type.has_option_or_result() { g.write('.data)') } - if node.or_block.kind != .absent - && (m.return_type.has_flag(.option) || m.return_type.has_flag(.result)) { + if node.or_block.kind != .absent && m.return_type.has_option_or_result() { if !g.inside_assign { cur_line := g.go_before_last_stmt() tmp_var := g.new_tmp_var() @@ -304,7 +301,7 @@ fn (mut g Gen) comptime_if(node ast.IfExpr) { } } tmp_var := g.new_tmp_var() - is_opt_or_result := node.typ.has_flag(.option) || node.typ.has_flag(.result) + is_opt_or_result := node.typ.has_option_or_result() line := if node.is_expr { stmt_str := g.go_before_last_stmt() g.write(util.tabs(g.indent)) diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 1940fcd005..e02604f15e 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -769,7 +769,7 @@ fn (mut g Gen) call_expr(node ast.CallExpr) { mut ret_typ := node.return_type if g.table.sym(ret_typ).kind == .alias { unaliased_type := g.table.unaliased_type(ret_typ) - if unaliased_type.has_flag(.option) || unaliased_type.has_flag(.result) { + if unaliased_type.has_option_or_result() { ret_typ = unaliased_type } } @@ -808,7 +808,7 @@ fn (mut g Gen) call_expr(node ast.CallExpr) { mut unwrapped_typ := node.return_type.clear_flags(.option, .result) if g.table.sym(unwrapped_typ).kind == .alias { unaliased_type := g.table.unaliased_type(unwrapped_typ) - if unaliased_type.has_flag(.option) || unaliased_type.has_flag(.result) { + if unaliased_type.has_option_or_result() { unwrapped_typ = unaliased_type.clear_flags(.option, .result) } } diff --git a/vlib/v/gen/c/if.v b/vlib/v/gen/c/if.v index 6d1081cd73..4680a94435 100644 --- a/vlib/v/gen/c/if.v +++ b/vlib/v/gen/c/if.v @@ -7,8 +7,7 @@ import v.ast fn (mut g Gen) need_tmp_var_in_if(node ast.IfExpr) bool { if node.is_expr && g.inside_ternary == 0 { - if g.is_autofree || node.typ.has_flag(.option) || node.typ.has_flag(.result) - || node.is_comptime { + if g.is_autofree || node.typ.has_option_or_result() || node.is_comptime { return true } for branch in node.branches { @@ -97,7 +96,7 @@ fn (mut g Gen) need_tmp_var_in_expr(expr ast.Expr) bool { ast.ConcatExpr { for val in expr.vals { if val is ast.CallExpr { - if val.return_type.has_flag(.option) || val.return_type.has_flag(.result) { + if val.return_type.has_option_or_result() { return true } } diff --git a/vlib/v/gen/c/match.v b/vlib/v/gen/c/match.v index 6ce45af0f7..8f6d1ebd9b 100644 --- a/vlib/v/gen/c/match.v +++ b/vlib/v/gen/c/match.v @@ -8,7 +8,7 @@ import v.ast fn (mut g Gen) need_tmp_var_in_match(node ast.MatchExpr) bool { if node.is_expr && node.return_type != ast.void_type && node.return_type != 0 { if g.table.sym(node.return_type).kind in [.sum_type, .multi_return] - || node.return_type.has_flag(.option) || node.return_type.has_flag(.result) { + || node.return_type.has_option_or_result() { return true } if g.table.final_sym(node.cond_type).kind == .enum_ && node.branches.len > 5 { diff --git a/vlib/v/gen/c/str_intp.v b/vlib/v/gen/c/str_intp.v index fa0ccf7ecf..a9d24edfab 100644 --- a/vlib/v/gen/c/str_intp.v +++ b/vlib/v/gen/c/str_intp.v @@ -13,7 +13,7 @@ import v.ast import v.util fn (mut g Gen) get_default_fmt(ftyp ast.Type, typ ast.Type) u8 { - if ftyp.has_flag(.option) || ftyp.has_flag(.result) { + if ftyp.has_option_or_result() { return `s` } else if typ.is_float() { return `g` @@ -38,7 +38,7 @@ fn (mut g Gen) get_default_fmt(ftyp ast.Type, typ ast.Type) u8 { } if ftyp in [ast.string_type, ast.bool_type] || sym.kind in [.enum_, .array, .array_fixed, .struct_, .map, .multi_return, .sum_type, .interface_, .none_] - || ftyp.has_flag(.option) || ftyp.has_flag(.result) || sym.has_method('str') { + || ftyp.has_option_or_result() || sym.has_method('str') { return `s` } else { return `_` diff --git a/vlib/v/gen/wasm/gen.v b/vlib/v/gen/wasm/gen.v index 38c339890a..f4c825ae79 100644 --- a/vlib/v/gen/wasm/gen.v +++ b/vlib/v/gen/wasm/gen.v @@ -147,7 +147,7 @@ pub fn (mut g Gen) fn_external_import(node ast.FnDecl) { if node.language == .js && g.pref.os == .wasi { g.v_error('javascript interop functions are not allowed in a `wasi` build', node.pos) } - if node.return_type.has_flag(.option) || node.return_type.has_flag(.result) { + if node.return_type.has_option_or_result() { g.v_error('interop functions must not return option or result', node.pos) } diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index f6e35ac578..a72aac92e6 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -248,7 +248,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { return ast.StructDecl{} } field_pos = field_start_pos.extend(p.prev_tok.pos()) - if typ.has_flag(.option) || typ.has_flag(.result) { + if typ.has_option_or_result() { option_pos = p.peek_token(-2).pos() } }