From 06764bc5594750349ef259e905f8b45be09d480e Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Sun, 20 Nov 2022 01:33:39 +0530 Subject: [PATCH] checker: disallow taking address of optional fields for now (#16487) --- vlib/v/checker/checker.v | 8 ++++++-- vlib/v/checker/tests/optional_fields_addr_err.out | 13 +++++++++++++ vlib/v/checker/tests/optional_fields_addr_err.vv | 13 +++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 vlib/v/checker/tests/optional_fields_addr_err.out create mode 100644 vlib/v/checker/tests/optional_fields_addr_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index bad0d16d0f..19aaa49b51 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3544,9 +3544,13 @@ pub fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) ast.Type { && (node.right.typ == ast.bool_type_idx || (right_sym.kind == .enum_ && !(right_sym.info as ast.Enum).is_flag && !(right_sym.info as ast.Enum).uses_exprs)) { - c.error('cannot take address of field in struct `${c.table.type_to_str(node.right.expr_type)}`, which is tagged as `[minify]`', + c.error('cannot take the address of field in struct `${c.table.type_to_str(node.right.expr_type)}`, which is tagged as `[minify]`', node.pos.extend(node.right.pos)) } + + if node.right.typ.has_flag(.optional) { + c.error('cannot take the address of an optional field', node.pos.extend(node.right.pos)) + } } } // TODO: testing ref/deref strategy @@ -3562,7 +3566,7 @@ pub fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) ast.Type { } if mut node.right is ast.Ident { if node.right.kind == .constant && !c.inside_unsafe && c.pref.experimental { - c.warn('cannot take an address of const outside `unsafe`', node.right.pos) + c.warn('cannot take the address of const outside `unsafe`', node.right.pos) } } if node.right is ast.SelectorExpr { diff --git a/vlib/v/checker/tests/optional_fields_addr_err.out b/vlib/v/checker/tests/optional_fields_addr_err.out new file mode 100644 index 0000000000..f41665ffee --- /dev/null +++ b/vlib/v/checker/tests/optional_fields_addr_err.out @@ -0,0 +1,13 @@ +vlib/v/checker/tests/optional_fields_addr_err.vv:9:10: error: cannot take the address of an optional field + 7 | fn main() { + 8 | x := Wrapper{} + 9 | if _ := &x.value { + | ~~~~~~~~ + 10 | } + 11 | +vlib/v/checker/tests/optional_fields_addr_err.vv:12:7: error: cannot take the address of an optional field + 10 | } + 11 | + 12 | _ := &x.value + | ~~~~~~~~ + 13 | } diff --git a/vlib/v/checker/tests/optional_fields_addr_err.vv b/vlib/v/checker/tests/optional_fields_addr_err.vv new file mode 100644 index 0000000000..0fcbe08f51 --- /dev/null +++ b/vlib/v/checker/tests/optional_fields_addr_err.vv @@ -0,0 +1,13 @@ +module main + +struct Wrapper { + value ?u8 +} + +fn main() { + x := Wrapper{} + if _ := &x.value { + } + + _ := &x.value +}