@@ -21,20 +21,16 @@ use std::ops::Mul;
21
21
use std:: ops:: Sub ;
22
22
23
23
use dupe:: Dupe ;
24
- use either:: Either ;
25
24
26
25
use crate as starlark;
27
26
use crate :: collections:: StarlarkHashValue ;
28
- use crate :: typing:: Ty ;
29
27
use crate :: values:: type_repr:: StarlarkTypeRepr ;
30
28
use crate :: values:: types:: float:: StarlarkFloat ;
31
29
use crate :: values:: types:: int_or_big:: StarlarkInt ;
32
30
use crate :: values:: types:: int_or_big:: StarlarkIntRef ;
33
31
use crate :: values:: AllocFrozenValue ;
34
32
use crate :: values:: AllocValue ;
35
33
use crate :: values:: UnpackValue ;
36
- use crate :: values:: Value ;
37
- use crate :: values:: ValueLike ;
38
34
39
35
#[ derive( Debug , thiserror:: Error ) ]
40
36
enum NumError {
@@ -47,10 +43,11 @@ enum NumError {
47
43
/// It's an intermediate representation that facilitates conversions between
48
44
/// numerical types and helps in implementation of arithmetical operations
49
45
/// between them.
50
- #[ derive( Clone , Debug , Dupe , Copy ) ]
46
+ #[ derive( Clone , Debug , Dupe , Copy , StarlarkTypeRepr , UnpackValue ) ]
51
47
pub ( crate ) enum NumRef < ' v > {
52
48
Int ( StarlarkIntRef < ' v > ) ,
53
- Float ( f64 ) ,
49
+ // `StarlarkFloat` not `f64` here because `f64` unpacks from `int` too.
50
+ Float ( StarlarkFloat ) ,
54
51
}
55
52
56
53
#[ derive(
@@ -65,35 +62,12 @@ pub(crate) enum Num {
65
62
Float ( f64 ) ,
66
63
}
67
64
68
- impl < ' v > StarlarkTypeRepr for NumRef < ' v > {
69
- fn starlark_type_repr ( ) -> Ty {
70
- Either :: < StarlarkIntRef , StarlarkFloat > :: starlark_type_repr ( )
71
- }
72
- }
73
-
74
- impl < ' v > UnpackValue < ' v > for NumRef < ' v > {
75
- fn expected ( ) -> String {
76
- "int or float" . to_owned ( )
77
- }
78
-
79
- #[ allow( clippy:: manual_map) ]
80
- fn unpack_value ( value : Value < ' v > ) -> Option < Self > {
81
- if let Some ( i) = StarlarkIntRef :: unpack_value ( value) {
82
- Some ( NumRef :: Int ( i) )
83
- } else if let Some ( f) = value. downcast_ref :: < StarlarkFloat > ( ) {
84
- Some ( NumRef :: Float ( f. 0 ) )
85
- } else {
86
- None
87
- }
88
- }
89
- }
90
-
91
65
impl < ' v > NumRef < ' v > {
92
66
/// Get underlying value as float
93
67
pub ( crate ) fn as_float ( & self ) -> f64 {
94
68
match self {
95
69
Self :: Int ( i) => i. to_f64 ( ) ,
96
- Self :: Float ( f) => * f ,
70
+ Self :: Float ( f) => f . 0 ,
97
71
}
98
72
}
99
73
@@ -106,7 +80,7 @@ impl<'v> NumRef<'v> {
106
80
pub ( crate ) fn as_int ( & self ) -> Option < i32 > {
107
81
match self {
108
82
Self :: Int ( i) => i. to_i32 ( ) ,
109
- Self :: Float ( f) => Self :: f64_to_i32_exact ( * f ) ,
83
+ Self :: Float ( f) => Self :: f64_to_i32_exact ( f . 0 ) ,
110
84
}
111
85
}
112
86
@@ -129,7 +103,7 @@ impl<'v> NumRef<'v> {
129
103
match ( self . as_int ( ) , self ) {
130
104
// equal ints and floats should have the same hash
131
105
( Some ( i) , _) => i as u64 ,
132
- ( None , Self :: Float ( f) ) => float_hash ( f) ,
106
+ ( None , Self :: Float ( f) ) => float_hash ( f. 0 ) ,
133
107
( None , Self :: Int ( StarlarkIntRef :: Small ( i) ) ) => {
134
108
// shouldn't happen - as_int() should have resulted in an int
135
109
i. to_i32 ( ) as u64
@@ -150,7 +124,7 @@ impl<'v> NumRef<'v> {
150
124
fn to_owned ( self ) -> Num {
151
125
match self {
152
126
NumRef :: Int ( i) => Num :: Int ( i. to_owned ( ) ) ,
153
- NumRef :: Float ( f) => Num :: Float ( f) ,
127
+ NumRef :: Float ( f) => Num :: Float ( f. 0 ) ,
154
128
}
155
129
}
156
130
@@ -183,7 +157,7 @@ impl<'v> NumRef<'v> {
183
157
184
158
impl < ' v > From < f64 > for NumRef < ' v > {
185
159
fn from ( f : f64 ) -> Self {
186
- Self :: Float ( f )
160
+ Self :: Float ( StarlarkFloat ( f ) )
187
161
}
188
162
}
189
163
@@ -255,6 +229,7 @@ mod tests {
255
229
256
230
use super :: * ;
257
231
use crate :: values:: types:: inline_int:: InlineInt ;
232
+ use crate :: values:: Value ;
258
233
259
234
#[ test]
260
235
fn test_from_value ( ) {
@@ -298,8 +273,8 @@ mod tests {
298
273
InlineInt :: MIN . to_f64( )
299
274
) ;
300
275
301
- assert_eq ! ( NumRef :: Float ( 0.0 ) . as_float( ) , 0.0 ) ;
302
- assert ! ( NumRef :: Float ( f64 :: NAN ) . as_float( ) . is_nan( ) ) ;
276
+ assert_eq ! ( NumRef :: Float ( StarlarkFloat ( 0.0 ) ) . as_float( ) , 0.0 ) ;
277
+ assert ! ( NumRef :: Float ( StarlarkFloat ( f64 :: NAN ) ) . as_float( ) . is_nan( ) ) ;
303
278
}
304
279
305
280
#[ test]
@@ -317,55 +292,70 @@ mod tests {
317
292
Some ( -42 )
318
293
) ;
319
294
320
- assert_eq ! ( NumRef :: Float ( 0_f64 ) . as_int( ) , Some ( 0 ) ) ;
321
- assert_eq ! ( NumRef :: Float ( 42_f64 ) . as_int( ) , Some ( 42 ) ) ;
322
- assert_eq ! ( NumRef :: Float ( -42_f64 ) . as_int( ) , Some ( -42 ) ) ;
295
+ assert_eq ! ( NumRef :: Float ( StarlarkFloat ( 0_f64 ) ) . as_int( ) , Some ( 0 ) ) ;
296
+ assert_eq ! ( NumRef :: Float ( StarlarkFloat ( 42_f64 ) ) . as_int( ) , Some ( 42 ) ) ;
297
+ assert_eq ! ( NumRef :: Float ( StarlarkFloat ( -42_f64 ) ) . as_int( ) , Some ( -42 ) ) ;
323
298
324
- assert_eq ! ( NumRef :: Float ( i32 :: MIN as f64 ) . as_int( ) , Some ( i32 :: MIN ) ) ;
325
- assert_eq ! ( NumRef :: Float ( i32 :: MAX as f64 ) . as_int( ) , Some ( i32 :: MAX ) ) ;
299
+ assert_eq ! (
300
+ NumRef :: Float ( StarlarkFloat ( i32 :: MIN as f64 ) ) . as_int( ) ,
301
+ Some ( i32 :: MIN )
302
+ ) ;
303
+ assert_eq ! (
304
+ NumRef :: Float ( StarlarkFloat ( i32 :: MAX as f64 ) ) . as_int( ) ,
305
+ Some ( i32 :: MAX )
306
+ ) ;
326
307
327
- assert_eq ! ( NumRef :: Float ( 42.75 ) . as_int( ) , None ) ;
328
- assert_eq ! ( NumRef :: Float ( -42.75 ) . as_int( ) , None ) ;
329
- assert_eq ! ( NumRef :: Float ( f64 :: NAN ) . as_int( ) , None ) ;
330
- assert_eq ! ( NumRef :: Float ( f64 :: INFINITY ) . as_int( ) , None ) ;
331
- assert_eq ! ( NumRef :: Float ( f64 :: NEG_INFINITY ) . as_int( ) , None ) ;
308
+ assert_eq ! ( NumRef :: Float ( StarlarkFloat ( 42.75 ) ) . as_int( ) , None ) ;
309
+ assert_eq ! ( NumRef :: Float ( StarlarkFloat ( -42.75 ) ) . as_int( ) , None ) ;
310
+ assert_eq ! ( NumRef :: Float ( StarlarkFloat ( f64 :: NAN ) ) . as_int( ) , None ) ;
311
+ assert_eq ! ( NumRef :: Float ( StarlarkFloat ( f64 :: INFINITY ) ) . as_int( ) , None ) ;
312
+ assert_eq ! (
313
+ NumRef :: Float ( StarlarkFloat ( f64 :: NEG_INFINITY ) ) . as_int( ) ,
314
+ None
315
+ ) ;
332
316
}
333
317
334
318
#[ test]
335
319
fn test_hashing ( ) {
336
320
assert_eq ! (
337
321
NumRef :: Int ( StarlarkIntRef :: Small ( InlineInt :: testing_new( 0 ) ) ) . get_hash_64( ) ,
338
- NumRef :: Float ( 0.0 ) . get_hash_64( )
322
+ NumRef :: Float ( StarlarkFloat ( 0.0 ) ) . get_hash_64( )
339
323
) ;
340
324
assert_eq ! (
341
325
NumRef :: Int ( StarlarkIntRef :: Small ( InlineInt :: testing_new( 42 ) ) ) . get_hash_64( ) ,
342
- NumRef :: Float ( 42.0 ) . get_hash_64( )
326
+ NumRef :: Float ( StarlarkFloat ( 42.0 ) ) . get_hash_64( )
343
327
) ;
344
328
345
329
assert_eq ! (
346
- NumRef :: Float ( f64 :: INFINITY + f64 :: NEG_INFINITY ) . get_hash_64( ) ,
347
- NumRef :: Float ( f64 :: NAN ) . get_hash_64( )
330
+ NumRef :: Float ( StarlarkFloat ( f64 :: INFINITY + f64 :: NEG_INFINITY ) ) . get_hash_64( ) ,
331
+ NumRef :: Float ( StarlarkFloat ( f64 :: NAN ) ) . get_hash_64( )
348
332
) ;
349
333
assert_eq ! (
350
- NumRef :: Float ( "0.25" . parse( ) . unwrap( ) ) . get_hash_64( ) ,
351
- NumRef :: Float ( "25e-2" . parse( ) . unwrap( ) ) . get_hash_64( )
334
+ NumRef :: Float ( StarlarkFloat ( "0.25" . parse( ) . unwrap( ) ) ) . get_hash_64( ) ,
335
+ NumRef :: Float ( StarlarkFloat ( "25e-2" . parse( ) . unwrap( ) ) ) . get_hash_64( )
352
336
) ;
353
337
354
338
let x = 1u64 << 55 ;
355
339
assert_eq ! ( x as f64 as u64 , x, "Self-check" ) ;
356
340
assert_eq ! (
357
- NumRef :: Float ( x as f64 ) . get_hash_64( ) ,
341
+ NumRef :: Float ( StarlarkFloat ( x as f64 ) ) . get_hash_64( ) ,
358
342
NumRef :: Int ( StarlarkInt :: from( BigInt :: from( x) ) . as_ref( ) ) . get_hash_64( ) ,
359
343
)
360
344
}
361
345
362
346
#[ test]
363
347
fn test_eq ( ) {
364
- assert_eq ! ( NumRef :: Float ( f64 :: NAN ) , NumRef :: Float ( f64 :: NAN ) ) ;
365
- assert_eq ! ( NumRef :: Float ( f64 :: INFINITY ) , NumRef :: Float ( f64 :: INFINITY ) ) ;
348
+ assert_eq ! (
349
+ NumRef :: Float ( StarlarkFloat ( f64 :: NAN ) ) ,
350
+ NumRef :: Float ( StarlarkFloat ( f64 :: NAN ) )
351
+ ) ;
352
+ assert_eq ! (
353
+ NumRef :: Float ( StarlarkFloat ( f64 :: INFINITY ) ) ,
354
+ NumRef :: Float ( StarlarkFloat ( f64 :: INFINITY ) )
355
+ ) ;
366
356
assert_eq ! (
367
357
NumRef :: Int ( StarlarkIntRef :: Small ( InlineInt :: testing_new( 10 ) ) ) ,
368
- NumRef :: Float ( 10.0 )
358
+ NumRef :: Float ( StarlarkFloat ( 10.0 ) )
369
359
) ;
370
360
}
371
361
}
0 commit comments