2
2
3
3
use rustc:: lint:: LateContext ;
4
4
use rustc:: middle:: const_eval:: lookup_const_by_id;
5
- use rustc:: middle:: def:: PathResolution ;
6
- use rustc:: middle:: def:: Def ;
5
+ use rustc:: middle:: def:: { Def , PathResolution } ;
7
6
use rustc_front:: hir:: * ;
8
- use syntax:: ptr:: P ;
9
- use std:: cmp:: PartialOrd ;
10
7
use std:: cmp:: Ordering :: { self , Greater , Less , Equal } ;
11
- use std:: rc:: Rc ;
8
+ use std:: cmp:: PartialOrd ;
9
+ use std:: hash:: { Hash , Hasher } ;
10
+ use std:: mem;
12
11
use std:: ops:: Deref ;
13
-
14
- use syntax:: ast:: Lit_ ;
15
- use syntax:: ast:: LitIntType ;
16
- use syntax:: ast:: { UintTy , FloatTy , StrStyle } ;
12
+ use std:: rc:: Rc ;
13
+ use syntax:: ast:: { LitIntType , Lit_ } ;
17
14
use syntax:: ast:: Sign :: { self , Plus , Minus } ;
15
+ use syntax:: ast:: { UintTy , FloatTy , StrStyle } ;
16
+ use syntax:: ptr:: P ;
18
17
19
18
20
- #[ derive( PartialEq , Eq , Debug , Copy , Clone , Hash ) ]
19
+ #[ derive( Debug , Copy , Clone ) ]
21
20
pub enum FloatWidth {
22
21
Fw32 ,
23
22
Fw64 ,
@@ -34,7 +33,7 @@ impl From<FloatTy> for FloatWidth {
34
33
}
35
34
36
35
/// a Lit_-like enum to fold constant `Expr`s into
37
- #[ derive( Eq , Debug , Clone , Hash ) ]
36
+ #[ derive( Debug , Clone ) ]
38
37
pub enum Constant {
39
38
/// a String "abc"
40
39
Str ( String , StrStyle ) ,
@@ -100,18 +99,12 @@ impl PartialEq for Constant {
100
99
( & Constant :: Int ( lv, lty) , & Constant :: Int ( rv, rty) ) => {
101
100
lv == rv && ( is_negative ( lty) & ( lv != 0 ) ) == ( is_negative ( rty) & ( rv != 0 ) )
102
101
}
103
- ( & Constant :: Float ( ref ls, lw) , & Constant :: Float ( ref rs, rw) ) => {
104
- use self :: FloatWidth :: * ;
105
- if match ( lw, rw) {
106
- ( FwAny , _) | ( _, FwAny ) | ( Fw32 , Fw32 ) | ( Fw64 , Fw64 ) => true ,
102
+ ( & Constant :: Float ( ref ls, _) , & Constant :: Float ( ref rs, _) ) => {
103
+ // we want `Fw32 == FwAny` and `FwAny == Fw64`, by transitivity we must have
104
+ // `Fw32 == Fw64` so don’t compare them
105
+ match ( ls. parse :: < f64 > ( ) , rs. parse :: < f64 > ( ) ) {
106
+ ( Ok ( l) , Ok ( r) ) => l. eq ( & r) ,
107
107
_ => false ,
108
- } {
109
- match ( ls. parse :: < f64 > ( ) , rs. parse :: < f64 > ( ) ) {
110
- ( Ok ( l) , Ok ( r) ) => l. eq ( & r) ,
111
- _ => false ,
112
- }
113
- } else {
114
- false
115
108
}
116
109
}
117
110
( & Constant :: Bool ( l) , & Constant :: Bool ( r) ) => l == r,
@@ -123,6 +116,46 @@ impl PartialEq for Constant {
123
116
}
124
117
}
125
118
119
+ impl Hash for Constant {
120
+ fn hash < H > ( & self , state : & mut H ) where H : Hasher {
121
+ match * self {
122
+ Constant :: Str ( ref s, ref k) => {
123
+ s. hash ( state) ;
124
+ k. hash ( state) ;
125
+ }
126
+ Constant :: Binary ( ref b) => {
127
+ b. hash ( state) ;
128
+ }
129
+ Constant :: Byte ( u) => {
130
+ u. hash ( state) ;
131
+ }
132
+ Constant :: Char ( c) => {
133
+ c. hash ( state) ;
134
+ }
135
+ Constant :: Int ( u, t) => {
136
+ u. hash ( state) ;
137
+ t. hash ( state) ;
138
+ }
139
+ Constant :: Float ( ref f, _) => {
140
+ // don’t use the width here because of PartialEq implementation
141
+ if let Ok ( f) = f. parse :: < f64 > ( ) {
142
+ unsafe { mem:: transmute :: < f64 , u64 > ( f) } . hash ( state) ;
143
+ }
144
+ }
145
+ Constant :: Bool ( b) => {
146
+ b. hash ( state) ;
147
+ }
148
+ Constant :: Vec ( ref v) | Constant :: Tuple ( ref v) => {
149
+ v. hash ( state) ;
150
+ }
151
+ Constant :: Repeat ( ref c, l) => {
152
+ c. hash ( state) ;
153
+ l. hash ( state) ;
154
+ }
155
+ }
156
+ }
157
+ }
158
+
126
159
impl PartialOrd for Constant {
127
160
fn partial_cmp ( & self , other : & Constant ) -> Option < Ordering > {
128
161
match ( self , other) {
@@ -143,18 +176,10 @@ impl PartialOrd for Constant {
143
176
( false , true ) => Greater ,
144
177
} )
145
178
}
146
- ( & Constant :: Float ( ref ls, lw) , & Constant :: Float ( ref rs, rw) ) => {
147
- use self :: FloatWidth :: * ;
148
- if match ( lw, rw) {
149
- ( FwAny , _) | ( _, FwAny ) | ( Fw32 , Fw32 ) | ( Fw64 , Fw64 ) => true ,
150
- _ => false ,
151
- } {
152
- match ( ls. parse :: < f64 > ( ) , rs. parse :: < f64 > ( ) ) {
153
- ( Ok ( ref l) , Ok ( ref r) ) => l. partial_cmp ( r) ,
154
- _ => None ,
155
- }
156
- } else {
157
- None
179
+ ( & Constant :: Float ( ref ls, _) , & Constant :: Float ( ref rs, _) ) => {
180
+ match ( ls. parse :: < f64 > ( ) , rs. parse :: < f64 > ( ) ) {
181
+ ( Ok ( ref l) , Ok ( ref r) ) => l. partial_cmp ( r) ,
182
+ _ => None ,
158
183
}
159
184
}
160
185
( & Constant :: Bool ( ref l) , & Constant :: Bool ( ref r) ) => Some ( l. cmp ( r) ) ,
0 commit comments