-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Miri -Zmiri-retag-fields
libstd test failure inside VecDeque::drain
#99701
Comments
use std::collections::VecDeque;
fn main() {
let mut tester: VecDeque<usize> = VecDeque::with_capacity(3);
for i in 0..3 {
tester.push_back(i);
}
let _: VecDeque<_> = tester.drain(1..2).collect();
} And here's a minimal example. |
Okay, thinking out loud as to what the problem is. I'm being told that I can't do this copy, because some allocation that was created, is protected. It's the drop in the But okay. Does that imply that for as long as you're inside the I looked up stacked borrows and got https://www.ralfj.de/blog/2019/04/30/stacked-borrows-2.html (well, I got the github, which linked to 2.1, but then that doesn't say anything about protectors so I went to this page). when it says Apologies for the ramble but I'm both tired and I don't understand stacked borrows and I figured trying to explain the thought process of someone who doesn't understand stacked borrows, trying to debug a stacked borrows issue, would be in some way useful. |
I never gave the protector errors much love because they're relatively rare to encounter. In general, if you're asking "is that information we have" the answer is yes. I'm wary of writing an error code library with suggestions for Miri because I think the effort there scales relatively poorly. That's why I've focused on surfacing more information in the diagnostics (which as you point out, is notably absent here). Protector errors appear when you attempt to remove or disable a tag which is protected, because it is part of a function argument. Reads disable Unique tags, so this isn't a read. Writes remove ~everything above the granting tag, so since we're removing a SharedReadOnly tag this seems like a write access. If reborrows and use thereof form a neat stack, you can't run into a protector error. So the problem here is that we're trying to write using a tag which is below the FnEntry retag which occurs due to passing the iterator as an argument. The fix, if it is possible, would involve deriving our write access from the iterator, after the function call in question. If it interests you, I have a branch which tries to centralize the Stacked Borrows information a bit more and thus make it easier to make richer diagnostics: https://github.com/saethlin/miri/tree/diagnostics-cleanup There's just a lot of other things I want to do so I haven't finished it yet |
We debugged this in the community Discord. The problem is that rust/library/alloc/src/collections/vec_deque/drain.rs Lines 16 to 25 in 3ae03e0
wraps VecDeque 's Iter type: rust/library/alloc/src/collections/vec_deque/iter.rs Lines 15 to 19 in 3ae03e0
But this iterator needs to mutate the |
That means the fix should fairly simple to use |
The rust/library/alloc/src/vec/drain.rs Lines 160 to 169 in 2f320a2
but VecDeque wasn't updated to match. Well, that and the respective |
yes but also Drain needs to be covariant, and just putting an IterMut in it would make it invariant. So I'm thinking an internal |
Is this a duplicate of #60076? |
Looks to be, yes. I'll close this and copy paste my smaller reproduction to that issue |
Using https://github.com/rust-lang/miri-test-libstd, running
MIRIFLAGS="-Zmiri-retag-fields" ./run-test.sh alloc --all-targets collections::vec_deque::tests::test_drain
, I getThe test is a bit large, will try and shrink this down, but figured I'd make the issue now. I can reproduce this by copy pasting the test into a normal rust file.
The text was updated successfully, but these errors were encountered: