@@ -350,14 +350,20 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
350350 }
351351
352352 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+ } ;
354360
355361 // Try to read the local as an immediate so that if it is representable as a scalar, we can
356362 // 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 ( ) ,
359365 _ => op,
360- }
366+ } )
361367 }
362368
363369 /// Remove `local` from the pool of `Locals`. Allows writing to them,
@@ -857,8 +863,9 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
857863 if let Ok ( place_layout) = self . tcx . layout_of ( self . param_env . and ( place_ty) ) {
858864 let can_const_prop = self . can_const_prop [ place. local ] ;
859865 if let Some ( ( ) ) = self . const_prop ( rval, place_layout, source_info, place) {
860- // This will return None for variables that are from other blocks,
861- // so it should be okay to propagate from here on down.
866+ // This will return None if the above `const_prop` invocation only "wrote" a
867+ // type whose creation requires no write. E.g. a generator whose initial state
868+ // consists solely of uninitialized memory (so it doesn't capture any locals).
862869 if let Some ( value) = self . get_const ( place) {
863870 if self . should_const_prop ( value) {
864871 trace ! ( "replacing {:?} with {:?}" , rval, value) ;
0 commit comments