@@ -17,8 +17,7 @@ use syntax_pos::{Span, DUMMY_SP};
17
17
use rustc:: ty:: subst:: InternalSubsts ;
18
18
use rustc_data_structures:: indexed_vec:: IndexVec ;
19
19
use rustc:: ty:: layout:: {
20
- LayoutOf , TyLayout , LayoutError ,
21
- HasTyCtxt , TargetDataLayout , HasDataLayout ,
20
+ LayoutOf , TyLayout , LayoutError , HasTyCtxt , TargetDataLayout , HasDataLayout , Size ,
22
21
} ;
23
22
24
23
use crate :: interpret:: {
@@ -333,6 +332,12 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
333
332
this. ecx . operand_field ( eval, field. index ( ) as u64 )
334
333
} ) ?;
335
334
} ,
335
+ ProjectionElem :: Deref => {
336
+ trace ! ( "processing deref" ) ;
337
+ eval = self . use_ecx ( source_info, |this| {
338
+ this. ecx . deref_operand ( eval)
339
+ } ) ?. into ( ) ;
340
+ }
336
341
// We could get more projections by using e.g., `operand_projection`,
337
342
// but we do not even have the stack frame set up properly so
338
343
// an `Index` projection would throw us off-track.
@@ -363,8 +368,12 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
363
368
Rvalue :: Use ( ref op) => {
364
369
self . eval_operand ( op, source_info)
365
370
} ,
371
+ Rvalue :: Ref ( _, _, ref place) => {
372
+ let src = self . eval_place ( place, source_info) ?;
373
+ let mplace = src. try_as_mplace ( ) . ok ( ) ?;
374
+ Some ( ImmTy :: from_scalar ( mplace. ptr . into ( ) , place_layout) . into ( ) )
375
+ } ,
366
376
Rvalue :: Repeat ( ..) |
367
- Rvalue :: Ref ( ..) |
368
377
Rvalue :: Aggregate ( ..) |
369
378
Rvalue :: NullaryOp ( NullOp :: Box , _) |
370
379
Rvalue :: Discriminant ( ..) => None ,
@@ -376,10 +385,30 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
376
385
this. ecx . cast ( op, kind, dest. into ( ) ) ?;
377
386
Ok ( dest. into ( ) )
378
387
} )
379
- }
388
+ } ,
389
+ Rvalue :: Len ( ref place) => {
390
+ let place = self . eval_place ( & place, source_info) ?;
391
+ let mplace = place. try_as_mplace ( ) . ok ( ) ?;
392
+
393
+ if let ty:: Slice ( _) = mplace. layout . ty . sty {
394
+ let len = mplace. meta . unwrap ( ) . to_usize ( & self . ecx ) . unwrap ( ) ;
380
395
381
- // FIXME(oli-obk): evaluate static/constant slice lengths
382
- Rvalue :: Len ( _) => None ,
396
+ Some ( ImmTy {
397
+ imm : Immediate :: Scalar (
398
+ Scalar :: from_uint (
399
+ len,
400
+ Size :: from_bits (
401
+ self . tcx . sess . target . usize_ty . bit_width ( ) . unwrap ( ) as u64
402
+ )
403
+ ) . into ( ) ,
404
+ ) ,
405
+ layout : self . tcx . layout_of ( self . param_env . and ( self . tcx . types . usize ) ) . ok ( ) ?,
406
+ } . into ( ) )
407
+ } else {
408
+ trace ! ( "not slice: {:?}" , mplace. layout. ty. sty) ;
409
+ None
410
+ }
411
+ } ,
383
412
Rvalue :: NullaryOp ( NullOp :: SizeOf , ty) => {
384
413
type_size_of ( self . tcx , self . param_env , ty) . and_then ( |n| Some (
385
414
ImmTy {
@@ -525,12 +554,10 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
525
554
source_info : SourceInfo ,
526
555
) {
527
556
trace ! ( "attepting to replace {:?} with {:?}" , rval, value) ;
528
- self . ecx . validate_operand (
529
- value,
530
- vec ! [ ] ,
531
- None ,
532
- true ,
533
- ) . expect ( "value should already be a valid const" ) ;
557
+ if let Err ( e) = self . ecx . validate_operand ( value, vec ! [ ] , None , true ) {
558
+ trace ! ( "validation error, attempt failed: {:?}" , e) ;
559
+ return ;
560
+ }
534
561
535
562
// FIXME> figure out what tho do when try_read_immediate fails
536
563
let imm = self . use_ecx ( source_info, |this| {
0 commit comments