1
1
use consts:: constant;
2
2
use rustc:: lint:: * ;
3
3
use rustc:: hir:: * ;
4
+ use rustc:: hir:: def:: Def ;
4
5
use std:: hash:: { Hash , Hasher } ;
5
6
use std:: collections:: hash_map:: DefaultHasher ;
6
7
use syntax:: ast:: { Name , NodeId } ;
@@ -103,8 +104,8 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
103
104
( & ExprLoop ( ref lb, ref ll, ref lls) , & ExprLoop ( ref rb, ref rl, ref rls) ) => {
104
105
self . eq_block ( lb, rb) && both ( ll, rl, |l, r| l. node . as_str ( ) == r. node . as_str ( ) ) && lls == rls
105
106
}
106
- ( & ExprMatch ( ref le, ref la, ref ls ) , & ExprMatch ( ref re, ref ra, ref rs ) ) => {
107
- ls == rs && self . eq_expr ( le, re) &&
107
+ ( & ExprMatch ( ref le, ref la, _ ) , & ExprMatch ( ref re, ref ra, _ ) ) => {
108
+ self . eq_expr ( le, re) &&
108
109
over ( la, ra, |l, r| {
109
110
self . eq_expr ( & l. body , & r. body ) && both ( & l. guard , & r. guard , |l, r| self . eq_expr ( l, r) ) &&
110
111
over ( & l. pats , & r. pats , |l, r| self . eq_pat ( l, r) )
@@ -118,9 +119,10 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
118
119
}
119
120
( & ExprRepeat ( ref le, ref ll) , & ExprRepeat ( ref re, ref rl) ) => self . eq_expr ( le, re) && self . eq_expr ( ll, rl) ,
120
121
( & ExprRet ( ref l) , & ExprRet ( ref r) ) => both ( l, r, |l, r| self . eq_expr ( l, r) ) ,
121
- ( & ExprPath ( ref l) , & ExprPath ( ref r) ) => self . eq_qpath ( l, r ) ,
122
+ ( & ExprPath ( ref l) , & ExprPath ( ref r) ) => self . eq_qpath ( l, left . id , r , right . id ) ,
122
123
( & ExprStruct ( ref l_path, ref lf, ref lo) , & ExprStruct ( ref r_path, ref rf, ref ro) ) => {
123
- self . eq_qpath ( l_path, r_path) && both ( lo, ro, |l, r| self . eq_expr ( l, r) ) &&
124
+ self . eq_qpath ( l_path, left. id , r_path, right. id ) &&
125
+ both ( lo, ro, |l, r| self . eq_expr ( l, r) ) &&
124
126
over ( lf, rf, |l, r| self . eq_field ( l, r) )
125
127
}
126
128
( & ExprTup ( ref l_tup) , & ExprTup ( ref r_tup) ) => self . eq_exprs ( l_tup, r_tup) ,
@@ -142,21 +144,17 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
142
144
left. name . node == right. name . node && self . eq_expr ( & left. expr , & right. expr )
143
145
}
144
146
145
- fn eq_lifetime ( & self , left : & Lifetime , right : & Lifetime ) -> bool {
146
- left. name == right. name
147
- }
148
-
149
147
/// Check whether two patterns are the same.
150
148
pub fn eq_pat ( & self , left : & Pat , right : & Pat ) -> bool {
151
149
match ( & left. node , & right. node ) {
152
150
( & PatKind :: Box ( ref l) , & PatKind :: Box ( ref r) ) => self . eq_pat ( l, r) ,
153
151
( & PatKind :: TupleStruct ( ref lp, ref la, ls) , & PatKind :: TupleStruct ( ref rp, ref ra, rs) ) => {
154
- self . eq_qpath ( lp, rp ) && over ( la, ra, |l, r| self . eq_pat ( l, r) ) && ls == rs
152
+ self . eq_qpath ( lp, left . id , rp , right . id ) && over ( la, ra, |l, r| self . eq_pat ( l, r) ) && ls == rs
155
153
}
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) )
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) )
158
156
}
159
- ( & PatKind :: Path ( ref l) , & PatKind :: Path ( ref r) ) => self . eq_qpath ( l, r ) ,
157
+ ( & PatKind :: Path ( ref l) , & PatKind :: Path ( ref r) ) => self . eq_qpath ( l, left . id , r , right . id ) ,
160
158
( & PatKind :: Lit ( ref l) , & PatKind :: Lit ( ref r) ) => self . eq_expr ( l, r) ,
161
159
( & PatKind :: Tuple ( ref l, ls) , & PatKind :: Tuple ( ref r, rs) ) => {
162
160
ls == rs && over ( l, r, |l, r| self . eq_pat ( l, r) )
@@ -174,48 +172,23 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
174
172
}
175
173
}
176
174
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
- }
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) ;
193
178
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
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 ! ( ) ;
208
186
}
187
+ } else {
188
+ l == r
209
189
}
210
190
}
211
191
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
-
219
192
fn eq_ty ( & self , left : & Ty , right : & Ty ) -> bool {
220
193
match ( & left. node , & right. node ) {
221
194
( & TySlice ( ref l_vec) , & TySlice ( ref r_vec) ) => self . eq_ty ( l_vec, r_vec) ,
@@ -226,16 +199,12 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
226
199
( & TyRptr ( _, ref l_rmut) , & TyRptr ( _, ref r_rmut) ) => {
227
200
l_rmut. mutbl == r_rmut. mutbl && self . eq_ty ( & * l_rmut. ty , & * r_rmut. ty )
228
201
}
229
- ( & TyPath ( ref l) , & TyPath ( ref r) ) => self . eq_qpath ( l, r ) ,
202
+ ( & TyPath ( ref l) , & TyPath ( ref r) ) => self . eq_qpath ( l, left . id , r , right . id ) ,
230
203
( & TyTup ( ref l) , & TyTup ( ref r) ) => over ( l, r, |l, r| self . eq_ty ( l, r) ) ,
231
204
( & TyInfer , & TyInfer ) => true ,
232
205
_ => false ,
233
206
}
234
207
}
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
- }
239
208
}
240
209
241
210
fn swap_binop < ' a > ( binop : BinOp_ , lhs : & ' a Expr , rhs : & ' a Expr ) -> Option < ( BinOp_ , & ' a Expr , & ' a Expr ) > {
@@ -420,7 +389,7 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
420
389
}
421
390
j. hash ( & mut self . s ) ;
422
391
}
423
- ExprMatch ( ref e, ref arms, ref s ) => {
392
+ ExprMatch ( ref e, ref arms, _ ) => {
424
393
let c: fn ( _, _, _) -> _ = ExprMatch ;
425
394
c. hash ( & mut self . s ) ;
426
395
self . hash_expr ( e) ;
@@ -432,8 +401,6 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
432
401
}
433
402
self . hash_expr ( & arm. body ) ;
434
403
}
435
-
436
- s. hash ( & mut self . s ) ;
437
404
}
438
405
ExprMethodCall ( ref name, ref _tys, ref args) => {
439
406
let c: fn ( _, _, _) -> _ = ExprMethodCall ;
@@ -529,7 +496,19 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
529
496
}
530
497
531
498
pub fn hash_qpath ( & mut self , p : & QPath , id : NodeId ) {
532
- self . cx . tcx . tables ( ) . qpath_def ( p, id) . hash ( & mut self . s ) ;
499
+ let def = self . cx . tcx . tables ( ) . qpath_def ( p, id) ;
500
+ if let Def :: Local ( _) = def {
501
+ true . hash ( & mut self . s ) ;
502
+ if let QPath :: Resolved ( None , ref seq) = * p {
503
+ assert_eq ! ( seq. segments. len( ) , 1 ) ;
504
+ self . hash_name ( & seq. segments [ 0 ] . name ) ;
505
+ } else {
506
+ unreachable ! ( ) ;
507
+ }
508
+ } else {
509
+ false . hash ( & mut self . s ) ;
510
+ def. hash ( & mut self . s ) ;
511
+ }
533
512
}
534
513
535
514
pub fn hash_path ( & mut self , p : & Path ) {
0 commit comments