@@ -157,14 +157,19 @@ struct ConstPropMachine<'mir, 'tcx> {
157157 written_only_inside_own_block_locals : FxHashSet < Local > ,
158158 /// Locals that need to be cleared after every block terminates.
159159 only_propagate_inside_block_locals : BitSet < Local > ,
160+ can_const_prop : IndexVec < Local , ConstPropMode > ,
160161}
161162
162163impl < ' mir , ' tcx > ConstPropMachine < ' mir , ' tcx > {
163- fn new ( only_propagate_inside_block_locals : BitSet < Local > ) -> Self {
164+ fn new (
165+ only_propagate_inside_block_locals : BitSet < Local > ,
166+ can_const_prop : IndexVec < Local , ConstPropMode > ,
167+ ) -> Self {
164168 Self {
165169 stack : Vec :: new ( ) ,
166170 written_only_inside_own_block_locals : Default :: default ( ) ,
167171 only_propagate_inside_block_locals,
172+ can_const_prop,
168173 }
169174 }
170175}
@@ -243,6 +248,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
243248 local : Local ,
244249 ) -> InterpResult < ' tcx , Result < & ' a mut LocalValue < Self :: PointerTag > , MemPlace < Self :: PointerTag > > >
245250 {
251+ if ecx. machine . can_const_prop [ local] == ConstPropMode :: NoPropagation {
252+ throw_machine_stop_str ! ( "tried to write to a local that is marked as not propagatable" )
253+ }
246254 if frame == 0 && ecx. machine . only_propagate_inside_block_locals . contains ( local) {
247255 ecx. machine . written_only_inside_own_block_locals . insert ( local) ;
248256 }
@@ -287,7 +295,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
287295struct ConstPropagator < ' mir , ' tcx > {
288296 ecx : InterpCx < ' mir , ' tcx , ConstPropMachine < ' mir , ' tcx > > ,
289297 tcx : TyCtxt < ' tcx > ,
290- can_const_prop : IndexVec < Local , ConstPropMode > ,
291298 param_env : ParamEnv < ' tcx > ,
292299 // FIXME(eddyb) avoid cloning these two fields more than once,
293300 // by accessing them through `ecx` instead.
@@ -347,7 +354,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
347354 tcx,
348355 span,
349356 param_env,
350- ConstPropMachine :: new ( only_propagate_inside_block_locals) ,
357+ ConstPropMachine :: new ( only_propagate_inside_block_locals, can_const_prop ) ,
351358 ( ) ,
352359 ) ;
353360
@@ -373,7 +380,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
373380 ecx,
374381 tcx,
375382 param_env,
376- can_const_prop,
377383 // FIXME(eddyb) avoid cloning these two fields more than once,
378384 // by accessing them through `ecx` instead.
379385 source_scopes : body. source_scopes . clone ( ) ,
@@ -1031,7 +1037,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
10311037 let source_info = statement. source_info ;
10321038 self . source_info = Some ( source_info) ;
10331039 if let StatementKind :: Assign ( box ( place, ref mut rval) ) = statement. kind {
1034- let can_const_prop = self . can_const_prop [ place. local ] ;
1040+ let can_const_prop = self . ecx . machine . can_const_prop [ place. local ] ;
10351041 if let Some ( ( ) ) = self . const_prop ( rval, source_info, place) {
10361042 // This will return None if the above `const_prop` invocation only "wrote" a
10371043 // type whose creation requires no write. E.g. a generator whose initial state
0 commit comments