Skip to content

Commit

Permalink
checker: add infix checks for nil (#22045)
Browse files Browse the repository at this point in the history
  • Loading branch information
Delta456 authored Aug 18, 2024
1 parent acf04a2 commit ceac4ba
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 0 deletions.
34 changes: 34 additions & 0 deletions vlib/v/checker/infix.v
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,37 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
}
}
}

// Do not allow comparing nil to non-pointers
if node.left.is_nil() {
mut final_type := right_type
if mut right_sym.info is ast.Alias
&& right_sym.info.parent_type.is_any_kind_of_pointer() {
final_type = right_sym.info.parent_type
}
if !final_type.is_any_kind_of_pointer() && (right_final_sym.kind != .function
|| (right_final_sym.language != .c && right_final_sym.kind == .placeholder))
&& !right_final_sym.is_heap() {
rt := c.table.sym(right_type).name
c.error('cannot compare with `nil` because `${rt}` is not a pointer',
node.pos)
}
}

if node.right.is_nil() {
mut final_type := left_type
if mut left_sym.info is ast.Alias
&& left_sym.info.parent_type.is_any_kind_of_pointer() {
final_type = left_sym.info.parent_type
}
if !final_type.is_any_kind_of_pointer() && (left_final_sym.kind != .function
|| (left_final_sym.language != .c && left_final_sym.kind == .placeholder))
&& !left_final_sym.is_heap() {
lt := c.table.sym(left_type).name
c.error('cannot compare with `nil` because `${lt}` is not a pointer',
node.pos)
}
}
}
.key_in, .not_in {
match right_final_sym.kind {
Expand Down Expand Up @@ -542,6 +573,9 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
c.error('unwrapped Option cannot be compared in an infix expression',
opt_comp_pos)
}
if node.left.is_nil() || node.right.is_nil() {
c.error('cannot use `${node.op.str()}` with `nil`', node.pos)
}
}
.key_like {
node.promoted_type = ast.bool_type
Expand Down
14 changes: 14 additions & 0 deletions vlib/v/checker/tests/nil_compare_err.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
vlib/v/checker/tests/nil_compare_err.vv:3:6: error: cannot compare with `nil` because `[]int` is not a pointer
1 | a := [12, 34, 56]
2 |
3 | if a != unsafe { nil } {
| ~~
4 | println(a)
5 | }
vlib/v/checker/tests/nil_compare_err.vv:7:7: error: cannot use `>` with `nil`
5 | }
6 |
7 | if 23 > unsafe { nil } {
| ^
8 | println('hey')
9 | }
9 changes: 9 additions & 0 deletions vlib/v/checker/tests/nil_compare_err.vv
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
a := [12, 34, 56]

if a != unsafe { nil } {
println(a)
}

if 23 > unsafe { nil } {
println('hey')
}

0 comments on commit ceac4ba

Please sign in to comment.