@@ -10,6 +10,7 @@ use std::cmp::Ordering;
10
10
use rustc_data_structures:: fx:: FxIndexMap ;
11
11
use rustc_hir:: { LangItem , RangeEnd } ;
12
12
use rustc_middle:: mir:: * ;
13
+ use rustc_middle:: ty:: adjustment:: PointerCoercion ;
13
14
use rustc_middle:: ty:: util:: IntTypeExt ;
14
15
use rustc_middle:: ty:: { self , GenericArg , Ty , TyCtxt } ;
15
16
use rustc_middle:: { bug, span_bug} ;
@@ -374,53 +375,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
374
375
mut val : Place < ' tcx > ,
375
376
mut ty : Ty < ' tcx > ,
376
377
) {
377
- let expect_ty = value. ty ( ) ;
378
+ let mut expect_ty = value. ty ( ) ;
378
379
let expect_op = self . literal_operand ( source_info. span , value) ;
379
380
let mut expect = self . temp ( value. ty ( ) , source_info. span ) ;
380
- self . cfg . push_assign (
381
- block,
382
- source_info,
383
- expect,
384
- Rvalue :: Use ( expect_op) ,
385
- ) ;
381
+ self . cfg . push_assign ( block, source_info, expect, Rvalue :: Use ( expect_op) ) ;
386
382
387
- match ty . kind ( ) {
388
- ty :: Ref ( _ , inner_ty , _ ) if inner_ty . is_slice ( ) => {
389
- let ref_ty = Ty :: new_imm_ref ( self . tcx , self . tcx . lifetimes . re_erased , ty) ;
383
+ let mut normalize_depth = | mut ty : Ty < ' tcx > , mut val : Place < ' tcx > | {
384
+ if !ty . is_ref ( ) {
385
+ ty = Ty :: new_imm_ref ( self . tcx , self . tcx . lifetimes . re_erased , ty) ;
390
386
let temp = self . temp ( ty, source_info. span ) ;
391
387
self . cfg . push_assign (
392
388
block,
393
389
source_info,
394
390
temp,
395
391
Rvalue :: Ref ( self . tcx . lifetimes . re_erased , BorrowKind :: Shared , val) ,
396
392
) ;
397
- ty = ref_ty;
398
393
val = temp;
399
- tracing:: warn!( "slice ty sig: {:?}" , ty) ;
400
- }
401
- ty:: Ref ( _, inner_ty, _) if inner_ty. is_array ( ) => {
402
- let ref_ty = Ty :: new_imm_ref ( self . tcx , self . tcx . lifetimes . re_erased , ty) ;
403
- let temp = self . temp ( ref_ty, source_info. span ) ;
404
- self . cfg . push_assign (
405
- block,
406
- source_info,
407
- temp,
408
- Rvalue :: Ref ( self . tcx . lifetimes . re_erased , BorrowKind :: Shared , val) ,
409
- ) ;
410
-
411
- ty = ref_ty;
412
- val = temp;
413
- tracing:: warn!( "arr ty sig: {:?}" , ty) ;
414
- }
415
- ty:: Ref ( _, inner_ty, _) if inner_ty. is_str ( ) => {
416
- // nothing yet
417
- }
418
- _ => todo ! ( "not yet, ty: {:?}" , ty) ,
419
- }
420
-
421
- let mut normalize_depth = |mut ty : Ty < ' tcx > , mut val : Place < ' tcx > | {
422
- if !ty. is_ref ( ) {
423
- panic ! ( "not a reference?" ) ;
394
+ return ( ty, val) ;
424
395
}
425
396
426
397
loop {
@@ -438,15 +409,50 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
438
409
tracing:: warn!( "from {:?} to {:?}" , val, temp) ;
439
410
val = temp;
440
411
}
441
- _=> break ,
412
+ _ => break ,
442
413
}
443
414
}
444
415
445
416
( ty, val)
446
417
} ;
447
418
448
419
( ty, val) = normalize_depth ( ty, val) ;
449
- ( _, expect) = normalize_depth ( expect_ty, expect) ;
420
+ ( expect_ty, expect) = normalize_depth ( expect_ty, expect) ;
421
+
422
+ let mut coerce = |mut ty : Ty < ' tcx > , mut place : Place < ' tcx > , elem_ty : Ty < ' tcx > | {
423
+ assert ! ( ty. is_ref( ) && ty. peel_refs( ) . is_array( ) ) ;
424
+ let ref_ty = Ty :: new_imm_ref (
425
+ self . tcx ,
426
+ self . tcx . lifetimes . re_erased ,
427
+ Ty :: new_slice ( self . tcx , elem_ty) ,
428
+ ) ;
429
+
430
+ let ref_val = self . temp ( ref_ty, source_info. span ) ;
431
+ self . cfg . push_assign (
432
+ block,
433
+ source_info,
434
+ ref_val,
435
+ Rvalue :: Cast (
436
+ CastKind :: PointerCoercion ( PointerCoercion :: Unsize , CoercionSource :: Implicit ) ,
437
+ Operand :: Copy ( place) ,
438
+ ref_ty,
439
+ ) ,
440
+ ) ;
441
+
442
+ ty = ref_ty;
443
+ place = ref_val;
444
+ ( ty, place)
445
+ } ;
446
+
447
+ match ( ty. peel_refs ( ) . kind ( ) , expect_ty. peel_refs ( ) . kind ( ) ) {
448
+ ( ty:: Slice ( _) , ty:: Array ( elem_ty, _) ) => {
449
+ ( _, expect) = coerce ( expect_ty, expect, * elem_ty) ;
450
+ }
451
+ ( ty:: Array ( elem_ty, _) , ty:: Slice ( _) ) => {
452
+ ( ty, val) = coerce ( ty, val, * elem_ty) ;
453
+ }
454
+ _ => ( ) ,
455
+ }
450
456
451
457
// Figure out the type on which we are calling `PartialEq`. This involves an extra wrapping
452
458
// reference: we can only compare two `&T`, and then compare_ty will be `T`.
0 commit comments