Skip to content

Commit afc07f4

Browse files
authored
cgen,checker: minor optimizations (#23191)
1 parent 9acf058 commit afc07f4

File tree

6 files changed

+79
-71
lines changed

6 files changed

+79
-71
lines changed

vlib/v/checker/struct.v

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,12 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
4242
} else if (embed_sym.info as ast.Struct).is_heap && !embed.typ.is_ptr() {
4343
struct_sym.info.is_heap = true
4444
}
45-
if embed.typ.has_flag(.generic) {
45+
embed_is_generic := embed.typ.has_flag(.generic)
46+
if embed_is_generic {
4647
has_generic_types = true
4748
}
4849
// Ensure each generic type of the embed was declared in the struct's definition
49-
if node.generic_types.len > 0 && embed.typ.has_flag(.generic) {
50+
if embed_is_generic && node.generic_types.len > 0 {
5051
embed_generic_names := c.table.generic_type_names(embed.typ)
5152
node_generic_names := node.generic_types.map(c.table.type_to_str(it))
5253
for name in embed_generic_names {
@@ -163,14 +164,15 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
163164
if !c.ensure_type_exists(field.typ, field.type_pos) {
164165
continue
165166
}
167+
field_is_generic := field.typ.has_flag(.generic)
166168
if !c.ensure_generic_type_specify_type_names(field.typ, field.type_pos, c.table.final_sym(field.typ).kind in [
167169
.array,
168170
.array_fixed,
169171
.map,
170-
], field.typ.has_flag(.generic)) {
172+
], field_is_generic) {
171173
continue
172174
}
173-
if field.typ.has_flag(.generic) {
175+
if field_is_generic {
174176
has_generic_types = true
175177
}
176178
if node.language == .v {
@@ -228,7 +230,7 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
228230

229231
if field.has_default_expr {
230232
c.expected_type = field.typ
231-
if !field.typ.has_flag(.option) && !field.typ.has_flag(.result) {
233+
if !field.typ.has_option_or_result() {
232234
c.check_expr_option_or_result_call(field.default_expr, field.default_expr_typ)
233235
}
234236
if sym.info is ast.ArrayFixed && field.typ == field.default_expr_typ {
@@ -272,12 +274,14 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
272274
field.default_expr.pos)
273275
}
274276
}
275-
if field.typ.has_flag(.option) && field.default_expr is ast.None {
276-
c.warn('unnecessary default value of `none`: struct fields are zeroed by default',
277-
field.default_expr.pos)
278-
}
279-
if field.typ.has_flag(.option) && field.default_expr.is_nil() {
280-
c.error('cannot assign `nil` to option value', field.default_expr.pos())
277+
field_is_option := field.typ.has_flag(.option)
278+
if field_is_option {
279+
if field.default_expr is ast.None {
280+
c.warn('unnecessary default value of `none`: struct fields are zeroed by default',
281+
field.default_expr.pos)
282+
} else if field.default_expr.is_nil() {
283+
c.error('cannot assign `nil` to option value', field.default_expr.pos())
284+
}
281285
}
282286
continue
283287
}
@@ -694,7 +698,8 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
694698
if got_type == ast.void_type {
695699
c.error('`${init_field.expr}` (no value) used as value', init_field.pos)
696700
}
697-
if !exp_type.has_flag(.option) {
701+
exp_type_is_option := exp_type.has_flag(.option)
702+
if !exp_type_is_option {
698703
got_type = c.check_expr_option_or_result_call(init_field.expr, got_type)
699704
if got_type.has_flag(.option) {
700705
c.error('cannot assign an Option value to a non-option struct field',
@@ -707,7 +712,7 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
707712
if got_type.has_flag(.result) {
708713
c.check_expr_option_or_result_call(init_field.expr, init_field.typ)
709714
}
710-
if exp_type.has_flag(.option) && got_type.is_ptr() && !(exp_type.is_ptr()
715+
if exp_type_is_option && got_type.is_ptr() && !(exp_type.is_ptr()
711716
&& exp_type_sym.kind == .struct) {
712717
c.error('cannot assign a pointer to option struct field', init_field.pos)
713718
}
@@ -776,7 +781,7 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
776781
} else {
777782
if !c.inside_unsafe && type_sym.language == .v && !(c.file.is_translated
778783
|| c.pref.translated) && exp_type.is_ptr()
779-
&& !got_type.is_any_kind_of_pointer() && !exp_type.has_flag(.option)
784+
&& !got_type.is_any_kind_of_pointer() && !exp_type_is_option
780785
&& !(init_field.expr is ast.UnsafeExpr && init_field.expr.expr.str() == '0') {
781786
if init_field.expr.str() == '0' {
782787
c.error('assigning `0` to a reference field is only allowed in `unsafe` blocks',
@@ -787,7 +792,7 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
787792
}
788793
} else if exp_type.is_any_kind_of_pointer()
789794
&& !got_type.is_any_kind_of_pointer() && !got_type.is_int()
790-
&& (!exp_type.has_flag(.option) || got_type.idx() != ast.none_type_idx) {
795+
&& (!exp_type_is_option || got_type.idx() != ast.none_type_idx) {
791796
got_typ_str := c.table.type_to_str(got_type)
792797
exp_typ_str := c.table.type_to_str(exp_type)
793798
c.error('cannot assign to field `${field_info.name}`: expected a pointer `${exp_typ_str}`, but got `${got_typ_str}`',

vlib/v/gen/c/cgen.v

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2165,7 +2165,7 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) bool {
21652165
// applicable to situations where the expr_typ does not have `option` and `result`,
21662166
// e.g. field default: "foo ?int = 1", field assign: "foo = 1", field init: "foo: 1"
21672167
fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.Type, tmp_var string) {
2168-
if !ret_typ.has_flag(.option) && !ret_typ.has_flag(.result) {
2168+
if !ret_typ.has_option_or_result() {
21692169
panic('cgen: parameter `ret_typ` of function `expr_with_tmp_var()` must be an Option or Result')
21702170
}
21712171

@@ -2182,6 +2182,8 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
21822182
g.writeln('${g.styp(ret_typ)} ${tmp_var} = {.state=2, .err=${expr.name}};')
21832183
} else {
21842184
mut simple_assign := false
2185+
expr_typ_is_option := expr_typ.has_flag(.option)
2186+
ret_typ_is_option := ret_typ.has_flag(.option)
21852187
if ret_typ.has_flag(.generic) {
21862188
if expr is ast.SelectorExpr && g.cur_concrete_types.len == 0 {
21872189
// resolve generic struct on selectorExpr inside non-generic function
@@ -2203,8 +2205,8 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
22032205
} else {
22042206
g.writeln('${g.styp(ret_typ)} ${tmp_var};')
22052207
}
2206-
if ret_typ.has_flag(.option) {
2207-
if expr_typ.has_flag(.option) && expr in [ast.StructInit, ast.ArrayInit, ast.MapInit] {
2208+
if ret_typ_is_option {
2209+
if expr_typ_is_option && expr in [ast.StructInit, ast.ArrayInit, ast.MapInit] {
22082210
simple_assign = expr is ast.StructInit
22092211
if simple_assign {
22102212
g.write('${tmp_var} = ')
@@ -2214,13 +2216,13 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
22142216
} else {
22152217
simple_assign =
22162218
((expr is ast.SelectorExpr || (expr is ast.Ident && !expr.is_auto_heap()))
2217-
&& ret_typ.is_ptr() && expr_typ.is_ptr() && expr_typ.has_flag(.option))
2219+
&& ret_typ.is_ptr() && expr_typ.is_ptr() && expr_typ_is_option)
22182220
|| (expr_typ == ret_typ && !(expr_typ.has_option_or_result()
22192221
&& (expr_typ.is_ptr() || expr is ast.LambdaExpr)))
22202222
// option ptr assignment simplification
22212223
if simple_assign {
22222224
g.write('${tmp_var} = ')
2223-
} else if expr_typ.has_flag(.option) && expr is ast.PrefixExpr
2225+
} else if expr_typ_is_option && expr is ast.PrefixExpr
22242226
&& expr.right is ast.StructInit
22252227
&& (expr.right as ast.StructInit).init_fields.len == 0 {
22262228
g.write('_option_none(&(${styp}[]) { ')
@@ -2243,7 +2245,7 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
22432245
g.write('_result_ok(&(${styp}[]) { ')
22442246
}
22452247
g.expr_with_cast(expr, expr_typ, ret_typ)
2246-
if ret_typ.has_flag(.option) {
2248+
if ret_typ_is_option {
22472249
if simple_assign {
22482250
g.writeln(';')
22492251
} else {
@@ -2448,8 +2450,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
24482450
if method.return_type.has_flag(.option) {
24492451
// Register an option if it's not registered yet
24502452
g.register_option(method.return_type)
2451-
}
2452-
if method.return_type.has_flag(.result) {
2453+
} else if method.return_type.has_flag(.result) {
24532454
// Register a result if it's not registered yet
24542455
g.register_result(method.return_type)
24552456
}
@@ -2896,7 +2897,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
28962897
neither_void := ast.voidptr_type !in [got_type, expected_type]
28972898
&& ast.nil_type !in [got_type, expected_type]
28982899
if expected_type.has_flag(.shared_f) && !got_type_raw.has_flag(.shared_f)
2899-
&& !expected_type.has_flag(.option) && !expected_type.has_flag(.result) {
2900+
&& !expected_type.has_option_or_result() {
29002901
shared_styp := exp_styp[0..exp_styp.len - 1] // `shared` implies ptr, so eat one `*`
29012902
if got_type_raw.is_ptr() {
29022903
g.error('cannot convert reference to `shared`', expr.pos())
@@ -2939,8 +2940,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
29392940
return
29402941
}
29412942
}
2942-
if exp_sym.kind == .function && !expected_type.has_flag(.option)
2943-
&& !expected_type.has_flag(.result) {
2943+
if exp_sym.kind == .function && !expected_type.has_option_or_result() {
29442944
g.write('(voidptr)')
29452945
}
29462946
// no cast
@@ -3626,7 +3626,8 @@ fn (mut g Gen) expr(node_ ast.Expr) {
36263626
node.return_type.clear_option_and_result()
36273627
}
36283628
mut shared_styp := ''
3629-
if g.is_shared && !ret_type.has_flag(.shared_f) && !g.inside_or_block {
3629+
ret_typ_is_shared := ret_type.has_flag(.shared_f)
3630+
if g.is_shared && !ret_typ_is_shared && !g.inside_or_block {
36303631
ret_sym := g.table.sym(ret_type)
36313632
shared_typ := if ret_type.is_ptr() {
36323633
ret_type.deref().set_flag(.shared_f)
@@ -3648,8 +3649,7 @@ fn (mut g Gen) expr(node_ ast.Expr) {
36483649
0
36493650
}
36503651

3651-
if g.is_shared && !ret_type.has_flag(.shared_f) && !g.inside_or_block
3652-
&& ret_type.is_ptr() {
3652+
if g.is_shared && !ret_typ_is_shared && !g.inside_or_block && ret_type.is_ptr() {
36533653
g.write('*'.repeat(ret_type.nr_muls()))
36543654
}
36553655
g.call_expr(node)
@@ -3665,7 +3665,7 @@ fn (mut g Gen) expr(node_ ast.Expr) {
36653665
}
36663666
g.strs_to_free0 = []
36673667
}
3668-
if g.is_shared && !ret_type.has_flag(.shared_f) && !g.inside_or_block {
3668+
if g.is_shared && !ret_typ_is_shared && !g.inside_or_block {
36693669
g.writeln('}, sizeof(${shared_styp}))')
36703670
}
36713671
/*
@@ -4524,10 +4524,10 @@ fn (mut g Gen) debugger_stmt(node ast.DebuggerStmt) {
45244524
cast_sym := g.table.sym(var_typ)
45254525

45264526
mut param_var := strings.new_builder(50)
4527+
is_option := obj.typ.has_flag(.option)
4528+
var_typ_is_option := var_typ.has_flag(.option)
45274529
if obj.smartcasts.len > 0 {
4528-
is_option_unwrap := obj.typ.has_flag(.option)
4529-
&& var_typ == obj.typ.clear_flag(.option)
4530-
is_option := obj.typ.has_flag(.option)
4530+
is_option_unwrap := is_option && var_typ == obj.typ.clear_flag(.option)
45314531
mut opt_cast := false
45324532
mut func := if cast_sym.info is ast.Aggregate {
45334533
''
@@ -4571,7 +4571,7 @@ fn (mut g Gen) debugger_stmt(node ast.DebuggerStmt) {
45714571
param_var.write_string('.data)')
45724572
}
45734573
param_var.write_string('${dot}_${cast_sym.cname}')
4574-
} else if obj.typ.has_flag(.option) && !var_typ.has_flag(.option) {
4574+
} else if is_option && !var_typ_is_option {
45754575
param_var.write_string('${obj.name}.data')
45764576
} else {
45774577
param_var.write_string('${obj.name}')
@@ -4581,15 +4581,15 @@ fn (mut g Gen) debugger_stmt(node ast.DebuggerStmt) {
45814581
values.write_string('${func}(${param_var.str()})}')
45824582
} else {
45834583
func := g.get_str_fn(var_typ)
4584-
if obj.typ.has_flag(.option) && !var_typ.has_flag(.option) {
4584+
if is_option && !var_typ_is_option {
45854585
// option unwrap
45864586
base_typ := g.base_type(obj.typ)
45874587
values.write_string('${func}(*(${base_typ}*)${obj.name}.data)}')
45884588
} else {
45894589
_, str_method_expects_ptr, _ := cast_sym.str_method_info()
45904590

45914591
// eprintln(">> ${obj.name} | str expects ptr? ${str_method_expects_ptr} | ptr? ${var_typ.is_ptr()} || auto heap? ${obj.is_auto_heap} | auto deref? ${obj.is_auto_deref}")
4592-
deref := if var_typ.has_flag(.option) {
4592+
deref := if var_typ_is_option {
45934593
''
45944594
} else if str_method_expects_ptr && !obj.typ.is_ptr() {
45954595
'&'
@@ -5355,26 +5355,27 @@ fn (mut g Gen) cast_expr(node ast.CastExpr) {
53555355
if g.comptime.is_comptime_expr(node.expr) {
53565356
expr_type = g.unwrap_generic(g.comptime.get_type(node.expr))
53575357
}
5358+
node_typ_is_option := node.typ.has_flag(.option)
53585359
if sym.kind in [.sum_type, .interface] {
5359-
if node.typ.has_flag(.option) && node.expr is ast.None {
5360+
if node_typ_is_option && node.expr is ast.None {
53605361
g.gen_option_error(node.typ, node.expr)
53615362
} else if node.expr is ast.Ident && g.comptime.is_comptime_variant_var(node.expr) {
53625363
g.expr_with_cast(node.expr, g.comptime.type_map['${g.comptime.comptime_for_variant_var}.typ'],
53635364
node_typ)
5364-
} else if node.typ.has_flag(.option) {
5365+
} else if node_typ_is_option {
53655366
g.expr_with_opt(node.expr, expr_type, node.typ)
53665367
} else {
53675368
g.expr_with_cast(node.expr, expr_type, node_typ)
53685369
}
5369-
} else if !node.typ.has_flag(.option) && !node.typ.is_ptr() && sym.info is ast.Struct
5370+
} else if !node_typ_is_option && !node.typ.is_ptr() && sym.info is ast.Struct
53705371
&& !sym.info.is_typedef {
53715372
// deprecated, replaced by Struct{...exr}
53725373
styp := g.styp(node.typ)
53735374
g.write('*((${styp} *)(&')
53745375
g.expr(node.expr)
53755376
g.write('))')
53765377
} else if sym.kind == .alias && g.table.final_sym(node.typ).kind == .array_fixed {
5377-
if node.typ.has_flag(.option) {
5378+
if node_typ_is_option {
53785379
g.expr_with_opt(node.expr, expr_type, node.typ)
53795380
} else {
53805381
if node.expr is ast.ArrayInit && g.assign_op != .decl_assign {
@@ -5409,9 +5410,9 @@ fn (mut g Gen) cast_expr(node ast.CastExpr) {
54095410
cast_label = '(${styp})'
54105411
}
54115412
}
5412-
if node.typ.has_flag(.option) && node.expr is ast.None {
5413+
if node_typ_is_option && node.expr is ast.None {
54135414
g.gen_option_error(node.typ, node.expr)
5414-
} else if node.typ.has_flag(.option) {
5415+
} else if node_typ_is_option {
54155416
if sym.info is ast.Alias {
54165417
if sym.info.parent_type.has_flag(.option) {
54175418
cur_stmt := g.go_before_last_stmt()
@@ -6893,13 +6894,13 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast
68936894
} else {
68946895
mut is_array_fixed := false
68956896
mut return_wrapped := false
6897+
mut return_is_option := is_option && return_type.has_option_or_result()
68966898
if is_option {
68976899
is_array_fixed = g.table.final_sym(return_type).kind == .array_fixed
68986900
if !is_array_fixed {
68996901
if g.inside_return && !g.inside_struct_init
69006902
&& expr_stmt.expr is ast.CallExpr&& (expr_stmt.expr as ast.CallExpr).return_type.has_option_or_result()
6901-
&& g.cur_fn.return_type.has_option_or_result()
6902-
&& return_type.has_option_or_result()
6903+
&& g.cur_fn.return_type.has_option_or_result() && return_is_option
69036904
&& expr_stmt.expr.or_block.kind == .absent {
69046905
g.write('${cvar_name} = ')
69056906
return_wrapped = true
@@ -6919,7 +6920,7 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast
69196920
}
69206921
// return expr or { fn_returns_option() }
69216922
if is_option && g.inside_return && expr_stmt.expr is ast.CallExpr
6922-
&& return_type.has_option_or_result() {
6923+
&& return_is_option {
69236924
g.expr_with_cast(expr_stmt.expr, expr_stmt.typ, return_type)
69246925
} else {
69256926
old_inside_opt_data := g.inside_opt_data

vlib/v/gen/c/fn.v

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2260,7 +2260,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
22602260
g.writeln('));')
22612261
return
22622262
}
2263-
if g.is_autofree && !typ.has_flag(.option) && !typ.has_flag(.result) {
2263+
if g.is_autofree && !typ.has_option_or_result() {
22642264
// Create a temporary variable so that the value can be freed
22652265
tmp := g.new_tmp_var()
22662266
g.write('string ${tmp} = ')
@@ -2459,8 +2459,7 @@ fn (mut g Gen) autofree_call_pregen(node ast.CallExpr) {
24592459
// Create a temporary var before fn call for each argument in order to free it (only if it's a complex expression,
24602460
// like `foo(get_string())` or `foo(a + b)`
24612461
mut free_tmp_arg_vars := g.is_autofree && !g.is_builtin_mod && node.args.len > 0
2462-
&& !node.args[0].typ.has_flag(.option)
2463-
&& !node.args[0].typ.has_flag(.result) // TODO: copy pasta checker.v
2462+
&& !node.args[0].typ.has_option_or_result() // TODO: copy pasta checker.v
24642463
if !free_tmp_arg_vars {
24652464
return
24662465
}

vlib/v/gen/c/for.v

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,14 +234,15 @@ fn (mut g Gen) for_in_stmt(node_ ast.ForInStmt) {
234234
node.cond_type = node.val_type
235235
}
236236
mut cond_var := ''
237-
if (node.cond is ast.Ident && !node.cond_type.has_flag(.option))
237+
cond_is_option := node.cond_type.has_flag(.option)
238+
if (node.cond is ast.Ident && !cond_is_option)
238239
|| (node.cond is ast.SelectorExpr && node.cond.or_block.kind == .absent) {
239240
cond_var = g.expr_string(node.cond)
240241
} else {
241242
cond_var = g.new_tmp_var()
242243
g.write2(g.styp(node.cond_type), ' ${cond_var} = ')
243244
old_inside_opt_or_res := g.inside_opt_or_res
244-
if node.cond_type.has_flag(.option) {
245+
if cond_is_option {
245246
g.inside_opt_or_res = true
246247
}
247248
g.expr(node.cond)
@@ -251,7 +252,7 @@ fn (mut g Gen) for_in_stmt(node_ ast.ForInStmt) {
251252
i := if node.key_var in ['', '_'] { g.new_tmp_var() } else { node.key_var }
252253
g.empty_line = true
253254
opt_expr := '(*(${g.styp(node.cond_type.clear_flag(.option))}*)${cond_var}${op_field}data)'
254-
cond_expr := if node.cond_type.has_flag(.option) {
255+
cond_expr := if cond_is_option {
255256
'${opt_expr}${op_field}len'
256257
} else {
257258
'${cond_var}${op_field}len'
@@ -274,7 +275,7 @@ fn (mut g Gen) for_in_stmt(node_ ast.ForInStmt) {
274275
// instead of
275276
// `int* val = ((int**)arr.data)[i];`
276277
// right := if node.val_is_mut { styp } else { styp + '*' }
277-
right := if node.cond_type.has_flag(.option) {
278+
right := if cond_is_option {
278279
'((${styp}*)${opt_expr}${op_field}data)[${i}]'
279280
} else if node.val_is_mut || node.val_is_ref {
280281
'((${styp})${cond_var}${op_field}data) + ${i}'

0 commit comments

Comments
 (0)