Skip to content

Commit 849f901

Browse files
committed
elide mod comments using new detached-spec-scoping
1 parent 32b37ae commit 849f901

1 file changed

Lines changed: 61 additions & 68 deletions

File tree

kernel/src/collections/ring_buffer.rs

Lines changed: 61 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -356,75 +356,71 @@ mod flux_specs {
356356
}
357357

358358
// ======= RingBuffer spec ===========
359-
use crate::collections;
360-
#[flux::specs {
361-
mod collections {
362-
mod ring_buffer {
363-
// Specify well-formedness for RingBuffer<T>.
364-
// Flux will raise an error if 1) any RingBuffer implementation violates these rules,
365-
// Or 2) Any Tock code attempts to create a RingBuffer that violates these rules.
366-
// At the bottom of this spec, we have included some example
367-
// test code that raises Flux errors for both of these cases.
368-
#[refined_by(ring_len: int, hd: int, tl: int)]
369-
struct RingBuffer<T> {
370-
ring: {&mut [T][ring_len] | ring_len > 1},
371-
head: {usize[hd] | hd < ring_len},
372-
tail: {usize[tl] | tl < ring_len},
373-
}
359+
use crate::collections::list::ListIterator;
360+
use crate::collections::queue::Queue;
361+
use crate::collections::ring_buffer::RingBuffer;
362+
use core::iter::Iterator;
374363

375-
impl RingBuffer<T> {
376-
// Example of a function-level spec.
377-
// It has a precondition that the input slice is length > 1, so
378-
// every time RingBuffer::new() is called (throughout Tock),
379-
// Flux will ensure the slice passed in has length > 1.
380-
//
381-
// It also has a postcondition that the output RingBuffer has a head and tail of zero.
382-
// Flux will check the implementation of `new` to ensure this is true.
383-
//
384-
// Design note: This contract has the strongest possible postcondition (head == 0 and tail == 0),
385-
// but we could also make the postcondition something "weaker" like `result.head == result.tail`.
386-
// Weaker vs stronger contracts is a design decision: it is easier to prove that a weak contract
387-
// holds in the implementation, but it lets you prove less in the rest of Tock (e.g., if there was code
388-
// that was only safe if head/tail was 0 after it called new, we could prove its safety only with the stronger contract).
389-
fn new({&mut [T][@ring_len] | ring_len > 1}) -> RingBuffer<T>[ring_len, 0, 0];
390-
}
391-
}
364+
#[flux::specs {
365+
// Specify well-formedness for RingBuffer<T>.
366+
// Flux will raise an error if 1) any RingBuffer implementation violates these rules,
367+
// Or 2) Any Tock code attempts to create a RingBuffer that violates these rules.
368+
// At the bottom of this spec, we have included some example
369+
// test code that raises Flux errors for both of these cases.
370+
#[refined_by(ring_len: int, hd: int, tl: int)]
371+
struct RingBuffer<T> {
372+
ring: {&mut [T][ring_len] | ring_len > 1},
373+
head: {usize[hd] | hd < ring_len},
374+
tail: {usize[tl] | tl < ring_len},
375+
}
392376
393-
mod queue {
394-
impl Queue<T> for collections::ring_buffer::RingBuffer<T> {
395-
// Simple function-level contract.
396-
// See `new` example above for a discussion of contract design.
397-
fn empty(self: &mut RingBuffer<T>[@old])
398-
ensures self: RingBuffer<T>[old.ring_len, 0, 0];
399-
400-
// These specs of the form: `(self: RingBuffer) ensures RingBuffer`
401-
// are present to compensate for a current technical limitation of Flux,
402-
// and should be gone in the near future.
403-
fn enqueue(self: &mut RingBuffer<T>, val: T) -> bool
404-
ensures self: RingBuffer<T>;
405-
406-
fn push(self: &mut RingBuffer<T>, val: T) -> Option<T>
407-
ensures self: RingBuffer<T>;
408-
409-
fn dequeue(self: &mut RingBuffer<T>) -> Option<T>
410-
ensures self: RingBuffer<T>;
411-
412-
fn remove_first_matching<F>(self: &mut RingBuffer<T>, _) -> Option<T>
413-
ensures self: RingBuffer<T>;
414-
415-
fn retain<F>(self: &mut RingBuffer<T>, _)
416-
ensures self: RingBuffer<T>;
417-
}
418-
419-
}
377+
impl RingBuffer<T> {
378+
// Example of a function-level spec.
379+
// It has a precondition that the input slice is length > 1, so
380+
// every time RingBuffer::new() is called (throughout Tock),
381+
// Flux will ensure the slice passed in has length > 1.
382+
//
383+
// It also has a postcondition that the output RingBuffer has a head and tail of zero.
384+
// Flux will check the implementation of `new` to ensure this is true.
385+
//
386+
// Design note: This contract has the strongest possible postcondition (head == 0 and tail == 0),
387+
// but we could also make the postcondition something "weaker" like `result.head == result.tail`.
388+
// Weaker vs stronger contracts is a design decision: it is easier to prove that a weak contract
389+
// holds in the implementation, but it lets you prove less in the rest of Tock (e.g., if there was code
390+
// that was only safe if head/tail was 0 after it called new, we could prove its safety only with the stronger contract).
391+
fn new({&mut [T][@ring_len] | ring_len > 1}) -> RingBuffer<T>[ring_len, 0, 0];
392+
}
393+
394+
impl Queue<T> for RingBuffer<T> {
395+
// Simple function-level contract.
396+
// See `new` example above for a discussion of contract design.
397+
fn empty(self: &mut RingBuffer<T>[@old])
398+
ensures self: RingBuffer<T>[old.ring_len, 0, 0];
399+
400+
// These specs of the form: `(self: RingBuffer) ensures RingBuffer`
401+
// are present to compensate for a current technical limitation of Flux,
402+
// and should be gone in the near future.
403+
fn enqueue(self: &mut RingBuffer<T>, val: T) -> bool
404+
ensures self: RingBuffer<T>;
405+
406+
fn push(self: &mut RingBuffer<T>, val: T) -> Option<T>
407+
ensures self: RingBuffer<T>;
408+
409+
fn dequeue(self: &mut RingBuffer<T>) -> Option<T>
410+
ensures self: RingBuffer<T>;
411+
412+
fn remove_first_matching<F>(self: &mut RingBuffer<T>, _) -> Option<T>
413+
ensures self: RingBuffer<T>;
414+
415+
fn retain<F>(self: &mut RingBuffer<T>, _)
416+
ensures self: RingBuffer<T>;
417+
}
420418
421-
mod list {
422-
impl Iterator for collections::list::ListIterator<T> {
423-
fn next(self: &mut ListIterator<T>) -> Option<&T>
424-
ensures self: ListIterator<T>;
425-
}
426-
}
419+
impl Iterator for ListIterator<T> {
420+
fn next(self: &mut ListIterator<T>) -> Option<&T>
421+
ensures self: ListIterator<T>;
427422
}
423+
428424
}]
429425
const _: () = ();
430426

@@ -434,9 +430,6 @@ mod flux_specs {
434430
// 1. Bad usage of the RingBuffer API that leads to kernel panics
435431
// 2. Bad implementation of the RingBuffer API that leads to kernel panics
436432

437-
use crate::collections::queue::Queue;
438-
use crate::collections::ring_buffer::RingBuffer;
439-
440433
// 1. Flux will prevent Tock from using the RingBuffer API incorrectly, leading to panics
441434
#[allow(dead_code)]
442435
#[flux_rs::should_fail]

0 commit comments

Comments
 (0)