From 84d3741a47aed43c31349c650d6e21605588e089 Mon Sep 17 00:00:00 2001 From: Ranjit Jhala Date: Fri, 22 Nov 2024 17:54:32 -0800 Subject: [PATCH] more push/scope/mysteries --- tests/tests/todo/issue-899c.rs | 58 ++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 tests/tests/todo/issue-899c.rs diff --git a/tests/tests/todo/issue-899c.rs b/tests/tests/todo/issue-899c.rs new file mode 100644 index 0000000000..8475c2dee1 --- /dev/null +++ b/tests/tests/todo/issue-899c.rs @@ -0,0 +1,58 @@ +use core::slice::{Iter, SliceIndex}; + + +pub trait Queue { + /// Returns true if the queue is full, false otherwise. + fn is_full(&self) -> bool; + + /// If the queue isn't full, add a new element to the back of the queue. + /// Returns whether the element was added. + #[flux_rs::sig(fn(self: &strg Self, _) -> bool ensures self: Self)] + fn enqueue(&mut self, val: T) -> bool; +} + + +#[flux_rs::extern_spec] +impl [T] { + #[flux_rs::sig(fn(&[T][@len]) -> usize[len])] + fn len(v: &[T]) -> usize; +} + + +#[flux_rs::refined_by(ring_len: int, hd: int, tl: int)] +#[flux_rs::invariant(ring_len > 1)] +pub struct RingBuffer<'a, T: 'a> { + #[field({&mut [T][ring_len] | ring_len > 1})] + ring: &'a mut [T], + #[field({usize[hd] | hd < ring_len})] + head: usize, + #[field({usize[tl] | tl < ring_len})] + tail: usize, +} + +impl Queue for RingBuffer<'_, T> { + fn is_full(&self) -> bool { + self.head == ((self.tail + 1) % self.ring.len()) + } + + #[flux_rs::sig(fn(self: &strg Self, _) -> bool ensures self: Self)] + fn enqueue(&mut self, val: T) -> bool { + if self.is_full() { + // Incrementing tail will overwrite head + false + } else { + self.ring[self.tail] = val; + self.tail = (self.tail + 1) % self.ring.len(); + true + } + } +} + +// This code causes an ICE +fn get_ring_buffer() -> &'static mut RingBuffer<'static, usize> {unimplemented!()} + +fn enqueue_task() { + let rb = get_ring_buffer(); + rb.enqueue(3); +} +