diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 01a118ec16..b7c7584f88 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3835,10 +3835,15 @@ fn (mut c Checker) check_index_type(typ_sym &table.TypeSymbol, index_type table. // println('index expr left=$typ_sym.source_name $node.pos.line_nr') // if typ_sym.kind == .array && (!(table.type_idx(index_type) in table.number_type_idxs) && // index_type_sym.kind != .enum_) { - if typ_sym.kind in [.array, .array_fixed] && !(index_type.is_number() || index_type_sym.kind == - .enum_) { - c.error('non-integer index `$index_type_sym.source_name` (array type `$typ_sym.source_name`)', - pos) + if typ_sym.kind in [.array, .array_fixed, .string, .ustring] { + if !(index_type.is_number() || index_type_sym.kind == .enum_) { + type_str := if typ_sym.kind in [.string, .ustring] { 'non-integer string index `$index_type_sym.source_name`' } else { 'non-integer index `$index_type_sym.source_name` (array type `$typ_sym.source_name`)' } + c.error('$type_str', pos) + } + if index_type.has_flag(.optional) { + type_str := if typ_sym.kind in [.string, .ustring] { '(type `$typ_sym.source_name`)' } else { '(array type `$typ_sym.source_name`)' } + c.error('cannot use optional as index $type_str', pos) + } } } diff --git a/vlib/v/checker/tests/optional_index_err.out b/vlib/v/checker/tests/optional_index_err.out new file mode 100644 index 0000000000..ba5f4abdd8 --- /dev/null +++ b/vlib/v/checker/tests/optional_index_err.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/optional_index_err.vv:3:14: error: cannot use optional as index (type `string`) + 1 | fn main() { + 2 | v := 'hello' + 3 | println(v[v.last_index('l')]) + | ~~~~~~~~~~~~~~~~~~~ + 4 | } diff --git a/vlib/v/checker/tests/optional_index_err.vv b/vlib/v/checker/tests/optional_index_err.vv new file mode 100644 index 0000000000..e34bc6f66a --- /dev/null +++ b/vlib/v/checker/tests/optional_index_err.vv @@ -0,0 +1,4 @@ +fn main() { + v := 'hello' + println(v[v.last_index('l')]) +} diff --git a/vlib/v/checker/tests/string_index_non_int_err.out b/vlib/v/checker/tests/string_index_non_int_err.out new file mode 100644 index 0000000000..449e73f13a --- /dev/null +++ b/vlib/v/checker/tests/string_index_non_int_err.out @@ -0,0 +1,20 @@ +vlib/v/checker/tests/string_index_non_int_err.vv:3:14: error: non-integer string index `string` + 1 | fn main() { + 2 | v := 'foo' + 3 | println(v['f']) + | ~~~~~ + 4 | println(v[true]) + 5 | println(v[[23]]) +vlib/v/checker/tests/string_index_non_int_err.vv:4:14: error: non-integer string index `bool` + 2 | v := 'foo' + 3 | println(v['f']) + 4 | println(v[true]) + | ~~~~~~ + 5 | println(v[[23]]) + 6 | } +vlib/v/checker/tests/string_index_non_int_err.vv:5:14: error: non-integer string index `[]int` + 3 | println(v['f']) + 4 | println(v[true]) + 5 | println(v[[23]]) + | ~~~~~~ + 6 | } diff --git a/vlib/v/checker/tests/string_index_non_int_err.vv b/vlib/v/checker/tests/string_index_non_int_err.vv new file mode 100644 index 0000000000..6619e471ca --- /dev/null +++ b/vlib/v/checker/tests/string_index_non_int_err.vv @@ -0,0 +1,6 @@ +fn main() { + v := 'foo' + println(v['f']) + println(v[true]) + println(v[[23]]) +}