@@ -237,6 +237,319 @@ test_verify_one_file! {
237237 } => Err ( err) => assert_fails( err, 8 )
238238}
239239
240+ test_verify_one_file ! {
241+ #[ test] test_slice_index_range_to verus_code! {
242+ use std:: ops:: Index ;
243+ use vstd:: prelude:: * ;
244+
245+ fn range_to( s: & [ u8 ] ) {
246+ assume( s. len( ) == 5 ) ;
247+ let x = & s[ ..3 ] ;
248+ assert( x@ == s@. subrange( 0 , 3 ) ) ;
249+ assert( x@ == s@. subrange( 0 , 4 ) ) ; // FAILS
250+ }
251+
252+ fn range_to_bounds( s: & [ u8 ] ) {
253+ assume( s. len( ) == 5 ) ;
254+ let x = & s[ ..7 ] ; // FAILS
255+ }
256+
257+ fn range_to_index( s: & [ u8 ] ) {
258+ assume( s. len( ) == 5 ) ;
259+ let x = s. index( ..3 ) ;
260+ assert( x@ == s@. subrange( 0 , 3 ) ) ;
261+ assert( x@ == s@. subrange( 0 , 4 ) ) ; // FAILS
262+ }
263+
264+ fn range_to_index_bounds( s: & [ u8 ] ) {
265+ assume( s. len( ) == 5 ) ;
266+ let x = s. index( ..7 ) ; // FAILS
267+ }
268+ } => Err ( err) => assert_fails( err, 4 )
269+ }
270+
271+ test_verify_one_file ! {
272+ #[ test] test_slice_index_range_from verus_code! {
273+ use vstd:: prelude:: * ;
274+
275+ fn range_from( s: & [ u8 ] ) {
276+ assume( s. len( ) == 5 ) ;
277+ let x = & s[ 2 ..] ;
278+ assert( x@ == s@. subrange( 2 , 5 ) ) ;
279+ assert( x@ == s@. subrange( 1 , 5 ) ) ; // FAILS
280+ }
281+
282+ fn range_from_bounds( s: & [ u8 ] ) {
283+ assume( s. len( ) == 5 ) ;
284+ let x = & s[ 7 ..] ; // FAILS
285+ }
286+ } => Err ( err) => assert_fails( err, 2 )
287+ }
288+
289+ test_verify_one_file ! {
290+ #[ test] test_slice_index_range_to_inclusive verus_code! {
291+ use vstd:: prelude:: * ;
292+
293+ fn range_to_inclusive( s: & [ u8 ] ) {
294+ assume( s. len( ) == 5 ) ;
295+ let x = & s[ ..=3 ] ;
296+ assert( x@ == s@. subrange( 0 , 4 ) ) ;
297+ assert( x@ == s@. subrange( 0 , 3 ) ) ; // FAILS
298+ }
299+
300+ fn range_to_inclusive_bounds( s: & [ u8 ] ) {
301+ assume( s. len( ) == 5 ) ;
302+ let x = & s[ ..=5 ] ; // FAILS
303+ }
304+ } => Err ( err) => assert_fails( err, 2 )
305+ }
306+
307+ test_verify_one_file ! {
308+ #[ test] test_slice_index_range_full verus_code! {
309+ use vstd:: prelude:: * ;
310+
311+ fn range_full( s: & [ u8 ] ) {
312+ assume( s. len( ) == 5 ) ;
313+ let x = & s[ ..] ;
314+ assert( x@ == s@) ;
315+ assert( x@. len( ) == 4 ) ; // FAILS
316+ }
317+ } => Err ( err) => assert_one_fails( err)
318+ }
319+
320+ test_verify_one_file ! {
321+ #[ test] test_slice_index_range_inclusive verus_code! {
322+ use vstd:: prelude:: * ;
323+
324+ fn range_inclusive( s: & [ u8 ] ) {
325+ assume( s. len( ) == 5 ) ;
326+ let x = & s[ 1 ..=3 ] ;
327+ assert( x@ == s@. subrange( 1 , 4 ) ) ;
328+ assert( x@ == s@. subrange( 1 , 3 ) ) ; // FAILS
329+ }
330+
331+ fn range_inclusive_bounds( s: & [ u8 ] ) {
332+ assume( s. len( ) == 5 ) ;
333+ let x = & s[ 1 ..=5 ] ; // FAILS
334+ }
335+ } => Err ( err) => assert_fails( err, 2 )
336+ }
337+
338+ test_verify_one_file ! {
339+ #[ test] test_slice_get_ranges verus_code! {
340+ use vstd:: prelude:: * ;
341+
342+ fn range_get( s: & [ u8 ] ) {
343+ assume( s. len( ) == 5 ) ;
344+ let some = s. get( 1 ..3 ) ;
345+ assert( some. is_some( ) ) ;
346+ assert( some. unwrap( ) @ == s@. subrange( 1 , 3 ) ) ;
347+ let none = s. get( 1 ..7 ) ;
348+ assert( none. is_none( ) ) ;
349+ }
350+
351+ fn range_to_get( s: & [ u8 ] ) {
352+ assume( s. len( ) == 5 ) ;
353+ let some = s. get( ..3 ) ;
354+ assert( some. is_some( ) ) ;
355+ assert( some. unwrap( ) @ == s@. subrange( 0 , 3 ) ) ;
356+ let none = s. get( ..7 ) ;
357+ assert( none. is_none( ) ) ;
358+ }
359+
360+ fn range_from_get( s: & [ u8 ] ) {
361+ assume( s. len( ) == 5 ) ;
362+ let some = s. get( 2 ..) ;
363+ assert( some. is_some( ) ) ;
364+ assert( some. unwrap( ) @ == s@. subrange( 2 , 5 ) ) ;
365+ let none = s. get( 7 ..) ;
366+ assert( none. is_none( ) ) ;
367+ }
368+
369+ fn range_to_inclusive_get( s: & [ u8 ] ) {
370+ assume( s. len( ) == 5 ) ;
371+ let some = s. get( ..=3 ) ;
372+ assert( some. is_some( ) ) ;
373+ assert( some. unwrap( ) @ == s@. subrange( 0 , 4 ) ) ;
374+ let none = s. get( ..=7 ) ;
375+ assert( none. is_none( ) ) ;
376+ }
377+
378+ fn range_full_get( s: & [ u8 ] ) {
379+ assume( s. len( ) == 5 ) ;
380+ let some = s. get( ..) ;
381+ assert( some. is_some( ) ) ;
382+ assert( some. unwrap( ) @ == s@) ;
383+ }
384+
385+ fn range_inclusive_get( s: & [ u8 ] ) {
386+ assume( s. len( ) == 5 ) ;
387+ let some = s. get( 1 ..=3 ) ;
388+ assert( some. is_some( ) ) ;
389+ assert( some. unwrap( ) @ == s@. subrange( 1 , 4 ) ) ;
390+ let none = s. get( 1 ..=7 ) ;
391+ assert( none. is_none( ) ) ;
392+ }
393+
394+ fn range_get_wrong_fails( s: & [ u8 ] ) {
395+ assume( s. len( ) == 5 ) ;
396+ let some = s. get( 1 ..3 ) ;
397+ assert( some. unwrap( ) @ == s@. subrange( 1 , 4 ) ) ; // FAILS
398+ }
399+ } => Err ( err) => assert_one_fails( err)
400+ }
401+
402+ // Checks the mutable-indexing form (`&mut s[range]`) via the returned
403+ // sub-slice's own view, both before and after writing through it.
404+ test_verify_one_file ! {
405+ #[ test] test_slice_index_mut_ranges verus_code! {
406+ use vstd:: prelude:: * ;
407+
408+ fn range_index_mut( s: & mut [ u8 ] ) {
409+ assume( s. len( ) == 5 ) ;
410+ let sub = & mut s[ 1 ..3 ] ;
411+ assert( sub@ == old( s) @. subrange( 1 , 3 ) ) ;
412+ sub[ 0 ] = 99 ;
413+ sub[ 1 ] = 88 ;
414+ assert( sub@ == seq![ 99 , 88 ] ) ;
415+ }
416+
417+ fn range_to_index_mut( s: & mut [ u8 ] ) {
418+ assume( s. len( ) == 5 ) ;
419+ let sub = & mut s[ ..3 ] ;
420+ assert( sub@ == old( s) @. subrange( 0 , 3 ) ) ;
421+ sub[ 0 ] = 99 ;
422+ assert( sub@[ 0 ] == 99 ) ;
423+ }
424+
425+ fn range_from_index_mut( s: & mut [ u8 ] ) {
426+ assume( s. len( ) == 5 ) ;
427+ let sub = & mut s[ 2 ..] ;
428+ assert( sub@ == old( s) @. subrange( 2 , 5 ) ) ;
429+ sub[ 0 ] = 99 ;
430+ assert( sub@[ 0 ] == 99 ) ;
431+ }
432+
433+ fn range_to_inclusive_index_mut( s: & mut [ u8 ] ) {
434+ assume( s. len( ) == 5 ) ;
435+ let sub = & mut s[ ..=3 ] ;
436+ assert( sub@ == old( s) @. subrange( 0 , 4 ) ) ;
437+ sub[ 3 ] = 99 ;
438+ assert( sub@[ 3 ] == 99 ) ;
439+ }
440+
441+ fn range_full_index_mut( s: & mut [ u8 ] ) {
442+ assume( s. len( ) == 5 ) ;
443+ let sub = & mut s[ ..] ;
444+ assert( sub@ == old( s) @) ;
445+ sub[ 4 ] = 99 ;
446+ assert( sub@[ 4 ] == 99 ) ;
447+ }
448+
449+ fn range_inclusive_index_mut( s: & mut [ u8 ] ) {
450+ assume( s. len( ) == 5 ) ;
451+ let sub = & mut s[ 1 ..=3 ] ;
452+ assert( sub@ == old( s) @. subrange( 1 , 4 ) ) ;
453+ sub[ 0 ] = 99 ;
454+ assert( sub@[ 0 ] == 99 ) ;
455+ }
456+ } => Ok ( ( ) )
457+ }
458+
459+ test_verify_one_file ! {
460+ #[ test] test_slice_index_mut_ranges_fails verus_code! {
461+ use vstd:: prelude:: * ;
462+
463+ fn range_index_mut_wrong( s: & mut [ u8 ] ) {
464+ assume( s. len( ) == 5 ) ;
465+ let sub = & mut s[ 1 ..3 ] ;
466+ sub[ 0 ] = 99 ;
467+ assert( sub@[ 0 ] == 5 ) ; // FAILS
468+ }
469+
470+ fn range_index_mut_wrong_len( s: & mut [ u8 ] ) {
471+ assume( s. len( ) == 5 ) ;
472+ let sub = & mut s[ 1 ..3 ] ;
473+ assert( sub@. len( ) == 3 ) ; // FAILS: 1..3 has length 2, not 3
474+ }
475+ } => Err ( err) => assert_fails( err, 2 )
476+ }
477+
478+ // Writing through a range-indexed mutable sub-slice reborrow, then observing
479+ // the *original* slice's own view after the reborrow's last use.
480+ test_verify_one_file ! {
481+ #[ test] test_slice_index_mut_range_writeback verus_code! {
482+ use vstd:: prelude:: * ;
483+
484+ fn range_writeback( s: & mut [ u8 ] )
485+ requires old( s) @. len( ) == 5 ,
486+ ensures final( s) @ == old( s) @. update( 1 , 99 ) . update( 2 , 88 ) ,
487+ {
488+ let sub = & mut s[ 1 ..3 ] ;
489+ sub[ 0 ] = 99 ;
490+ sub[ 1 ] = 88 ;
491+ }
492+
493+ fn range_to_writeback( s: & mut [ u8 ] )
494+ requires old( s) @. len( ) == 5 ,
495+ ensures final( s) @ == old( s) @. update( 0 , 99 ) . update( 1 , 88 ) ,
496+ {
497+ let sub = & mut s[ ..2 ] ;
498+ sub[ 0 ] = 99 ;
499+ sub[ 1 ] = 88 ;
500+ }
501+
502+ fn range_from_writeback( s: & mut [ u8 ] )
503+ requires old( s) @. len( ) == 5 ,
504+ ensures final( s) @ == old( s) @. update( 3 , 99 ) . update( 4 , 88 ) ,
505+ {
506+ let sub = & mut s[ 3 ..] ;
507+ sub[ 0 ] = 99 ;
508+ sub[ 1 ] = 88 ;
509+ }
510+
511+ fn range_to_inclusive_writeback( s: & mut [ u8 ] )
512+ requires old( s) @. len( ) == 5 ,
513+ ensures final( s) @ == old( s) @. update( 0 , 99 ) . update( 1 , 88 ) ,
514+ {
515+ let sub = & mut s[ ..=1 ] ;
516+ sub[ 0 ] = 99 ;
517+ sub[ 1 ] = 88 ;
518+ }
519+
520+ fn range_full_writeback( s: & mut [ u8 ] )
521+ requires old( s) @. len( ) == 5 ,
522+ ensures final( s) @ == old( s) @. update( 0 , 99 ) . update( 4 , 88 ) ,
523+ {
524+ let sub = & mut s[ ..] ;
525+ sub[ 0 ] = 99 ;
526+ sub[ 4 ] = 88 ;
527+ }
528+
529+ fn range_inclusive_writeback( s: & mut [ u8 ] )
530+ requires old( s) @. len( ) == 5 ,
531+ ensures final( s) @ == old( s) @. update( 1 , 99 ) . update( 3 , 88 ) ,
532+ {
533+ let sub = & mut s[ 1 ..=3 ] ;
534+ sub[ 0 ] = 99 ;
535+ sub[ 2 ] = 88 ;
536+ }
537+ } => Ok ( ( ) )
538+ }
539+
540+ test_verify_one_file ! {
541+ #[ test] test_slice_index_mut_range_writeback_fails verus_code! {
542+ use vstd:: prelude:: * ;
543+
544+ fn range_writeback_wrong_value( s: & mut [ u8 ] ) {
545+ assume( s. len( ) == 5 ) ;
546+ let sub = & mut s[ 1 ..3 ] ;
547+ sub[ 0 ] = 99 ;
548+ assert( s@[ 1 ] == 5 ) ; // FAILS
549+ }
550+ } => Err ( err) => assert_one_fails( err)
551+ }
552+
240553test_verify_one_file ! {
241554 #[ test] test_array_index verus_code! {
242555 use std:: ops:: Index ;
0 commit comments