From 115edff7e9817d9dea881b86106ba8698a6644d6 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Wed, 9 Jun 2021 12:05:46 +0300 Subject: [PATCH] v.checker: restrict `x T` in `fn test(x T){ unsafe{ println(x[0]) }`, but allow `x &T` --- vlib/v/checker/checker.v | 8 +++++++- .../tests/generic_param_used_as_an_array_err.out | 6 ++++++ .../tests/generic_param_used_as_an_array_err.vv | 12 ++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 vlib/v/checker/tests/generic_param_used_as_an_array_err.out create mode 100644 vlib/v/checker/tests/generic_param_used_as_an_array_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 8567d3f694..54beed80e0 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -6510,10 +6510,16 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type { break } .any { + gname := typ_sym.name typ = c.unwrap_generic(typ) node.left_type = typ typ_sym = c.table.get_final_type_symbol(typ) - continue + if typ.is_ptr() { + continue + } else { + c.error('generic type $gname does not support indexing, pass an array, or a reference instead, e.g. []$gname or &$gname', + node.pos) + } } else { break diff --git a/vlib/v/checker/tests/generic_param_used_as_an_array_err.out b/vlib/v/checker/tests/generic_param_used_as_an_array_err.out new file mode 100644 index 0000000000..eb4ee7cbe8 --- /dev/null +++ b/vlib/v/checker/tests/generic_param_used_as_an_array_err.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/generic_param_used_as_an_array_err.vv:2:10: error: generic type T does not support indexing, pass an array, or a reference instead, e.g. []T or &T + 1 | fn test(arr T) { + 2 | a := arr[1] + | ~~~ + 3 | println(a) + 4 | } diff --git a/vlib/v/checker/tests/generic_param_used_as_an_array_err.vv b/vlib/v/checker/tests/generic_param_used_as_an_array_err.vv new file mode 100644 index 0000000000..f545b77147 --- /dev/null +++ b/vlib/v/checker/tests/generic_param_used_as_an_array_err.vv @@ -0,0 +1,12 @@ +fn test(arr T) { + a := arr[1] + println(a) +} + +fn main() { + a := [1, 2, 3]! + test(a) + + b := ['a', 'b', 'c']! + test(b) +}