Closed as not planned
Description
I'm working on a statically allocated MPSC queue for embedded systems, and I've run into a miri issue. From my understanding of stacked borrows, reading from a mutable reference shouldn't pop from the stack. However, in my case the stack is popped when creating the reference, but only in some cases.
I've created a minimal example shown below.
Shared code:
use std::sync::atomic::{AtomicBool, Ordering};
struct Queue {
field: AtomicBool,
}
impl Queue {
fn new() -> Self {
Self {
field: AtomicBool::new(false),
}
}
unsafe fn get_sender(&self) -> Sender {
let this = &*(self as *const Self);
Sender::new(&this.field)
}
fn recv(&mut self) {
self.field.store(true, Ordering::Relaxed);
}
fn ref_mut(&mut self) -> &mut Self {
self
}
}
struct Sender {
field: &'static AtomicBool,
}
impl Sender {
fn new(field: &'static AtomicBool) -> Self {
Self { field }
}
fn send(&self) {
self.field.store(true, Ordering::Relaxed);
}
}
This is fine:
fn main() {
let mut queue = Queue::new();
let sender = unsafe { queue.get_sender() };
queue.recv();
sender.send();
}
And this is also fine:
fn main() {
let mut queue = Queue::new();
let sender = unsafe { queue.get_sender() };
let queue = queue.ref_mut();
queue.recv();
sender.send();
}
But this is not:
fn main() {
let mut queue = Queue::new();
let sender = unsafe { queue.get_sender() };
let queue = &mut queue;
queue.recv();
sender.send();
}
Error (with tag tracking):
note: tracking was triggered
--> src/main.rs:35:16
|
35 | Self { field }
| ^^^^^ created tag 2411
|
= note: inside `Sender::new` at src/main.rs:35:16
note: inside `Queue::get_sender` at src/main.rs:17:9
--> src/main.rs:17:9
|
17 | Sender::new(&this.field)
| ^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `main` at src/main.rs:46:27
--> src/main.rs:46:27
|
46 | let sender = unsafe { queue.get_sender() };
| ^^^^^^^^^^^^^^^^^^
note: tracking was triggered
--> src/main.rs:48:17
|
48 | let queue = &mut queue;
| ^^^^^^^^^^ popped tracked tag for item [SharedReadWrite for <2411>] due to Write access for <2392>
|
= note: inside `main` at src/main.rs:48:17
error: Undefined Behavior: trying to reborrow <2411> for SharedReadWrite permission at alloc1283[0x0], but that tag does not exist in the borrow stack for this location
--> src/main.rs:39:9
|
39 | self.field.store(true, Ordering::Relaxed);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| trying to reborrow <2411> for SharedReadWrite permission at alloc1283[0x0], but that tag does not exist in the borrow stack for this location
| this error occurs as part of a reborrow at alloc1283[0x0..0x1]
|
= 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
= note: inside `Sender::send` at src/main.rs:39:9
note: inside `main` at src/main.rs:52:5
--> src/main.rs:52:5
|
52 | sender.send();
| ^^^^^^^^^^^^^
Metadata
Metadata
Assignees
Labels
No labels