Closed
Description
Description
fn main() {
let mut arr1 = [0u8; 64];
let arr2 = [0u8; 64];
let mut iter = arr1.chunks_mut(8).zip(arr2.chunks(8));
while let Some((chunk1, chunk2)) = iter.next() {
dbg!(chunk2[0]);
dbg!(chunk1[0]);
iter.next();
dbg!(chunk2[0]);
dbg!(chunk1[0]); // error here
}
}
Running this code in Miri will produce the following output:
[src\main.rs:6] chunk2[0] = 0
[src\main.rs:7] chunk1[0] = 0
[src\main.rs:9] chunk2[0] = 0
error: Undefined Behavior: no item granting read access to tag <1832> at alloc906 found in borrow stack.
--> src\main.rs:10:9
|
10 | dbg!(chunk1[0]); // error here
| ^^^^^^^^^^^^^^^ no item granting read access to tag <1832> at alloc906 found in borrow stack.
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
With -Zmiri-track-pointer-tag=1832,1585,12319
-Zmiri-track-pointer-tag=1832,1585,12319
note: tracking was triggered
--> \library\core\src\slice\iter.rs:1564:19
|
1564 | Self { v: slice, chunk_size: size }
| ^^^^^ created tag 1585
|
= note: inside `std::slice::ChunksMut::<u8>::new` at \library\core\src\slice\iter.rs:1564:19
= note: inside `core::slice::<impl [u8]>::chunks_mut` at \library\core\src\slice\mod.rs:828:9
note: inside `main` at src\main.rs:4:20
--> src\main.rs:4:20
|
4 | let mut iter = arr1.chunks_mut(8).zip(arr2.chunks(8));
| ^^^^^^^^^^^^^^^^^^
note: tracking was triggered
--> src\main.rs:5:21
|
5 | while let Some((chunk1, chunk2)) = iter.next() {
| ^^^^^^ created tag 1832
|
= note: inside `main` at src\main.rs:5:21
[src\main.rs:6] chunk2[0] = 0
[src\main.rs:7] chunk1[0] = 0
note: tracking was triggered
--> \library\core\src\slice\iter.rs:1641:32
|
1641 | let len = cmp::min(self.v.len().unchecked_sub(start), self.chunk_size);
| ^^^^^^^^^^^^ popped tracked tag for item [Unique for <1832>] due to Read access for <1585>
|
= note: inside `<std::slice::ChunksMut<u8> as std::iter::Iterator>::__iterator_get_unchecked` at \library\core\src\slice\iter.rs:1641:32
= note: inside `<std::iter::Zip<std::slice::ChunksMut<u8>, std::slice::Chunks<u8>> as std::iter::adapters::zip::ZipImpl<std::slice::ChunksMut<u8>, std::slice::Chunks<u8>>>::next` at \library\core\src\iter\adapters\zip.rs:278:23
= note: inside `<std::iter::Zip<std::slice::ChunksMut<u8>, std::slice::Chunks<u8>> as std::iter::Iterator>::next` at \library\core\src\iter\adapters\zip.rs:84:9
--> \library\core\src\slice\iter.rs:1642:32
|
1642 | from_raw_parts_mut(self.v.as_mut_ptr().add(start), len)
| ^^^^^^^^^^^^^^^^^^^ created tag 12319
|
= note: inside `<std::slice::ChunksMut<u8> as std::iter::Iterator>::__iterator_get_unchecked` at \library\core\src\slice\iter.rs:1642:32
--> \library\core\src\slice\mod.rs:483:5
|
483 | / pub const fn as_mut_ptr(&mut self) -> *mut T {
484 | | self as *mut [T] as *mut T
485 | | }
| |_____^ popped tracked tag for item [Disabled for <1832>] due to Write access for <12319>
|
= note: inside `core::slice::<impl [u8]>::as_mut_ptr` at \library\core\src\slice\mod.rs:483:5
= note: inside `<std::slice::ChunksMut<u8> as std::iter::Iterator>::__iterator_get_unchecked` at \library\core\src\slice\iter.rs:1642:32
note: inside `main` at src\main.rs:8:9
--> src\main.rs:8:9
|
8 | iter.next();
| ^^^^^^^^^^^
= note
[src\main.rs:9] chunk2[0] = 0
error: Undefined Behavior: no item granting read access to tag <1832> at alloc906 found in borrow stack.
--> src\main.rs:10:9
|
10 | dbg!(chunk1[0]); // error here
| ^^^^^^^^^^^^^^^ no item granting read access to tag <1832> at alloc906 found in borrow stack.
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
A few things to note here:
- Access to the mutable chunk will fail. For example
arr1.chunks(8).zip(arr2.chunks_mut(8))
will fail onchunk2[0]
instead. zip()
is required. This is probably due toZip
uses__iterator_get_unchecked()
internally rather thannext()
.chunks_mut()
andchunks_exact_mut()
can both reproduce.array_chunks_mut()
can't reproduce.
Environment
$ rustc --version --verbose
rustc 1.61.0-nightly (45e2c2881 2022-02-20)
binary: rustc
commit-hash: 45e2c2881d11324d610815bfff097e25c412199e
commit-date: 2022-02-20
host: x86_64-pc-windows-msvc
release: 1.61.0-nightly
LLVM version: 14.0.0
$ cargo miri --version
miri 0.1.0 (0db4090 2022-02-12)