@@ -11,7 +11,7 @@ use num_bigint::BigInt;
1111use num_complex:: Complex64 ;
1212use serde:: { Deserialize , Serialize } ;
1313use std:: collections:: BTreeSet ;
14- use std:: fmt;
14+ use std:: { fmt, hash } ;
1515
1616/// Sourcecode location.
1717#[ derive( Clone , Copy , Debug , Default , PartialEq , Serialize , Deserialize ) ]
@@ -103,7 +103,7 @@ impl ConstantBag for BasicBag {
103103
104104/// Primary container of a single code object. Each python function has
105105/// a codeobject. Also a module has a codeobject.
106- #[ derive( Clone , PartialEq , Serialize , Deserialize ) ]
106+ #[ derive( Clone , Serialize , Deserialize ) ]
107107pub struct CodeObject < C : Constant = ConstantData > {
108108 pub instructions : Box < [ Instruction ] > ,
109109 pub locations : Box < [ Location ] > ,
@@ -400,20 +400,66 @@ bitflags! {
400400 }
401401}
402402
403- #[ derive( Debug , Clone , PartialEq , Serialize , Deserialize ) ]
403+ #[ derive( Debug , Clone , Serialize , Deserialize ) ]
404404pub enum ConstantData {
405+ Tuple { elements : Vec < ConstantData > } ,
405406 Integer { value : BigInt } ,
406407 Float { value : f64 } ,
407408 Complex { value : Complex64 } ,
408409 Boolean { value : bool } ,
409410 Str { value : String } ,
410411 Bytes { value : Vec < u8 > } ,
411412 Code { code : Box < CodeObject > } ,
412- Tuple { elements : Vec < ConstantData > } ,
413413 None ,
414414 Ellipsis ,
415415}
416416
417+ impl PartialEq for ConstantData {
418+ fn eq ( & self , other : & Self ) -> bool {
419+ use ConstantData :: * ;
420+ match ( self , other) {
421+ ( Integer { value : a } , Integer { value : b } ) => a == b,
422+ // we want to compare floats *by actual value* - if we have the *exact same* float
423+ // already in a constant cache, we want to use that
424+ ( Float { value : a } , Float { value : b } ) => a. to_bits ( ) == b. to_bits ( ) ,
425+ ( Complex { value : a } , Complex { value : b } ) => {
426+ a. re . to_bits ( ) == b. re . to_bits ( ) && a. im . to_bits ( ) == b. im . to_bits ( )
427+ }
428+ ( Boolean { value : a } , Boolean { value : b } ) => a == b,
429+ ( Str { value : a } , Str { value : b } ) => a == b,
430+ ( Bytes { value : a } , Bytes { value : b } ) => a == b,
431+ ( Code { code : a } , Code { code : b } ) => std:: ptr:: eq ( a. as_ref ( ) , b. as_ref ( ) ) ,
432+ ( Tuple { elements : a } , Tuple { elements : b } ) => a == b,
433+ ( None , None ) => true ,
434+ ( Ellipsis , Ellipsis ) => true ,
435+ _ => false ,
436+ }
437+ }
438+ }
439+ impl Eq for ConstantData { }
440+
441+ impl hash:: Hash for ConstantData {
442+ fn hash < H : hash:: Hasher > ( & self , state : & mut H ) {
443+ use ConstantData :: * ;
444+ std:: mem:: discriminant ( self ) . hash ( state) ;
445+ match self {
446+ Integer { value } => value. hash ( state) ,
447+ Float { value } => value. to_bits ( ) . hash ( state) ,
448+ Complex { value } => {
449+ value. re . to_bits ( ) . hash ( state) ;
450+ value. im . to_bits ( ) . hash ( state) ;
451+ }
452+ Boolean { value } => value. hash ( state) ,
453+ Str { value } => value. hash ( state) ,
454+ Bytes { value } => value. hash ( state) ,
455+ Code { code } => std:: ptr:: hash ( code. as_ref ( ) , state) ,
456+ Tuple { elements } => elements. hash ( state) ,
457+ None => { }
458+ Ellipsis => { }
459+ }
460+ }
461+ }
462+
417463pub enum BorrowedConstant < ' a , C : Constant > {
418464 Integer { value : & ' a BigInt } ,
419465 Float { value : f64 } ,
0 commit comments