diff --git a/vlib/strings/builder.c.v b/vlib/strings/builder.c.v index ce0d0cf7bc..5271d46c8c 100644 --- a/vlib/strings/builder.c.v +++ b/vlib/strings/builder.c.v @@ -106,7 +106,7 @@ pub fn (mut b Builder) go_back(n int) { // cut_last cuts the last `n` bytes from the buffer and returns them pub fn (mut b Builder) cut_last(n int) string { cut_pos := b.len - n - x := unsafe { (&[]byte(b))[cut_pos..] } + x := unsafe { (*&[]byte(b))[cut_pos..] } res := x.bytestr() b.trim(cut_pos) return res @@ -147,7 +147,7 @@ pub fn (b &Builder) last_n(n int) string { if n > b.len { return '' } - x := unsafe { (&[]byte(b))[b.len - n..] } + x := unsafe { (*&[]byte(b))[b.len - n..] } return x.bytestr() } @@ -157,7 +157,7 @@ pub fn (b &Builder) after(n int) string { if n >= b.len { return '' } - x := unsafe { (&[]byte(b))[n..] } + x := unsafe { (*&[]byte(b))[n..] } return x.bytestr() } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 82bd9a2684..ccbb01337f 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3770,8 +3770,8 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type { '(note, that variables may be mutable but string values are always immutable, like in Go and Java)', node.pos) } - if !c.inside_unsafe && ((typ.is_ptr() && !typ.has_flag(.shared_f) - && !node.left.is_auto_deref_var()) || typ.is_pointer()) { + if (typ.is_ptr() && !typ.has_flag(.shared_f) && !node.left.is_auto_deref_var()) + || typ.is_pointer() { mut is_ok := false if mut node.left is ast.Ident { if mut node.left.obj is ast.Var { @@ -3779,7 +3779,10 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type { is_ok = node.left.obj.is_mut && node.left.obj.is_arg && !typ.deref().is_ptr() } } - if !is_ok && !c.pref.translated && !c.file.is_translated { + if !is_ok && node.index is ast.RangeExpr { + s := c.table.type_to_str(typ) + c.error('type `$s` does not support slicing', node.pos) + } else if !c.inside_unsafe && !is_ok && !c.pref.translated && !c.file.is_translated { c.warn('pointer indexing is only allowed in `unsafe` blocks', node.pos) } } diff --git a/vlib/v/checker/tests/ptr_slice.out b/vlib/v/checker/tests/ptr_slice.out new file mode 100644 index 0000000000..c8de2792a9 --- /dev/null +++ b/vlib/v/checker/tests/ptr_slice.out @@ -0,0 +1,14 @@ +vlib/v/checker/tests/ptr_slice.vv:9:17: error: type `&Foo` does not support slicing + 7 | + 8 | fn main() { + 9 | fs := jeje()[1..] + | ~~~~~ + 10 | println(fs) + 11 | vs := byteptr(0)[..3] +vlib/v/checker/tests/ptr_slice.vv:11:21: error: type `byteptr` does not support slicing + 9 | fs := jeje()[1..] + 10 | println(fs) + 11 | vs := byteptr(0)[..3] + | ~~~~~ + 12 | println(vs) + 13 | } diff --git a/vlib/v/checker/tests/ptr_slice.vv b/vlib/v/checker/tests/ptr_slice.vv new file mode 100644 index 0000000000..2249ab9039 --- /dev/null +++ b/vlib/v/checker/tests/ptr_slice.vv @@ -0,0 +1,13 @@ +struct Foo { +} + +fn jeje() &Foo { + return &Foo{} +} + +fn main() { + fs := jeje()[1..] + println(fs) + vs := byteptr(0)[..3] + println(vs) +}