1
1
use consts:: constant;
2
2
use rustc:: lint:: * ;
3
3
use rustc:: hir:: * ;
4
- use rustc:: hir:: def:: Def ;
5
4
use std:: hash:: { Hash , Hasher } ;
6
5
use std:: collections:: hash_map:: DefaultHasher ;
7
6
use syntax:: ast:: { Name , NodeId } ;
@@ -104,8 +103,8 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
104
103
( & ExprLoop ( ref lb, ref ll, _) , & ExprLoop ( ref rb, ref rl, _) ) => {
105
104
self . eq_block ( lb, rb) && both ( ll, rl, |l, r| l. node . as_str ( ) == r. node . as_str ( ) )
106
105
}
107
- ( & ExprMatch ( ref le, ref la, _ ) , & ExprMatch ( ref re, ref ra, _ ) ) => {
108
- self . eq_expr ( le, re) &&
106
+ ( & ExprMatch ( ref le, ref la, ref ls ) , & ExprMatch ( ref re, ref ra, ref rs ) ) => {
107
+ ls == rs && self . eq_expr ( le, re) &&
109
108
over ( la, ra, |l, r| {
110
109
self . eq_expr ( & l. body , & r. body ) && both ( & l. guard , & r. guard , |l, r| self . eq_expr ( l, r) ) &&
111
110
over ( & l. pats , & r. pats , |l, r| self . eq_pat ( l, r) )
@@ -119,10 +118,9 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
119
118
}
120
119
( & ExprRepeat ( ref le, ref ll) , & ExprRepeat ( ref re, ref rl) ) => self . eq_expr ( le, re) && self . eq_expr ( ll, rl) ,
121
120
( & ExprRet ( ref l) , & ExprRet ( ref r) ) => both ( l, r, |l, r| self . eq_expr ( l, r) ) ,
122
- ( & ExprPath ( ref l) , & ExprPath ( ref r) ) => self . eq_qpath ( l, left . id , r , right . id ) ,
121
+ ( & ExprPath ( ref l) , & ExprPath ( ref r) ) => self . eq_qpath ( l, r ) ,
123
122
( & ExprStruct ( ref l_path, ref lf, ref lo) , & ExprStruct ( ref r_path, ref rf, ref ro) ) => {
124
- self . eq_qpath ( l_path, left. id , r_path, right. id ) &&
125
- both ( lo, ro, |l, r| self . eq_expr ( l, r) ) &&
123
+ self . eq_qpath ( l_path, r_path) && both ( lo, ro, |l, r| self . eq_expr ( l, r) ) &&
126
124
over ( lf, rf, |l, r| self . eq_field ( l, r) )
127
125
}
128
126
( & ExprTup ( ref l_tup) , & ExprTup ( ref r_tup) ) => self . eq_exprs ( l_tup, r_tup) ,
@@ -144,17 +142,21 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
144
142
left. name . node == right. name . node && self . eq_expr ( & left. expr , & right. expr )
145
143
}
146
144
145
+ fn eq_lifetime ( & self , left : & Lifetime , right : & Lifetime ) -> bool {
146
+ left. name == right. name
147
+ }
148
+
147
149
/// Check whether two patterns are the same.
148
150
pub fn eq_pat ( & self , left : & Pat , right : & Pat ) -> bool {
149
151
match ( & left. node , & right. node ) {
150
152
( & PatKind :: Box ( ref l) , & PatKind :: Box ( ref r) ) => self . eq_pat ( l, r) ,
151
153
( & PatKind :: TupleStruct ( ref lp, ref la, ls) , & PatKind :: TupleStruct ( ref rp, ref ra, rs) ) => {
152
- self . eq_qpath ( lp, left . id , rp , right . id ) && over ( la, ra, |l, r| self . eq_pat ( l, r) ) && ls == rs
154
+ self . eq_qpath ( lp, rp ) && over ( la, ra, |l, r| self . eq_pat ( l, r) ) && ls == rs
153
155
}
154
- ( & PatKind :: Binding ( ref lb, _ , ref li, ref lp) , & PatKind :: Binding ( ref rb, _ , ref ri, ref rp) ) => {
155
- lb == rb && li. node . as_str ( ) == ri. node . as_str ( ) && both ( lp, rp, |l, r| self . eq_pat ( l, r) )
156
+ ( & PatKind :: Binding ( ref lb, ref ld , ref li, ref lp) , & PatKind :: Binding ( ref rb, ref rd , ref ri, ref rp) ) => {
157
+ lb == rb && ld == rd && li. node . as_str ( ) == ri. node . as_str ( ) && both ( lp, rp, |l, r| self . eq_pat ( l, r) )
156
158
}
157
- ( & PatKind :: Path ( ref l) , & PatKind :: Path ( ref r) ) => self . eq_qpath ( l, left . id , r , right . id ) ,
159
+ ( & PatKind :: Path ( ref l) , & PatKind :: Path ( ref r) ) => self . eq_qpath ( l, r ) ,
158
160
( & PatKind :: Lit ( ref l) , & PatKind :: Lit ( ref r) ) => self . eq_expr ( l, r) ,
159
161
( & PatKind :: Tuple ( ref l, ls) , & PatKind :: Tuple ( ref r, rs) ) => {
160
162
ls == rs && over ( l, r, |l, r| self . eq_pat ( l, r) )
@@ -172,23 +174,48 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
172
174
}
173
175
}
174
176
175
- fn eq_qpath ( & self , left : & QPath , lid : NodeId , right : & QPath , rid : NodeId ) -> bool {
176
- let l = self . cx . tcx . tables ( ) . qpath_def ( left, lid) ;
177
- let r = self . cx . tcx . tables ( ) . qpath_def ( right, rid) ;
177
+ fn eq_qpath ( & self , left : & QPath , right : & QPath ) -> bool {
178
+ match ( left, right) {
179
+ ( & QPath :: Resolved ( ref lty, ref lpath) , & QPath :: Resolved ( ref rty, ref rpath) ) => {
180
+ both ( lty, rty, |l, r| self . eq_ty ( l, r) ) && self . eq_path ( lpath, rpath)
181
+ } ,
182
+ ( & QPath :: TypeRelative ( ref lty, ref lseg) , & QPath :: TypeRelative ( ref rty, ref rseg) ) => {
183
+ self . eq_ty ( lty, rty) && self . eq_path_segment ( lseg, rseg)
184
+ } ,
185
+ _ => false ,
186
+ }
187
+ }
188
+
189
+ fn eq_path ( & self , left : & Path , right : & Path ) -> bool {
190
+ left. global == right. global &&
191
+ over ( & left. segments , & right. segments , |l, r| self . eq_path_segment ( l, r) )
192
+ }
178
193
179
- if let ( Def :: Local ( _) , Def :: Local ( _) ) = ( l, r) {
180
- if let ( & QPath :: Resolved ( None , ref l) , & QPath :: Resolved ( None , ref r) ) = ( left, right) {
181
- assert_eq ! ( l. segments. len( ) , 1 ) ;
182
- assert_eq ! ( r. segments. len( ) , 1 ) ;
183
- l. segments [ 0 ] . name == r. segments [ 0 ] . name
184
- } else {
185
- unreachable ! ( ) ;
194
+ fn eq_path_parameters ( & self , left : & PathParameters , right : & PathParameters ) -> bool {
195
+ match ( left, right) {
196
+ ( & AngleBracketedParameters ( ref left) , & AngleBracketedParameters ( ref right) ) => {
197
+ over ( & left. lifetimes , & right. lifetimes , |l, r| self . eq_lifetime ( l, r) ) &&
198
+ over ( & left. types , & right. types , |l, r| self . eq_ty ( l, r) ) &&
199
+ over ( & left. bindings , & right. bindings , |l, r| self . eq_type_binding ( l, r) )
200
+ }
201
+ ( & ParenthesizedParameters ( ref left) , & ParenthesizedParameters ( ref right) ) => {
202
+ over ( & left. inputs , & right. inputs , |l, r| self . eq_ty ( l, r) ) &&
203
+ both ( & left. output , & right. output , |l, r| self . eq_ty ( l, r) )
204
+ }
205
+ ( & AngleBracketedParameters ( _) , & ParenthesizedParameters ( _) ) |
206
+ ( & ParenthesizedParameters ( _) , & AngleBracketedParameters ( _) ) => {
207
+ false
186
208
}
187
- } else {
188
- l == r
189
209
}
190
210
}
191
211
212
+ fn eq_path_segment ( & self , left : & PathSegment , right : & PathSegment ) -> bool {
213
+ // The == of idents doesn't work with different contexts,
214
+ // we have to be explicit about hygiene
215
+ left. name . as_str ( ) == right. name . as_str ( ) &&
216
+ self . eq_path_parameters ( & left. parameters , & right. parameters )
217
+ }
218
+
192
219
fn eq_ty ( & self , left : & Ty , right : & Ty ) -> bool {
193
220
match ( & left. node , & right. node ) {
194
221
( & TySlice ( ref l_vec) , & TySlice ( ref r_vec) ) => self . eq_ty ( l_vec, r_vec) ,
@@ -199,12 +226,16 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
199
226
( & TyRptr ( _, ref l_rmut) , & TyRptr ( _, ref r_rmut) ) => {
200
227
l_rmut. mutbl == r_rmut. mutbl && self . eq_ty ( & * l_rmut. ty , & * r_rmut. ty )
201
228
}
202
- ( & TyPath ( ref l) , & TyPath ( ref r) ) => self . eq_qpath ( l, left . id , r , right . id ) ,
229
+ ( & TyPath ( ref l) , & TyPath ( ref r) ) => self . eq_qpath ( l, r ) ,
203
230
( & TyTup ( ref l) , & TyTup ( ref r) ) => over ( l, r, |l, r| self . eq_ty ( l, r) ) ,
204
231
( & TyInfer , & TyInfer ) => true ,
205
232
_ => false ,
206
233
}
207
234
}
235
+
236
+ fn eq_type_binding ( & self , left : & TypeBinding , right : & TypeBinding ) -> bool {
237
+ left. name == right. name && self . eq_ty ( & left. ty , & right. ty )
238
+ }
208
239
}
209
240
210
241
fn swap_binop < ' a > ( binop : BinOp_ , lhs : & ' a Expr , rhs : & ' a Expr ) -> Option < ( BinOp_ , & ' a Expr , & ' a Expr ) > {
@@ -388,7 +419,7 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
388
419
self . hash_name ( & i. node ) ;
389
420
}
390
421
}
391
- ExprMatch ( ref e, ref arms, _ ) => {
422
+ ExprMatch ( ref e, ref arms, ref s ) => {
392
423
let c: fn ( _, _, _) -> _ = ExprMatch ;
393
424
c. hash ( & mut self . s ) ;
394
425
self . hash_expr ( e) ;
@@ -400,6 +431,8 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
400
431
}
401
432
self . hash_expr ( & arm. body ) ;
402
433
}
434
+
435
+ s. hash ( & mut self . s ) ;
403
436
}
404
437
ExprMethodCall ( ref name, ref _tys, ref args) => {
405
438
let c: fn ( _, _, _) -> _ = ExprMethodCall ;
@@ -495,19 +528,7 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
495
528
}
496
529
497
530
pub fn hash_qpath ( & mut self , p : & QPath , id : NodeId ) {
498
- let def = self . cx . tcx . tables ( ) . qpath_def ( p, id) ;
499
- if let Def :: Local ( _) = def {
500
- true . hash ( & mut self . s ) ;
501
- if let QPath :: Resolved ( None , ref seq) = * p {
502
- assert_eq ! ( seq. segments. len( ) , 1 ) ;
503
- self . hash_name ( & seq. segments [ 0 ] . name ) ;
504
- } else {
505
- unreachable ! ( ) ;
506
- }
507
- } else {
508
- false . hash ( & mut self . s ) ;
509
- def. hash ( & mut self . s ) ;
510
- }
531
+ self . cx . tcx . tables ( ) . qpath_def ( p, id) . hash ( & mut self . s ) ;
511
532
}
512
533
513
534
pub fn hash_path ( & mut self , p : & Path ) {
0 commit comments