@@ -4146,45 +4146,6 @@ impl<T> [T] {
41464146 }
41474147 }
41484148
4149- //We need the following wrapper because it is not currently possible to write
4150- //contracts for functions that return mut refs to input arguments
4151- //see https://github.com/model-checking/kani/issues/3764
4152- //----------------------------
4153- //Checks if the part that will be transmuted from type T to U is valid for type U
4154- //reuses most function logic up to use of from_raw_parts,
4155- //where the potentially unsafe transmute occurs
4156- #[ requires(
4157- U :: IS_ZST || T :: IS_ZST || {
4158- let ptr = self . as_ptr( ) ;
4159- let offset = crate :: ptr:: align_offset( ptr, align_of:: <U >( ) ) ;
4160- offset > self . len( ) || {
4161- let ( _, rest) = self . split_at( offset) ;
4162- let ( us_len, _) = rest. align_to_offsets:: <U >( ) ;
4163- let middle = crate :: ptr:: slice_from_raw_parts( rest. as_ptr( ) as * const U , us_len
4164- ) ;
4165- ub_checks:: can_dereference( middle)
4166- }
4167- }
4168- ) ]
4169- //The following two ensures clauses guarantee that middle is of maximum size within self
4170- #[ ensures( |( prefix, _, _) : & ( * const [ T ] , * const [ U ] , * const [ T ] ) | prefix. len( ) * size_of:: <T >( ) < align_of:: <U >( ) ) ]
4171- #[ ensures( |( _, _, suffix) : & ( * const [ T ] , * const [ U ] , * const [ T ] ) | suffix. len( ) * size_of:: <T >( ) < size_of:: <U >( ) ) ]
4172- //Either align_to just returns self in the prefix, or the 3 returned slices
4173- //should be sequential, contiguous, and have same total length as self
4174- #[ ensures( |( prefix, middle, suffix) : & ( * const [ T ] , * const [ U ] , * const [ T ] ) |
4175- prefix. as_ptr( ) == self . as_ptr( ) &&
4176- ( prefix. len( ) == self . len( ) || (
4177- ( ( prefix. as_ptr( ) ) . add( prefix. len( ) ) as * const u8 == middle. as_ptr( ) as * const u8 )
4178- &&
4179- ( ( middle. as_ptr( ) ) . add( middle. len( ) ) as * const u8 == suffix. as_ptr( ) as * const u8 ) &&
4180- ( ( suffix. as_ptr( ) ) . add( suffix. len( ) ) == ( self . as_ptr( ) ) . add( self . len( ) ) ) )
4181- )
4182- ) ]
4183- unsafe fn align_to_mut_wrapper < U > ( & mut self ) -> ( * const [ T ] , * const [ U ] , * const [ T ] ) {
4184- let ( prefix_mut, mid_mut, suffix_mut) = self . align_to_mut :: < U > ( ) ;
4185- ( prefix_mut as * const [ T ] , mid_mut as * const [ U ] , suffix_mut as * const [ T ] )
4186- }
4187-
41884149 /// Splits a slice into a prefix, a middle of aligned SIMD types, and a suffix.
41894150 ///
41904151 /// This is a safe wrapper around [`slice::align_to`], so inherits the same
@@ -5370,9 +5331,9 @@ mod verify {
53705331
53715332 macro_rules! proof_of_contract_for_align_to {
53725333 ( $harness: ident, $src: ty, $dst: ty) => {
5373- #[ kani:: proof_for_contract( <[ $dst ] >:: align_to) ]
5334+ #[ kani:: proof_for_contract( <[ $src ] >:: align_to) ]
53745335 fn $harness( ) {
5375- const ARR_SIZE : usize = 1000 ;
5336+ const ARR_SIZE : usize = 100 ;
53765337 let src_arr: [ $src; ARR_SIZE ] = kani:: any( ) ;
53775338 let src_slice = kani:: slice:: any_slice_of_array( & src_arr) ;
53785339 let dst_slice = unsafe { src_slice. align_to:: <$dst>( ) } ;
@@ -5438,11 +5399,56 @@ mod verify {
54385399 gen_align_to_harnesses ! ( align_to_from_char, char ) ;
54395400 gen_align_to_harnesses ! ( align_to_from_unit, ( ) ) ;
54405401
5402+ trait wrap_align_to_mut < T > {
5403+ unsafe fn align_to_mut_wrapper < U > ( & mut self ) -> ( * const [ T ] , * const [ U ] , * const [ T ] ) ;
5404+ }
5405+
5406+ //We write this as an impl so that we can refer to "self"
5407+ impl < T > wrap_align_to_mut < T > for [ T ] {
5408+ //We need the following wrapper because it is not currently possible to write
5409+ //contracts for functions that return mut refs to input arguments
5410+ //see https://github.com/model-checking/kani/issues/3764
5411+ //----------------------------
5412+ //Checks if the part that will be transmuted from type T to U is valid for type U
5413+ //reuses most function logic up to use of from_raw_parts,
5414+ //where the potentially unsafe transmute occurs
5415+ #[ requires(
5416+ U :: IS_ZST || T :: IS_ZST || {
5417+ let ptr = self . as_ptr( ) ;
5418+ let offset = crate :: ptr:: align_offset( ptr, align_of:: <U >( ) ) ;
5419+ offset > self . len( ) || {
5420+ let ( _, rest) = self . split_at( offset) ;
5421+ let ( us_len, _) = rest. align_to_offsets:: <U >( ) ;
5422+ let middle = crate :: ptr:: slice_from_raw_parts( rest. as_ptr( ) as * const U , us_len
5423+ ) ;
5424+ ub_checks:: can_dereference( middle)
5425+ }
5426+ }
5427+ ) ]
5428+ //The following two ensures clauses guarantee that middle is of maximum size within self
5429+ #[ ensures( |( prefix, _, _) : & ( * const [ T ] , * const [ U ] , * const [ T ] ) | prefix. len( ) * size_of:: <T >( ) < align_of:: <U >( ) ) ]
5430+ #[ ensures( |( _, _, suffix) : & ( * const [ T ] , * const [ U ] , * const [ T ] ) | suffix. len( ) * size_of:: <T >( ) < size_of:: <U >( ) ) ]
5431+ //Either align_to just returns self in the prefix, or the 3 returned slices
5432+ //should be sequential, contiguous, and have same total length as self
5433+ #[ ensures( |( prefix, middle, suffix) : & ( * const [ T ] , * const [ U ] , * const [ T ] ) |
5434+ prefix. as_ptr( ) == self . as_ptr( ) &&
5435+ ( prefix. len( ) == self . len( ) || (
5436+ ( ( prefix. as_ptr( ) ) . add( prefix. len( ) ) as * const u8 == middle. as_ptr( ) as * const u8 ) &&
5437+ ( ( middle. as_ptr( ) ) . add( middle. len( ) ) as * const u8 == suffix. as_ptr( ) as * const u8 ) &&
5438+ ( ( suffix. as_ptr( ) ) . add( suffix. len( ) ) == ( self . as_ptr( ) ) . add( self . len( ) ) ) )
5439+ )
5440+ ) ]
5441+ unsafe fn align_to_mut_wrapper < U > ( & mut self ) -> ( * const [ T ] , * const [ U ] , * const [ T ] ) {
5442+ let ( prefix_mut, mid_mut, suffix_mut) = self . align_to_mut :: < U > ( ) ;
5443+ ( prefix_mut as * const [ T ] , mid_mut as * const [ U ] , suffix_mut as * const [ T ] )
5444+ }
5445+ }
5446+
54415447 macro_rules! proof_of_contract_for_align_to_mut {
54425448 ( $harness: ident, $src: ty, $dst: ty) => {
5443- #[ kani:: proof_for_contract( <[ $dst ] >:: align_to_mut_wrapper) ]
5449+ #[ kani:: proof_for_contract( <[ $src ] >:: align_to_mut_wrapper) ]
54445450 fn $harness( ) {
5445- const ARR_SIZE : usize = 1000 ;
5451+ const ARR_SIZE : usize = 100 ;
54465452 let mut src_arr: [ $src; ARR_SIZE ] = kani:: any( ) ;
54475453 let src_slice = kani:: slice:: any_slice_of_array_mut( & mut src_arr) ;
54485454 let dst_slice = unsafe { src_slice. align_to_mut_wrapper:: <$dst>( ) } ;
0 commit comments