3
3
//! Currently, this pass only propagates scalar values.
4
4
5
5
use rustc_const_eval:: const_eval:: { DummyMachine , throw_machine_stop_str} ;
6
- use rustc_const_eval:: interpret:: { ImmTy , Immediate , InterpCx , OpTy , PlaceTy , Projectable } ;
6
+ use rustc_const_eval:: interpret:: {
7
+ DiscardInterpError , ImmTy , Immediate , InterpCx , OpTy , PlaceTy , Projectable ,
8
+ } ;
7
9
use rustc_data_structures:: fx:: FxHashMap ;
8
10
use rustc_hir:: def:: DefKind ;
9
11
use rustc_middle:: bug;
@@ -364,8 +366,10 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
364
366
}
365
367
}
366
368
Operand :: Constant ( box constant) => {
367
- if let Ok ( constant) =
368
- self . ecx . eval_mir_constant ( & constant. const_ , constant. span , None )
369
+ if let Some ( constant) = self
370
+ . ecx
371
+ . eval_mir_constant ( & constant. const_ , constant. span , None )
372
+ . discard_interp_error ( )
369
373
{
370
374
self . assign_constant ( state, place, constant, & [ ] ) ;
371
375
}
@@ -387,15 +391,17 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
387
391
for & ( mut proj_elem) in projection {
388
392
if let PlaceElem :: Index ( index) = proj_elem {
389
393
if let FlatSet :: Elem ( index) = state. get ( index. into ( ) , & self . map )
390
- && let Ok ( offset) = index. to_target_usize ( & self . tcx )
394
+ && let Some ( offset) = index. to_target_usize ( & self . tcx ) . discard_interp_error ( )
391
395
&& let Some ( min_length) = offset. checked_add ( 1 )
392
396
{
393
397
proj_elem = PlaceElem :: ConstantIndex { offset, min_length, from_end : false } ;
394
398
} else {
395
399
return ;
396
400
}
397
401
}
398
- operand = if let Ok ( operand) = self . ecx . project ( & operand, proj_elem) {
402
+ operand = if let Some ( operand) =
403
+ self . ecx . project ( & operand, proj_elem) . discard_interp_error ( )
404
+ {
399
405
operand
400
406
} else {
401
407
return ;
@@ -406,24 +412,30 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
406
412
place,
407
413
operand,
408
414
& mut |elem, op| match elem {
409
- TrackElem :: Field ( idx) => self . ecx . project_field ( op, idx. as_usize ( ) ) . ok ( ) ,
410
- TrackElem :: Variant ( idx) => self . ecx . project_downcast ( op, idx) . ok ( ) ,
415
+ TrackElem :: Field ( idx) => {
416
+ self . ecx . project_field ( op, idx. as_usize ( ) ) . discard_interp_error ( )
417
+ }
418
+ TrackElem :: Variant ( idx) => {
419
+ self . ecx . project_downcast ( op, idx) . discard_interp_error ( )
420
+ }
411
421
TrackElem :: Discriminant => {
412
- let variant = self . ecx . read_discriminant ( op) . ok ( ) ?;
413
- let discr_value =
414
- self . ecx . discriminant_for_variant ( op. layout . ty , variant) . ok ( ) ?;
422
+ let variant = self . ecx . read_discriminant ( op) . discard_interp_error ( ) ?;
423
+ let discr_value = self
424
+ . ecx
425
+ . discriminant_for_variant ( op. layout . ty , variant)
426
+ . discard_interp_error ( ) ?;
415
427
Some ( discr_value. into ( ) )
416
428
}
417
429
TrackElem :: DerefLen => {
418
- let op: OpTy < ' _ > = self . ecx . deref_pointer ( op) . ok ( ) ?. into ( ) ;
419
- let len_usize = op. len ( & self . ecx ) . ok ( ) ?;
430
+ let op: OpTy < ' _ > = self . ecx . deref_pointer ( op) . discard_interp_error ( ) ?. into ( ) ;
431
+ let len_usize = op. len ( & self . ecx ) . discard_interp_error ( ) ?;
420
432
let layout =
421
433
self . tcx . layout_of ( self . param_env . and ( self . tcx . types . usize ) ) . unwrap ( ) ;
422
434
Some ( ImmTy :: from_uint ( len_usize, layout) . into ( ) )
423
435
}
424
436
} ,
425
437
& mut |place, op| {
426
- if let Ok ( imm) = self . ecx . read_immediate_raw ( op)
438
+ if let Some ( imm) = self . ecx . read_immediate_raw ( op) . discard_interp_error ( )
427
439
&& let Some ( imm) = imm. right ( )
428
440
{
429
441
let elem = self . wrap_immediate ( * imm) ;
@@ -447,11 +459,11 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
447
459
( FlatSet :: Bottom , _) | ( _, FlatSet :: Bottom ) => ( FlatSet :: Bottom , FlatSet :: Bottom ) ,
448
460
// Both sides are known, do the actual computation.
449
461
( FlatSet :: Elem ( left) , FlatSet :: Elem ( right) ) => {
450
- match self . ecx . binary_op ( op, & left, & right) {
462
+ match self . ecx . binary_op ( op, & left, & right) . discard_interp_error ( ) {
451
463
// Ideally this would return an Immediate, since it's sometimes
452
464
// a pair and sometimes not. But as a hack we always return a pair
453
465
// and just make the 2nd component `Bottom` when it does not exist.
454
- Ok ( val) => {
466
+ Some ( val) => {
455
467
if matches ! ( val. layout. abi, Abi :: ScalarPair ( ..) ) {
456
468
let ( val, overflow) = val. to_scalar_pair ( ) ;
457
469
( FlatSet :: Elem ( val) , FlatSet :: Elem ( overflow) )
@@ -470,7 +482,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
470
482
}
471
483
472
484
let arg_scalar = const_arg. to_scalar ( ) ;
473
- let Ok ( arg_value) = arg_scalar. to_bits ( layout. size ) else {
485
+ let Some ( arg_value) = arg_scalar. to_bits ( layout. size ) . discard_interp_error ( ) else {
474
486
return ( FlatSet :: Top , FlatSet :: Top ) ;
475
487
} ;
476
488
@@ -518,8 +530,10 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
518
530
return None ;
519
531
}
520
532
let enum_ty_layout = self . tcx . layout_of ( self . param_env . and ( enum_ty) ) . ok ( ) ?;
521
- let discr_value =
522
- self . ecx . discriminant_for_variant ( enum_ty_layout. ty , variant_index) . ok ( ) ?;
533
+ let discr_value = self
534
+ . ecx
535
+ . discriminant_for_variant ( enum_ty_layout. ty , variant_index)
536
+ . discard_interp_error ( ) ?;
523
537
Some ( discr_value. to_scalar ( ) )
524
538
}
525
539
@@ -573,7 +587,7 @@ impl<'a, 'tcx> Collector<'a, 'tcx> {
573
587
map : & Map < ' tcx > ,
574
588
) -> Option < Const < ' tcx > > {
575
589
let ty = place. ty ( self . local_decls , self . patch . tcx ) . ty ;
576
- let layout = ecx. layout_of ( ty) . ok ( ) ?;
590
+ let layout = ecx. layout_of ( ty) . discard_interp_error ( ) ?;
577
591
578
592
if layout. is_zst ( ) {
579
593
return Some ( Const :: zero_sized ( ty) ) ;
@@ -595,7 +609,7 @@ impl<'a, 'tcx> Collector<'a, 'tcx> {
595
609
. intern_with_temp_alloc ( layout, |ecx, dest| {
596
610
try_write_constant ( ecx, dest, place, ty, state, map)
597
611
} )
598
- . ok ( ) ?;
612
+ . discard_interp_error ( ) ?;
599
613
return Some ( Const :: Val ( ConstValue :: Indirect { alloc_id, offset : Size :: ZERO } , ty) ) ;
600
614
}
601
615
@@ -830,7 +844,7 @@ impl<'tcx> MutVisitor<'tcx> for Patch<'tcx> {
830
844
if let PlaceElem :: Index ( local) = elem {
831
845
let offset = self . before_effect . get ( & ( location, local. into ( ) ) ) ?;
832
846
let offset = offset. try_to_scalar ( ) ?;
833
- let offset = offset. to_target_usize ( & self . tcx ) . ok ( ) ?;
847
+ let offset = offset. to_target_usize ( & self . tcx ) . discard_interp_error ( ) ?;
834
848
let min_length = offset. checked_add ( 1 ) ?;
835
849
Some ( PlaceElem :: ConstantIndex { offset, min_length, from_end : false } )
836
850
} else {
0 commit comments