| 1 | // Regression test for https://github.com/vlang/v/issues/27507 |
| 2 | // `array.slice()` marks the source buffer's data header (`has_slices`) so a later |
| 3 | // grow/delete of the parent does copy-on-grow instead of mutating a buffer that a |
| 4 | // live slice still references. The marking was made cheaper (inlined header lookup, |
| 5 | // store only when not already set); this test guards that the behavior is unchanged. |
| 6 | |
| 7 | fn test_live_slice_survives_parent_grow() { |
| 8 | mut a := [1, 2, 3, 4, 5] |
| 9 | s := a[1..4] |
| 10 | assert s == [2, 3, 4] |
| 11 | // growing the parent must copy, leaving the slice intact |
| 12 | for i in 0 .. 200 { |
| 13 | a << i |
| 14 | } |
| 15 | a[2] = 999 |
| 16 | assert s == [2, 3, 4] |
| 17 | } |
| 18 | |
| 19 | fn test_repeated_transient_slices_of_same_buffer() { |
| 20 | mut buf := []u8{len: 0, cap: 256} |
| 21 | for i in 0 .. 256 { |
| 22 | buf << u8(i) |
| 23 | } |
| 24 | mut acc := u64(0) |
| 25 | for _ in 0 .. 10000 { |
| 26 | w := buf[8..buf.len] // read-only window, dropped immediately |
| 27 | for b in w { |
| 28 | acc += b |
| 29 | } |
| 30 | } |
| 31 | // 10000 iterations * sum(8..256) |
| 32 | mut one := u64(0) |
| 33 | for j := 8; j < 256; j++ { |
| 34 | one += u64(j) |
| 35 | } |
| 36 | assert acc == one * 10000 |
| 37 | } |
| 38 | |
| 39 | fn test_slice_of_slice() { |
| 40 | a := [10, 20, 30, 40, 50] |
| 41 | s := a[1..5] // [20,30,40,50] |
| 42 | b := s[1..3] // [30,40] |
| 43 | assert b == [30, 40] |
| 44 | } |
| 45 | |