- Notifications
You must be signed in to change notification settings - Fork 13.8k
Closed
Labels
T-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.
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)
scottmcm
Metadata
Metadata
Assignees
Labels
T-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.