@@ -20,12 +20,10 @@ use build::matches::{Candidate, MatchPair, Test, TestKind};
20
20
use hair:: * ;
21
21
use rustc_data_structures:: fx:: FxHashMap ;
22
22
use rustc_data_structures:: bitvec:: BitVector ;
23
- use rustc:: middle:: const_val:: ConstVal ;
24
23
use rustc:: ty:: { self , Ty } ;
25
24
use rustc:: ty:: util:: IntTypeExt ;
26
25
use rustc:: mir:: * ;
27
- use rustc:: mir:: interpret:: { Value , PrimVal } ;
28
- use rustc:: hir:: RangeEnd ;
26
+ use rustc:: hir:: { RangeEnd , Mutability } ;
29
27
use syntax_pos:: Span ;
30
28
use std:: cmp:: Ordering ;
31
29
@@ -258,69 +256,77 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
258
256
259
257
TestKind :: Eq { value, mut ty } => {
260
258
let mut val = Operand :: Copy ( place. clone ( ) ) ;
261
-
262
- let bytes = match value. val {
263
- ConstVal :: Value ( Value :: ByVal ( PrimVal :: Ptr ( p) ) ) => {
264
- let is_array_ptr = ty
265
- . builtin_deref ( true , ty:: NoPreference )
266
- . and_then ( |t| t. ty . builtin_index ( ) )
267
- . map_or ( false , |t| t == self . hir . tcx ( ) . types . u8 ) ;
268
- if is_array_ptr {
269
- self . hir
270
- . tcx ( )
271
- . interpret_interner
272
- . borrow ( )
273
- . get_alloc ( p. alloc_id )
274
- . map ( |alloc| & alloc. bytes [ ..] )
275
- } else {
276
- None
277
- }
278
- } ,
279
- _ => None ,
280
- } ;
281
- // If we're using b"..." as a pattern, we need to insert an
282
- // unsizing coercion, as the byte string has the type &[u8; N].
283
- let expect = if let Some ( bytes) = bytes {
284
- let tcx = self . hir . tcx ( ) ;
285
-
286
- // Unsize the place to &[u8], too, if necessary.
287
- if let ty:: TyRef ( region, mt) = ty. sty {
288
- if let ty:: TyArray ( _, _) = mt. ty . sty {
289
- ty = tcx. mk_imm_ref ( region, tcx. mk_slice ( tcx. types . u8 ) ) ;
290
- let val_slice = self . temp ( ty, test. span ) ;
291
- self . cfg . push_assign ( block, source_info, & val_slice,
292
- Rvalue :: Cast ( CastKind :: Unsize , val, ty) ) ;
293
- val = Operand :: Move ( val_slice) ;
294
- }
295
- }
296
-
297
- assert ! ( ty. is_slice( ) ) ;
298
-
299
- let array_ty = tcx. mk_array ( tcx. types . u8 , bytes. len ( ) as u64 ) ;
300
- let array_ref = tcx. mk_imm_ref ( tcx. types . re_static , array_ty) ;
301
- let array = self . literal_operand ( test. span , array_ref, Literal :: Value {
302
- value
303
- } ) ;
304
-
305
- let slice = self . temp ( ty, test. span ) ;
306
- self . cfg . push_assign ( block, source_info, & slice,
307
- Rvalue :: Cast ( CastKind :: Unsize , array, ty) ) ;
308
- Operand :: Move ( slice)
309
- } else {
310
- self . literal_operand ( test. span , ty, Literal :: Value {
311
- value
312
- } )
313
- } ;
314
-
315
- // Use PartialEq::eq for references, instead of BinOp::Eq.
259
+ let mut expect = self . literal_operand ( test. span , ty, Literal :: Value {
260
+ value
261
+ } ) ;
262
+ // Use PartialEq::eq instead of BinOp::Eq
263
+ // (the binop can only handle primitives)
316
264
let fail = self . cfg . start_new_block ( ) ;
317
- let str_or_bytestr = ty
318
- . builtin_deref ( true , ty:: NoPreference )
319
- . map ( |tam| tam. ty ) ;
320
- if let Some ( ty) = str_or_bytestr {
265
+ if !ty. is_scalar ( ) {
266
+ // unsize arrays to slices
267
+ let unsize = |ty : Ty < ' tcx > | match ty. sty {
268
+ ty:: TyRef ( region, tam) => match tam. ty . sty {
269
+ ty:: TyArray ( inner_ty, n) => Some ( ( region, inner_ty, n) ) ,
270
+ _ => None ,
271
+ } ,
272
+ _ => None ,
273
+ } ;
274
+ let opt_ref_ty = unsize ( ty) ;
275
+ let opt_ref_test_ty = unsize ( value. ty ) ;
276
+ let mut place = place. clone ( ) ;
277
+ match ( opt_ref_ty, opt_ref_test_ty) {
278
+ // nothing to do, neither is an array
279
+ ( None , None ) => { } ,
280
+ ( Some ( ( region, elem_ty, _) ) , _) |
281
+ ( None , Some ( ( region, elem_ty, _) ) ) => {
282
+ let tcx = self . hir . tcx ( ) ;
283
+ // make both a slice
284
+ ty = tcx. mk_imm_ref ( region, tcx. mk_slice ( elem_ty) ) ;
285
+ if opt_ref_ty. is_some ( ) {
286
+ place = self . temp ( ty, test. span ) ;
287
+ self . cfg . push_assign ( block, source_info, & place,
288
+ Rvalue :: Cast ( CastKind :: Unsize , val, ty) ) ;
289
+ }
290
+ if opt_ref_test_ty. is_some ( ) {
291
+ let array = self . literal_operand ( test. span , value. ty , Literal :: Value {
292
+ value
293
+ } ) ;
294
+
295
+ let slice = self . temp ( ty, test. span ) ;
296
+ self . cfg . push_assign ( block, source_info, & slice,
297
+ Rvalue :: Cast ( CastKind :: Unsize , array, ty) ) ;
298
+ expect = Operand :: Move ( slice) ;
299
+ }
300
+ } ,
301
+ }
321
302
let eq_def_id = self . hir . tcx ( ) . lang_items ( ) . eq_trait ( ) . unwrap ( ) ;
322
303
let ( mty, method) = self . hir . trait_method ( eq_def_id, "eq" , ty, & [ ty] ) ;
323
304
305
+ // take the argument by reference
306
+ let region_scope = self . topmost_scope ( ) ;
307
+ let region = self . hir . tcx ( ) . mk_region ( ty:: ReScope ( region_scope) ) ;
308
+ let tam = ty:: TypeAndMut {
309
+ ty,
310
+ mutbl : Mutability :: MutImmutable ,
311
+ } ;
312
+ let ref_ty = self . hir . tcx ( ) . mk_ref ( region, tam) ;
313
+
314
+ // let lhs_ref_place = &lhs;
315
+ let ref_rvalue = Rvalue :: Ref ( region, BorrowKind :: Shared , place. clone ( ) ) ;
316
+ let lhs_ref_place = self . temp ( ref_ty, test. span ) ;
317
+ self . cfg . push_assign ( block, source_info, & lhs_ref_place, ref_rvalue) ;
318
+ let val = Operand :: Move ( lhs_ref_place) ;
319
+
320
+ // let rhs_place = rhs;
321
+ let rhs_place = self . temp ( ty, test. span ) ;
322
+ self . cfg . push_assign ( block, source_info, & rhs_place, Rvalue :: Use ( expect) ) ;
323
+
324
+ // let rhs_ref_place = &rhs_place;
325
+ let ref_rvalue = Rvalue :: Ref ( region, BorrowKind :: Shared , rhs_place) ;
326
+ let rhs_ref_place = self . temp ( ref_ty, test. span ) ;
327
+ self . cfg . push_assign ( block, source_info, & rhs_ref_place, ref_rvalue) ;
328
+ let expect = Operand :: Move ( rhs_ref_place) ;
329
+
324
330
let bool_ty = self . hir . bool_ty ( ) ;
325
331
let eq_result = self . temp ( bool_ty, test. span ) ;
326
332
let eq_block = self . cfg . start_new_block ( ) ;
0 commit comments