v2 / vlib / v / checker / postfix.v
59 lines · 56 sloc · 2.14 KB · 8f42f04a125e0256f2831272cb72aacf72748142
Raw
1module checker
2
3import v.ast
4
5fn (mut c Checker) postfix_expr(mut node ast.PostfixExpr) ast.Type {
6 typ := c.unwrap_generic(c.type_resolver.get_type_or_default(node, c.expr(mut node.expr)))
7 typ_sym := c.table.sym(typ)
8 is_non_void_pointer := typ.is_any_kind_of_pointer() && !typ.has_flag(.shared_f)
9 && typ_sym.kind != .voidptr
10 mut unwrapped_question_type := c.unwrap_generic(c.type_resolver.get_type(node.expr))
11 if unwrapped_question_type != 0 && c.table.sym(unwrapped_question_type).kind == .alias {
12 unaliased_question_type := c.table.unaliased_type(unwrapped_question_type)
13 if unaliased_question_type.has_option_or_result() {
14 unwrapped_question_type = c.unwrap_generic(unaliased_question_type)
15 }
16 }
17 unwrapped_question_type = unwrapped_question_type.clear_option_and_result()
18
19 if node.op in [.inc, .dec] && !node.expr.is_lvalue() {
20 op_kind, bin_op_alt := if node.op == .inc { 'increment', '+' } else { 'decrement', '-' }
21 c.add_error_detail('try rewrite this as `${node.expr} ${bin_op_alt} 1`')
22 c.error('cannot ${op_kind} `${node.expr}` because it is non lvalue expression',
23 node.expr.pos())
24 }
25 if node.op != .question && !c.inside_unsafe && is_non_void_pointer
26 && !node.expr.is_auto_deref_var() {
27 if !c.pref.translated && !c.file.is_translated {
28 c.warn('pointer arithmetic is only allowed in `unsafe` blocks', node.pos)
29 }
30 }
31 if !(typ_sym.is_number() || ((c.inside_unsafe || c.pref.translated) && is_non_void_pointer)) {
32 if c.comptime.comptime_for_field_var != '' {
33 if c.comptime.is_comptime(node.expr) || node.expr is ast.ComptimeSelector {
34 node.typ = if node.op == .question {
35 unwrapped_question_type
36 } else {
37 c.unwrap_generic(c.type_resolver.get_type(node.expr))
38 }
39 return node.typ
40 }
41 }
42 if node.op != .question {
43 typ_str := c.table.type_to_str(typ)
44 c.error('invalid operation: ${node.op.str()} (non-numeric type `${typ_str}`)', node.pos)
45 } else {
46 node.typ = unwrapped_question_type
47 return node.typ
48 }
49 } else {
50 if node.op != .question {
51 node.auto_locked, _ = c.fail_if_immutable(mut node.expr)
52 } else {
53 node.typ = unwrapped_question_type
54 return node.typ
55 }
56 }
57 node.typ = typ
58 return typ
59}
60