@@ -350,14 +350,20 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
350
350
}
351
351
352
352
fn get_const ( & self , place : Place < ' tcx > ) -> Option < OpTy < ' tcx > > {
353
- let op = self . ecx . eval_place_to_op ( place, None ) . ok ( ) ;
353
+ let op = match self . ecx . eval_place_to_op ( place, None ) {
354
+ Ok ( op) => op,
355
+ Err ( e) => {
356
+ trace ! ( "get_const failed: {}" , e) ;
357
+ return None ;
358
+ }
359
+ } ;
354
360
355
361
// Try to read the local as an immediate so that if it is representable as a scalar, we can
356
362
// handle it as such, but otherwise, just return the value as is.
357
- match op . map ( |ret| self . ecx . try_read_immediate ( ret ) ) {
358
- Some ( Ok ( Ok ( imm) ) ) => Some ( imm. into ( ) ) ,
363
+ Some ( match self . ecx . try_read_immediate ( op ) {
364
+ Ok ( Ok ( imm) ) => imm. into ( ) ,
359
365
_ => op,
360
- }
366
+ } )
361
367
}
362
368
363
369
/// Remove `local` from the pool of `Locals`. Allows writing to them,
@@ -872,8 +878,9 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
872
878
if let Ok ( place_layout) = self . tcx . layout_of ( self . param_env . and ( place_ty) ) {
873
879
let can_const_prop = self . can_const_prop [ place. local ] ;
874
880
if let Some ( ( ) ) = self . const_prop ( rval, place_layout, source_info, place) {
875
- // This will return None for variables that are from other blocks,
876
- // so it should be okay to propagate from here on down.
881
+ // This will return None if the above `const_prop` invocation only "wrote" a
882
+ // type whose creation requires no write. E.g. a generator whose initial state
883
+ // consists solely of uninitialized memory (so it doesn't capture any locals).
877
884
if let Some ( value) = self . get_const ( place) {
878
885
if self . should_const_prop ( value) {
879
886
trace ! ( "replacing {:?} with {:?}" , rval, value) ;
0 commit comments