@@ -6,7 +6,6 @@ pub use mem::MaybeUninit;
6
6
use num:: { bigint:: ParseBigIntError , Integer , Num , One , Signed } ;
7
7
pub use once_cell:: unsync:: Lazy ;
8
8
use std:: {
9
- any:: Any ,
10
9
borrow:: Borrow ,
11
10
boxed:: Box ,
12
11
clone:: Clone ,
@@ -41,6 +40,15 @@ pub use num::ToPrimitive;
41
40
pub use num:: Zero ;
42
41
pub use std:: convert:: Into ;
43
42
43
+ pub use :: std:: any:: Any ;
44
+ pub use :: std:: marker:: Send ;
45
+ pub use :: std:: marker:: Sync ;
46
+
47
+ #[ cfg( not( feature = "sync" ) ) ]
48
+ pub type DynAny = dyn Any ;
49
+ #[ cfg( feature = "sync" ) ]
50
+ pub type DynAny = dyn Any + Send + Sync ;
51
+
44
52
#[ cfg( not( feature = "sync" ) ) ]
45
53
pub use :: std:: cell:: UnsafeCell ;
46
54
@@ -812,10 +820,10 @@ where
812
820
#[ cfg( feature = "sync" ) ]
813
821
let into_boxed_borrowed = into_boxed;
814
822
#[ cfg( feature = "sync" ) ]
815
- let guard = into_boxed_borrowed. lock ( ) . unwrap ( ) ;
823
+ let mut guard = into_boxed_borrowed. lock ( ) . unwrap ( ) ;
816
824
#[ cfg( feature = "sync" ) ]
817
825
let borrowed: Option < & Rc < Vec < T > > > = guard. as_ref ( ) ;
818
-
826
+
819
827
#[ cfg( not( feature = "sync" ) ) ]
820
828
let into_boxed = boxed. as_ref ( ) . clone ( ) ;
821
829
#[ cfg( not( feature = "sync" ) ) ]
@@ -828,19 +836,38 @@ where
828
836
// Let's create an array of size length and fill it up recursively
829
837
// We don't materialize nested arrays because most of the time they are forgotten
830
838
let mut array: Vec < T > = Vec :: with_capacity ( * length) ;
831
- Sequence :: < T > :: append_recursive ( & mut array, self ) ;
839
+ Sequence :: < T > :: append_recursive_safe ( & mut array, & borrowed , left , right ) ;
832
840
let result = Rc :: new ( array) ;
833
841
let mutable_left: * mut Sequence < T > = left. get ( ) ;
834
842
let mutable_right: * mut Sequence < T > = right. get ( ) ;
835
843
// safety: Once the array is computed, left and right won't ever be read again.
836
844
unsafe { * mutable_left = seq ! ( ) } ;
837
845
unsafe { * mutable_right = seq ! ( ) } ;
838
- Self :: write_cache ( boxed, result. clone ( ) ) ;
846
+ #[ cfg( not( feature = "sync" ) ) ]
847
+ let mut guard = boxed. borrow_mut ( ) ;
848
+ * guard = Some ( result. clone ( ) ) ;
839
849
result
840
850
}
841
851
}
842
852
}
843
853
854
+ pub fn append_recursive_safe (
855
+ array : & mut Vec < T > ,
856
+ borrowed : & Option < & Rc < Vec < T > > > ,
857
+ left : & Rc < UnsafeCell < Sequence < T > > > ,
858
+ right : & Rc < UnsafeCell < Sequence < T > > > ,
859
+ ) {
860
+ if let Some ( values) = borrowed. as_ref ( ) {
861
+ for value in values. iter ( ) {
862
+ array. push ( value. clone ( ) ) ;
863
+ }
864
+ return ;
865
+ }
866
+ // safety: When a concat is initialized, the left and right are well defined
867
+ Sequence :: < T > :: append_recursive ( array, unsafe { & mut * left. get ( ) } ) ;
868
+ Sequence :: < T > :: append_recursive ( array, unsafe { & mut * right. get ( ) } ) ;
869
+ }
870
+
844
871
pub fn append_recursive ( array : & mut Vec < T > , this : & Sequence < T > ) {
845
872
match this {
846
873
Sequence :: ArraySequence { values, .. } =>
@@ -863,7 +890,7 @@ where
863
890
let guard = into_boxed_borrowed. lock ( ) . unwrap ( ) ;
864
891
#[ cfg( feature = "sync" ) ]
865
892
let borrowed: Option < & Rc < Vec < T > > > = guard. as_ref ( ) ;
866
-
893
+
867
894
#[ cfg( not( feature = "sync" ) ) ]
868
895
let into_boxed = boxed. as_ref ( ) . clone ( ) ;
869
896
#[ cfg( not( feature = "sync" ) ) ]
@@ -940,28 +967,6 @@ where
940
967
}
941
968
}
942
969
943
- #[ cfg( feature = "sync" ) ]
944
- impl < T > Sequence < T >
945
- where
946
- T : DafnyType ,
947
- {
948
- fn write_cache ( boxed : & Rc < RefCell < Option < Rc < Vec < T > > > > > , array : Rc < Vec < T > > ) {
949
- let mut cache = boxed. lock ( ) . unwrap ( ) ;
950
- * cache = Some ( array. clone ( ) ) ;
951
- }
952
- }
953
-
954
- #[ cfg( not( feature = "sync" ) ) ]
955
- impl < T > Sequence < T >
956
- where
957
- T : DafnyType ,
958
- {
959
- fn write_cache ( boxed : & Rc < RefCell < Option < Rc < Vec < T > > > > > , array : Rc < Vec < T > > ) {
960
- let mut cache = boxed. borrow_mut ( ) ;
961
- * cache = Some ( array. clone ( ) ) ;
962
- }
963
- }
964
-
965
970
pub struct SequenceIter < T : Clone > {
966
971
array : Rc < Vec < T > > ,
967
972
index : SizeT ,
@@ -2178,7 +2183,7 @@ impl DafnyPrint for () {
2178
2183
}
2179
2184
}
2180
2185
2181
- #[ derive( Clone ) ]
2186
+ #[ derive( Clone , Copy ) ]
2182
2187
pub struct DafnyCharUTF16 ( pub u16 ) ;
2183
2188
pub type DafnyStringUTF16 = Sequence < DafnyCharUTF16 > ;
2184
2189
@@ -2254,7 +2259,7 @@ impl Sub<DafnyCharUTF16> for DafnyCharUTF16 {
2254
2259
}
2255
2260
}
2256
2261
2257
- #[ derive( Clone ) ]
2262
+ #[ derive( Clone , Copy ) ]
2258
2263
pub struct DafnyChar ( pub char ) ;
2259
2264
pub type DafnyString = Sequence < DafnyChar > ;
2260
2265
@@ -3200,18 +3205,19 @@ macro_rules! is_object {
3200
3205
#[ macro_export]
3201
3206
macro_rules! cast_any {
3202
3207
( $raw: expr) => {
3203
- $crate:: Upcast :: <dyn :: std :: any :: Any >:: upcast( $crate:: read!( $raw) )
3208
+ $crate:: Upcast :: <$crate :: DynAny >:: upcast( $crate:: read!( $raw) )
3204
3209
} ;
3205
3210
}
3206
3211
// cast_any_object is meant to be used on references only, to convert any references (classes or traits)*
3207
3212
// to an Any reference trait
3208
3213
#[ macro_export]
3209
3214
macro_rules! cast_any_object {
3210
3215
( $obj: expr) => {
3211
- $crate:: UpcastObject :: <dyn :: std :: any :: Any >:: upcast( $crate:: md!( $obj) )
3216
+ $crate:: UpcastObject :: <$crate :: DynAny >:: upcast( $crate:: md!( $obj) )
3212
3217
} ;
3213
3218
}
3214
3219
3220
+
3215
3221
// When initializing an uninitialized field for the first time,
3216
3222
// we ensure we don't drop the previous content
3217
3223
// This is problematic if the same field is overwritten multiple times
@@ -3354,12 +3360,12 @@ impl<T: ?Sized> Ptr<T> {
3354
3360
}
3355
3361
}
3356
3362
3357
- impl < T : ?Sized + ' static + Upcast < dyn Any > > Ptr < T > {
3363
+ impl < T : ?Sized + ' static + Upcast < DynAny > > Ptr < T > {
3358
3364
pub fn is_instance_of < U : ' static > ( self ) -> bool {
3359
3365
if self . is_null ( ) {
3360
3366
false
3361
3367
} else {
3362
- read ! ( Upcast :: <dyn Any >:: upcast( read!( self ) ) )
3368
+ read ! ( Upcast :: <DynAny >:: upcast( read!( self ) ) )
3363
3369
. downcast_ref :: < U > ( )
3364
3370
. is_some ( )
3365
3371
}
@@ -3490,10 +3496,10 @@ impl<T: ?Sized> Object<T> {
3490
3496
self . 0 . is_none ( )
3491
3497
}
3492
3498
}
3493
- impl < T : ?Sized + ' static + UpcastObject < dyn Any > > Object < T > {
3499
+ impl < T : ?Sized + ' static + UpcastObject < DynAny > > Object < T > {
3494
3500
pub fn is_instance_of < U : ' static > ( self ) -> bool {
3495
3501
// safety: Dafny won't call this function unless it can guarantee the object is still allocated
3496
- rd ! ( UpcastObject :: <dyn Any >:: upcast( rd!( self ) ) )
3502
+ rd ! ( UpcastObject :: <DynAny >:: upcast( rd!( self ) ) )
3497
3503
. downcast_ref :: < U > ( )
3498
3504
. is_some ( )
3499
3505
}
@@ -3517,14 +3523,14 @@ impl<T: ?Sized> Default for Object<T> {
3517
3523
}
3518
3524
}
3519
3525
3520
- impl < T : ?Sized + UpcastObject < dyn Any > > Debug for Object < T > {
3526
+ impl < T : ?Sized + UpcastObject < DynAny > > Debug for Object < T > {
3521
3527
fn fmt ( & self , f : & mut Formatter ) -> std:: fmt:: Result {
3522
3528
self . fmt_print ( f, false )
3523
3529
}
3524
3530
}
3525
- impl < T : ?Sized + UpcastObject < dyn Any > > DafnyPrint for Object < T > {
3531
+ impl < T : ?Sized + UpcastObject < DynAny > > DafnyPrint for Object < T > {
3526
3532
fn fmt_print ( & self , f : & mut Formatter < ' _ > , _in_seq : bool ) -> std:: fmt:: Result {
3527
- let obj_any = UpcastObject :: < dyn Any > :: upcast ( self . as_ref ( ) ) ;
3533
+ let obj_any = UpcastObject :: < DynAny > :: upcast ( self . as_ref ( ) ) ;
3528
3534
let option_string = obj_any. as_ref ( ) . downcast_ref :: < String > ( ) ;
3529
3535
match option_string {
3530
3536
Some ( s) => write ! ( f, "{}" , s) ,
@@ -3538,11 +3544,10 @@ impl<T: DafnyType> DafnyPrint for Object<[T]> {
3538
3544
write ! ( f, "<object>" )
3539
3545
}
3540
3546
}
3541
-
3542
- impl UpcastObject < dyn Any > for String {
3543
- fn upcast ( & self ) -> Object < dyn Any > {
3547
+ impl UpcastObject < DynAny > for String {
3548
+ fn upcast ( & self ) -> Object < DynAny > {
3544
3549
// SAFETY: RC was just created
3545
- unsafe { Object :: from_rc ( Rc :: new ( self . clone ( ) ) as Rc < dyn Any > ) }
3550
+ unsafe { Object :: from_rc ( Rc :: new ( self . clone ( ) ) as Rc < DynAny > ) }
3546
3551
}
3547
3552
}
3548
3553
@@ -3630,9 +3635,18 @@ pub fn allocate_object<T>() -> Object<T> {
3630
3635
}
3631
3636
3632
3637
pub struct AllocationTracker {
3633
- allocations : Vec < Weak < dyn Any > > ,
3638
+ allocations : Vec < Weak < DynAny > > ,
3634
3639
}
3635
3640
3641
+ #[ cfg( feature = "sync" ) ]
3642
+ pub fn allocate_object_track < T : ' static + Sync + Send > ( allocation_tracker : & mut AllocationTracker ) -> Object < T > {
3643
+ let res = allocate_object :: < T > ( ) ;
3644
+ allocation_tracker
3645
+ . allocations
3646
+ . push ( Rc :: < UnsafeCell < T > > :: downgrade ( & res. 0 . clone ( ) . unwrap ( ) ) ) ;
3647
+ res
3648
+ }
3649
+ #[ cfg( not( feature = "sync" ) ) ]
3636
3650
pub fn allocate_object_track < T : ' static > ( allocation_tracker : & mut AllocationTracker ) -> Object < T > {
3637
3651
let res = allocate_object :: < T > ( ) ;
3638
3652
allocation_tracker
@@ -3778,31 +3792,17 @@ macro_rules! refcount {
3778
3792
}
3779
3793
3780
3794
pub mod object {
3781
- use std:: any:: Any ;
3782
-
3783
- #[ cfg( not( feature = "sync" ) ) ]
3784
- pub fn downcast < T : ' static > ( _self : crate :: Object < dyn Any > ) -> crate :: Object < T > {
3785
- unsafe {
3786
- crate :: Object ( Some ( crate :: rcmut:: downcast :: < T > ( _self. 0 . unwrap ( ) ) . unwrap ( ) ) )
3787
- // Use unwrap_unchecked?
3788
- }
3789
- }
3795
+ use crate :: { Any , DynAny } ;
3790
3796
3791
- #[ cfg( feature = "sync" ) ]
3792
- pub fn downcast < T : ' static + Send + Sync > (
3793
- _self : crate :: Object < dyn Any + Send + Sync > ,
3794
- ) -> crate :: Object < T > {
3795
- unsafe {
3796
- crate :: Object ( Some ( crate :: rcmut:: downcast :: < T > ( _self. 0 . unwrap ( ) ) . unwrap ( ) ) )
3797
- // Use unwrap_unchecked?
3798
- }
3797
+ pub fn downcast < T : ' static > ( _self : crate :: Object < DynAny > ) -> crate :: Object < T > {
3798
+ super :: cast_object!( _self, T )
3799
3799
}
3800
3800
3801
3801
pub fn new < T > ( val : T ) -> crate :: Object < T > {
3802
3802
crate :: Object ( Some ( crate :: rcmut:: new ( val) ) )
3803
3803
}
3804
3804
#[ inline]
3805
- pub fn is < T : ' static + :: std :: any :: Any > ( _self : crate :: Object < dyn Any > ) -> bool {
3805
+ pub fn is < T : ' static + Any > ( _self : crate :: Object < DynAny > ) -> bool {
3806
3806
is_object ! ( _self, T )
3807
3807
}
3808
3808
}
@@ -3875,16 +3875,16 @@ pub mod rcmut {
3875
3875
3876
3876
#[ cfg( feature = "sync" ) ]
3877
3877
pub unsafe fn downcast < T : ' static + Send + Sync > (
3878
- this : RcMut < dyn :: std :: any :: Any + Send + Sync > ,
3878
+ this : RcMut < crate :: DynAny > ,
3879
3879
) -> Option < RcMut < T > > {
3880
- let t: Rc < dyn :: std :: any :: Any + Send + Sync > = to_rc ( this) ;
3880
+ let t: Rc < crate :: DynAny > = to_rc ( this) ;
3881
3881
let t: Rc < T > = Rc :: downcast :: < T > ( t) . ok ( ) ?;
3882
3882
mem:: transmute ( t)
3883
3883
}
3884
3884
3885
3885
#[ cfg( not( feature = "sync" ) ) ]
3886
- pub unsafe fn downcast < T : ' static > ( this : RcMut < dyn :: std :: any :: Any > ) -> Option < RcMut < T > > {
3887
- let t: Rc < dyn :: std :: any :: Any > = to_rc ( this) ;
3886
+ pub unsafe fn downcast < T : ' static > ( this : RcMut < crate :: DynAny > ) -> Option < RcMut < T > > {
3887
+ let t: Rc < crate :: DynAny > = to_rc ( this) ;
3888
3888
let t: Rc < T > = Rc :: downcast :: < T > ( t) . ok ( ) ?;
3889
3889
mem:: transmute ( t)
3890
3890
}
0 commit comments