@@ -13,6 +13,7 @@ use super::machine::CompileTimeInterpCx;
13
13
use super :: { ValTreeCreationError , ValTreeCreationResult , VALTREE_MAX_NODES } ;
14
14
use crate :: const_eval:: GlobalAccessPermissions ;
15
15
use crate :: errors:: MaxNumNodesInConstErr ;
16
+ use crate :: errors:: StaticRefErr ;
16
17
use crate :: interpret:: MPlaceTy ;
17
18
use crate :: interpret:: {
18
19
intern_const_alloc_recursive, ImmTy , Immediate , InternKind , MemPlaceMeta , MemoryKind , PlaceTy ,
@@ -138,6 +139,16 @@ fn const_to_valtree_inner<'tcx>(
138
139
139
140
ty:: Ref ( _, _, _) => {
140
141
let derefd_place = ecx. deref_pointer ( place) ?;
142
+ if let Some ( prov) = derefd_place. ptr ( ) . provenance {
143
+ match ecx. tcx . global_alloc ( prov. alloc_id ( ) ) {
144
+ mir:: interpret:: GlobalAlloc :: Function ( _) => unreachable ! ( ) ,
145
+ mir:: interpret:: GlobalAlloc :: VTable ( _, _) => unreachable ! ( ) ,
146
+ mir:: interpret:: GlobalAlloc :: Static ( _) => {
147
+ return Err ( ValTreeCreationError :: StaticRef ) ;
148
+ } ,
149
+ mir:: interpret:: GlobalAlloc :: Memory ( _) => { } ,
150
+ }
151
+ }
141
152
const_to_valtree_inner ( ecx, & derefd_place, num_nodes)
142
153
}
143
154
@@ -236,7 +247,7 @@ pub(crate) fn eval_to_valtree<'tcx>(
236
247
let const_alloc = tcx. eval_to_allocation_raw ( param_env. and ( cid) ) ?;
237
248
238
249
// FIXME Need to provide a span to `eval_to_valtree`
239
- let ecx = mk_eval_cx_to_read_const_val (
250
+ let mut ecx = mk_eval_cx_to_read_const_val (
240
251
tcx,
241
252
DUMMY_SP ,
242
253
param_env,
@@ -248,6 +259,14 @@ pub(crate) fn eval_to_valtree<'tcx>(
248
259
debug ! ( ?place) ;
249
260
250
261
let mut num_nodes = 0 ;
262
+
263
+ // To preserve provenance of static items, it is crucial that we do not
264
+ // treat them as constants and just read their values.
265
+ // This flag will cause valtree creation to ICE if a reference to a static
266
+ // is read, so valtree creation needs to eagerly catch those cases and handle
267
+ // them in custom ways. Currently by reporting a hard error, but we can opt to
268
+ // create a special valtree node for statics in the future.
269
+ ecx. machine . global_access_permissions = GlobalAccessPermissions :: Nothing ;
251
270
let valtree_result = const_to_valtree_inner ( & ecx, & place, & mut num_nodes) ;
252
271
253
272
match valtree_result {
@@ -262,6 +281,10 @@ pub(crate) fn eval_to_valtree<'tcx>(
262
281
tcx. dcx ( ) . emit_err ( MaxNumNodesInConstErr { span, global_const_id } ) ;
263
282
Err ( handled. into ( ) )
264
283
}
284
+ ValTreeCreationError :: StaticRef => {
285
+ let handled = tcx. dcx ( ) . emit_err ( StaticRefErr { span } ) ;
286
+ Err ( handled. into ( ) )
287
+ }
265
288
ValTreeCreationError :: NonSupportedType => Ok ( None ) ,
266
289
}
267
290
}
0 commit comments