@@ -157,14 +157,19 @@ struct ConstPropMachine<'mir, 'tcx> {
157
157
written_only_inside_own_block_locals : FxHashSet < Local > ,
158
158
/// Locals that need to be cleared after every block terminates.
159
159
only_propagate_inside_block_locals : BitSet < Local > ,
160
+ can_const_prop : IndexVec < Local , ConstPropMode > ,
160
161
}
161
162
162
163
impl < ' 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 {
164
168
Self {
165
169
stack : Vec :: new ( ) ,
166
170
written_only_inside_own_block_locals : Default :: default ( ) ,
167
171
only_propagate_inside_block_locals,
172
+ can_const_prop,
168
173
}
169
174
}
170
175
}
@@ -243,6 +248,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
243
248
local : Local ,
244
249
) -> InterpResult < ' tcx , Result < & ' a mut LocalValue < Self :: PointerTag > , MemPlace < Self :: PointerTag > > >
245
250
{
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
+ }
246
254
if frame == 0 && ecx. machine . only_propagate_inside_block_locals . contains ( local) {
247
255
ecx. machine . written_only_inside_own_block_locals . insert ( local) ;
248
256
}
@@ -287,7 +295,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
287
295
struct ConstPropagator < ' mir , ' tcx > {
288
296
ecx : InterpCx < ' mir , ' tcx , ConstPropMachine < ' mir , ' tcx > > ,
289
297
tcx : TyCtxt < ' tcx > ,
290
- can_const_prop : IndexVec < Local , ConstPropMode > ,
291
298
param_env : ParamEnv < ' tcx > ,
292
299
// FIXME(eddyb) avoid cloning these two fields more than once,
293
300
// by accessing them through `ecx` instead.
@@ -347,7 +354,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
347
354
tcx,
348
355
span,
349
356
param_env,
350
- ConstPropMachine :: new ( only_propagate_inside_block_locals) ,
357
+ ConstPropMachine :: new ( only_propagate_inside_block_locals, can_const_prop ) ,
351
358
( ) ,
352
359
) ;
353
360
@@ -373,7 +380,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
373
380
ecx,
374
381
tcx,
375
382
param_env,
376
- can_const_prop,
377
383
// FIXME(eddyb) avoid cloning these two fields more than once,
378
384
// by accessing them through `ecx` instead.
379
385
source_scopes : body. source_scopes . clone ( ) ,
@@ -1031,7 +1037,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
1031
1037
let source_info = statement. source_info ;
1032
1038
self . source_info = Some ( source_info) ;
1033
1039
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 ] ;
1035
1041
if let Some ( ( ) ) = self . const_prop ( rval, source_info, place) {
1036
1042
// This will return None if the above `const_prop` invocation only "wrote" a
1037
1043
// type whose creation requires no write. E.g. a generator whose initial state
0 commit comments