@@ -318,3 +318,74 @@ mod test {
318318 assert_eq ! ( buf. dequeue( ) , None ) ;
319319 }
320320}
321+
322+
323+ // ===== Flux proof ========
324+
325+ // Need to tell Flux what slice.len() does
326+ #[ flux_rs:: extern_spec]
327+ impl < T > [ T ] {
328+ #[ flux_rs:: sig( fn ( & [ T ] [ @len] ) -> usize [ len] ) ]
329+ fn len ( v : & [ T ] ) -> usize ;
330+ }
331+
332+ // Need to tell Flux what an Option<T> is
333+ // Here, we refine Option<T> with a bool, denoting whether it is Some or None
334+ #[ flux_rs:: extern_spec]
335+ #[ flux_rs:: refined_by( b: bool ) ]
336+ enum Option < T > {
337+ #[ variant( Option <T >[ false ] ) ]
338+ None ,
339+ #[ variant( { T } -> Option <T >[ true ] ) ]
340+ Some ( T ) ,
341+ }
342+
343+ #[ flux:: specs {
344+ mod collections {
345+ mod ring_buffer {
346+ // Specify well-formedness for RingBuffer<T>
347+ #[ refined_by( ring_len: int, hd: int, tl: int) ]
348+ struct RingBuffer <T > {
349+ ring: { & mut [ T ] [ ring_len] | ring_len > 1 } ,
350+ head: { usize [ hd] | hd < ring_len} ,
351+ tail: { usize [ tl] | tl < ring_len} ,
352+ }
353+
354+ impl RingBuffer <T > {
355+ // Every time RingBuffer::new() is called,
356+ // Flux will ensure the slice passed in has length > 1.
357+ fn new( { & mut [ T ] [ @ring_len] | ring_len > 1 } ) -> RingBuffer <T >[ ring_len, 0 , 0 ] ;
358+ }
359+ }
360+
361+ mod queue {
362+ impl Queue <T > for collections:: ring_buffer:: RingBuffer <T > {
363+ fn enqueue( self : & mut RingBuffer <T >, val: T ) -> bool
364+ ensures self : RingBuffer <T >;
365+
366+ fn push( self : & mut RingBuffer <T >, val: T ) -> Option <T >
367+ ensures self : RingBuffer <T >;
368+
369+ fn dequeue( self : & mut RingBuffer <T >) -> Option <T >
370+ ensures self : RingBuffer <T >;
371+
372+ fn remove_first_matching<F >( self : & mut RingBuffer <T >, _) -> Option <T >
373+ ensures self : RingBuffer <T >;
374+
375+ fn retain<F >( self : & mut RingBuffer <T >, _)
376+ ensures self : RingBuffer <T >;
377+
378+ fn empty( self : & mut RingBuffer <T >[ @old] )
379+ ensures self : RingBuffer <T >[ old. ring_len, 0 , 0 ] ;
380+ }
381+ }
382+
383+ mod list {
384+ impl Iterator for collections:: list:: ListIterator <T > {
385+ fn next( self : & mut ListIterator <T >) -> Option <& T >
386+ ensures self : ListIterator <T >;
387+ }
388+ }
389+ }
390+ } ]
391+ const _: ( ) = ( ) ;
0 commit comments