@@ -215,6 +215,9 @@ impl Layout {
215
215
#[ unstable( feature = "layout_for_ptr" , issue = "69835" ) ]
216
216
#[ rustc_const_unstable( feature = "const_alloc_layout" , issue = "67521" ) ]
217
217
#[ must_use]
218
+ // TODO: we should try to capture the above constraints on T in a `requires` clause, and the
219
+ // metadata helpers from https://github.com/model-checking/verify-rust-std/pull/37 may be able
220
+ // to accomplish this.
218
221
#[ ensures( |result| result. align( ) . is_power_of_two( ) ) ]
219
222
pub const unsafe fn for_value_raw < T : ?Sized > ( t : * const T ) -> Self {
220
223
// SAFETY: we pass along the prerequisites of these functions to the caller
@@ -345,13 +348,20 @@ impl Layout {
345
348
/// On arithmetic overflow, returns `LayoutError`.
346
349
#[ unstable( feature = "alloc_layout_extra" , issue = "55724" ) ]
347
350
#[ inline]
348
- // the below modulo operation might be too costly to prove
349
- #[ cfg_attr( not( kani) , ensures( |result| result. is_err( ) || n == 0 || result. as_ref( ) . unwrap( ) . 0 . size( ) % n == 0 ) ) ]
350
- #[ cfg_attr( kani, ensures( |result| result. is_err( ) || n == 0 || result. as_ref( ) . unwrap( ) . 0 . size( ) >= self . size( ) ) ) ]
351
- // the below multiplication might be too costly to prove at this time
352
- // #[ensures(|result| result.is_err() || result.as_ref().unwrap().0.size() == n * result.as_ref().unwrap().1)]
353
- // use the weaker statement below for now
354
- #[ ensures( |result| result. is_err( ) || n == 0 || result. as_ref( ) . unwrap( ) . 0 . size( ) >= result. as_ref( ) . unwrap( ) . 1 ) ]
351
+ // for Kani (v0.54.0), the below modulo operation is too costly to prove (running into the
352
+ // 6-hours timeout on GitHub); we use a weaker postcondition instead
353
+ #[ cfg_attr( not( kani) ,
354
+ ensures( |result| result. is_err( ) || n == 0 || result. as_ref( ) . unwrap( ) . 0 . size( ) % n == 0 ) ) ]
355
+ #[ cfg_attr( kani,
356
+ ensures( |result| result. is_err( ) || n == 0 || result. as_ref( ) . unwrap( ) . 0 . size( ) >= self . size( ) ) ) ]
357
+ // for Kani (v0.54.0), the below multiplication is too costly to prove (running into the
358
+ // 6-hours timeout on GitHub); we use a weaker postcondition instead
359
+ #[ cfg_attr( not( kani) ,
360
+ ensures( |result| result. is_err( ) ||
361
+ result. as_ref( ) . unwrap( ) . 0 . size( ) == n * result. as_ref( ) . unwrap( ) . 1 ) ) ]
362
+ #[ cfg_attr( kani,
363
+ ensures( |result| result. is_err( ) || n == 0 ||
364
+ result. as_ref( ) . unwrap( ) . 0 . size( ) >= result. as_ref( ) . unwrap( ) . 1 ) ) ]
355
365
pub fn repeat ( & self , n : usize ) -> Result < ( Self , usize ) , LayoutError > {
356
366
// This cannot overflow. Quoting from the invariant of Layout:
357
367
// > `size`, when rounded up to the nearest multiple of `align`,
@@ -442,10 +452,12 @@ impl Layout {
442
452
/// On arithmetic overflow, returns `LayoutError`.
443
453
#[ unstable( feature = "alloc_layout_extra" , issue = "55724" ) ]
444
454
#[ inline]
445
- // the below multiplication might be too costly to prove at this time
446
- // #[ensures(|result| result.is_err() || result.as_ref().unwrap().size() == n * self.size())]
447
- // use the weaker statement below for now
448
- #[ ensures( |result| result. is_err( ) || n == 0 || result. as_ref( ) . unwrap( ) . size( ) >= self . size( ) ) ]
455
+ // for Kani (v0.54.0), the below multiplication is too costly to prove (running into the
456
+ // 6-hours timeout on GitHub); we use a weaker postcondition instead
457
+ #[ cfg_attr( not( kani) ,
458
+ ensures( |result| result. is_err( ) || result. as_ref( ) . unwrap( ) . size( ) == n * self . size( ) ) ) ]
459
+ #[ cfg_attr( kani,
460
+ ensures( |result| result. is_err( ) || n == 0 || result. as_ref( ) . unwrap( ) . size( ) >= self . size( ) ) ) ]
449
461
#[ ensures( |result| result. is_err( ) || result. as_ref( ) . unwrap( ) . align( ) == self . align( ) ) ]
450
462
pub fn repeat_packed ( & self , n : usize ) -> Result < Self , LayoutError > {
451
463
let size = self . size ( ) . checked_mul ( n) . ok_or ( LayoutError ) ?;
@@ -602,7 +614,8 @@ mod verify {
602
614
let _ = Layout :: for_value :: < i32 > ( & x) ;
603
615
let array : [ i32 ; 2 ] = [ 1 , 2 ] ;
604
616
let _ = Layout :: for_value :: < [ i32 ] > ( & array[ 1 .. 1 ] ) ;
605
- // TODO: the case of a trait object as unsized tail is not yet covered
617
+ let trait_ref: & dyn core:: fmt:: Debug = & x;
618
+ let _ = Layout :: for_value :: < dyn core:: fmt:: Debug > ( trait_ref) ;
606
619
// TODO: the case of an extern type as unsized tail is not yet covered
607
620
}
608
621
@@ -613,7 +626,8 @@ mod verify {
613
626
let x = kani:: any :: < i32 > ( ) ;
614
627
let _ = Layout :: for_value_raw :: < i32 > ( & x as * const i32 ) ;
615
628
let _ = Layout :: for_value_raw :: < [ i32 ] > ( & [ ] as * const [ i32 ] ) ;
616
- // TODO: the case of a trait object as unsized tail is not yet covered
629
+ let trait_ref: & dyn core:: fmt:: Debug = & x;
630
+ let _ = Layout :: for_value_raw :: < dyn core:: fmt:: Debug > ( trait_ref) ;
617
631
// TODO: the case of an extern type as unsized tail is not yet covered
618
632
}
619
633
}
0 commit comments