@@ -33,7 +33,11 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
33
33
pub machine : M ,
34
34
35
35
/// The results of the type checker, from rustc.
36
- pub tcx : TyCtxtAt < ' tcx > ,
36
+ pub tcx : TyCtxt < ' tcx > ,
37
+
38
+ /// The span of the "root" of the evaluation, i.e., the const
39
+ /// we are evaluating (if this is CTFE).
40
+ pub ( super ) root_span : Span ,
37
41
38
42
/// Bounds in scope for polymorphic evaluations.
39
43
pub ( crate ) param_env : ty:: ParamEnv < ' tcx > ,
@@ -196,7 +200,7 @@ where
196
200
{
197
201
#[ inline]
198
202
fn tcx ( & self ) -> TyCtxt < ' tcx > {
199
- * self . tcx
203
+ self . tcx
200
204
}
201
205
}
202
206
@@ -209,13 +213,13 @@ where
209
213
}
210
214
}
211
215
212
- impl < ' mir , ' tcx , M : Machine < ' mir , ' tcx > > LayoutOf for InterpCx < ' mir , ' tcx , M > {
216
+ impl < ' mir , ' tcx : ' mir , M : Machine < ' mir , ' tcx > > LayoutOf for InterpCx < ' mir , ' tcx , M > {
213
217
type Ty = Ty < ' tcx > ;
214
218
type TyAndLayout = InterpResult < ' tcx , TyAndLayout < ' tcx > > ;
215
219
216
220
#[ inline]
217
221
fn layout_of ( & self , ty : Ty < ' tcx > ) -> Self :: TyAndLayout {
218
- self . tcx
222
+ self . tcx_at ( )
219
223
. layout_of ( self . param_env . and ( ty) )
220
224
. map_err ( |layout| err_inval ! ( Layout ( layout) ) . into ( ) )
221
225
}
@@ -292,23 +296,35 @@ pub(super) fn from_known_layout<'tcx>(
292
296
293
297
impl < ' mir , ' tcx : ' mir , M : Machine < ' mir , ' tcx > > InterpCx < ' mir , ' tcx , M > {
294
298
pub fn new (
295
- tcx : TyCtxtAt < ' tcx > ,
299
+ tcx : TyCtxt < ' tcx > ,
300
+ root_span : Span ,
296
301
param_env : ty:: ParamEnv < ' tcx > ,
297
302
machine : M ,
298
303
memory_extra : M :: MemoryExtra ,
299
304
) -> Self {
300
305
InterpCx {
301
306
machine,
302
307
tcx,
308
+ root_span,
303
309
param_env,
304
- memory : Memory :: new ( * tcx, memory_extra) ,
310
+ memory : Memory :: new ( tcx, memory_extra) ,
305
311
vtables : FxHashMap :: default ( ) ,
306
312
}
307
313
}
308
314
309
315
#[ inline( always) ]
310
- pub fn set_span ( & mut self , span : Span ) {
311
- self . tcx . span = span;
316
+ pub fn cur_span ( & self ) -> Span {
317
+ self
318
+ . stack ( )
319
+ . last ( )
320
+ . and_then ( |f| f. current_source_info ( ) )
321
+ . map ( |si| si. span )
322
+ . unwrap_or ( self . root_span )
323
+ }
324
+
325
+ #[ inline( always) ]
326
+ pub fn tcx_at ( & self ) -> TyCtxtAt < ' tcx > {
327
+ self . tcx . at ( self . cur_span ( ) )
312
328
}
313
329
314
330
#[ inline( always) ]
@@ -386,12 +402,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
386
402
387
403
#[ inline]
388
404
pub fn type_is_sized ( & self , ty : Ty < ' tcx > ) -> bool {
389
- ty. is_sized ( self . tcx , self . param_env )
405
+ ty. is_sized ( self . tcx_at ( ) , self . param_env )
390
406
}
391
407
392
408
#[ inline]
393
409
pub fn type_is_freeze ( & self , ty : Ty < ' tcx > ) -> bool {
394
- ty. is_freeze ( * self . tcx , self . param_env , DUMMY_SP )
410
+ ty. is_freeze ( self . tcx , self . param_env , self . cur_span ( ) )
395
411
}
396
412
397
413
pub fn load_mir (
@@ -402,20 +418,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
402
418
// do not continue if typeck errors occurred (can only occur in local crate)
403
419
let did = instance. def_id ( ) ;
404
420
if let Some ( did) = did. as_local ( ) {
405
- if self . tcx . has_typeck_tables ( did) {
406
- if let Some ( error_reported) = self . tcx . typeck_tables_of ( did) . tainted_by_errors {
421
+ if self . tcx_at ( ) . has_typeck_tables ( did) {
422
+ if let Some ( error_reported) = self . tcx_at ( ) . typeck_tables_of ( did) . tainted_by_errors {
407
423
throw_inval ! ( TypeckError ( error_reported) )
408
424
}
409
425
}
410
426
}
411
427
trace ! ( "load mir(instance={:?}, promoted={:?})" , instance, promoted) ;
412
428
if let Some ( promoted) = promoted {
413
- return Ok ( & self . tcx . promoted_mir ( did) [ promoted] ) ;
429
+ return Ok ( & self . tcx_at ( ) . promoted_mir ( did) [ promoted] ) ;
414
430
}
415
431
match instance {
416
432
ty:: InstanceDef :: Item ( def_id) => {
417
- if self . tcx . is_mir_available ( did) {
418
- Ok ( self . tcx . optimized_mir ( did) )
433
+ if self . tcx_at ( ) . is_mir_available ( did) {
434
+ Ok ( self . tcx_at ( ) . optimized_mir ( did) )
419
435
} else {
420
436
throw_unsup ! ( NoMirFor ( def_id) )
421
437
}
@@ -456,7 +472,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
456
472
trace ! ( "resolve: {:?}, {:#?}" , def_id, substs) ;
457
473
trace ! ( "param_env: {:#?}" , self . param_env) ;
458
474
trace ! ( "substs: {:#?}" , substs) ;
459
- match ty:: Instance :: resolve ( * self . tcx , self . param_env , def_id, substs) {
475
+ match ty:: Instance :: resolve ( self . tcx , self . param_env , def_id, substs) {
460
476
Ok ( Some ( instance) ) => Ok ( instance) ,
461
477
Ok ( None ) => throw_inval ! ( TooGeneric ) ,
462
478
@@ -475,7 +491,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
475
491
// have to support that case (mostly by skipping all caching).
476
492
match frame. locals . get ( local) . and_then ( |state| state. layout . get ( ) ) {
477
493
None => {
478
- let layout = from_known_layout ( self . tcx , layout, || {
494
+ let layout = from_known_layout ( self . tcx_at ( ) , layout, || {
479
495
let local_ty = frame. body . local_decls [ local] . ty ;
480
496
let local_ty =
481
497
self . subst_from_frame_and_normalize_erasing_regions ( frame, local_ty) ;
@@ -560,7 +576,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
560
576
let size = size. align_to ( align) ;
561
577
562
578
// Check if this brought us over the size limit.
563
- if size. bytes ( ) >= self . tcx . data_layout ( ) . obj_size_bound ( ) {
579
+ if size. bytes ( ) >= self . tcx . data_layout . obj_size_bound ( ) {
564
580
throw_ub ! ( InvalidMeta ( "total size is bigger than largest supported object" ) ) ;
565
581
}
566
582
Ok ( Some ( ( size, align) ) )
@@ -576,7 +592,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
576
592
let elem = layout. field ( self , 0 ) ?;
577
593
578
594
// Make sure the slice is not too big.
579
- let size = elem. size . checked_mul ( len, & * self . tcx ) . ok_or_else ( || {
595
+ let size = elem. size . checked_mul ( len, self ) . ok_or_else ( || {
580
596
err_ub ! ( InvalidMeta ( "slice is bigger than largest supported object" ) )
581
597
} ) ?;
582
598
Ok ( Some ( ( size, elem. align . abi ) ) )
@@ -627,7 +643,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
627
643
let mut locals = IndexVec :: from_elem ( dummy, & body. local_decls ) ;
628
644
629
645
// Now mark those locals as dead that we do not want to initialize
630
- match self . tcx . def_kind ( instance. def_id ( ) ) {
646
+ match self . tcx_at ( ) . def_kind ( instance. def_id ( ) ) {
631
647
// statics and constants don't have `Storage*` statements, no need to look for them
632
648
//
633
649
// FIXME: The above is likely untrue. See
@@ -842,7 +858,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
842
858
} else {
843
859
self . param_env
844
860
} ;
845
- let val = self . tcx . const_eval_global_id ( param_env, gid, Some ( self . tcx . span ) ) ?;
861
+ let val = self . tcx . const_eval_global_id ( param_env, gid, Some ( self . cur_span ( ) ) ) ?;
846
862
847
863
// Even though `ecx.const_eval` is called from `eval_const_to_op` we can never have a
848
864
// recursion deeper than one level, because the `tcx.const_eval` above is guaranteed to not
@@ -873,7 +889,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
873
889
// FIXME: We can hit delay_span_bug if this is an invalid const, interning finds
874
890
// that problem, but we never run validation to show an error. Can we ensure
875
891
// this does not happen?
876
- let val = self . tcx . const_eval_raw ( param_env. and ( gid) ) ?;
892
+ let val = self . tcx_at ( ) . const_eval_raw ( param_env. and ( gid) ) ?;
877
893
self . raw_const_to_mplace ( val)
878
894
}
879
895
0 commit comments