@@ -33,7 +33,11 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
3333 pub machine : M ,
3434
3535 /// 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 ,
3741
3842 /// Bounds in scope for polymorphic evaluations.
3943 pub ( crate ) param_env : ty:: ParamEnv < ' tcx > ,
@@ -196,7 +200,7 @@ where
196200{
197201 #[ inline]
198202 fn tcx ( & self ) -> TyCtxt < ' tcx > {
199- * self . tcx
203+ self . tcx
200204 }
201205}
202206
@@ -209,13 +213,13 @@ where
209213 }
210214}
211215
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 > {
213217 type Ty = Ty < ' tcx > ;
214218 type TyAndLayout = InterpResult < ' tcx , TyAndLayout < ' tcx > > ;
215219
216220 #[ inline]
217221 fn layout_of ( & self , ty : Ty < ' tcx > ) -> Self :: TyAndLayout {
218- self . tcx
222+ self . tcx_at ( )
219223 . layout_of ( self . param_env . and ( ty) )
220224 . map_err ( |layout| err_inval ! ( Layout ( layout) ) . into ( ) )
221225 }
@@ -292,23 +296,35 @@ pub(super) fn from_known_layout<'tcx>(
292296
293297impl < ' mir , ' tcx : ' mir , M : Machine < ' mir , ' tcx > > InterpCx < ' mir , ' tcx , M > {
294298 pub fn new (
295- tcx : TyCtxtAt < ' tcx > ,
299+ tcx : TyCtxt < ' tcx > ,
300+ root_span : Span ,
296301 param_env : ty:: ParamEnv < ' tcx > ,
297302 machine : M ,
298303 memory_extra : M :: MemoryExtra ,
299304 ) -> Self {
300305 InterpCx {
301306 machine,
302307 tcx,
308+ root_span,
303309 param_env,
304- memory : Memory :: new ( * tcx, memory_extra) ,
310+ memory : Memory :: new ( tcx, memory_extra) ,
305311 vtables : FxHashMap :: default ( ) ,
306312 }
307313 }
308314
309315 #[ 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 ( ) )
312328 }
313329
314330 #[ inline( always) ]
@@ -386,12 +402,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
386402
387403 #[ inline]
388404 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 )
390406 }
391407
392408 #[ inline]
393409 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 ( ) )
395411 }
396412
397413 pub fn load_mir (
@@ -402,20 +418,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
402418 // do not continue if typeck errors occurred (can only occur in local crate)
403419 let did = instance. def_id ( ) ;
404420 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 {
407423 throw_inval ! ( TypeckError ( error_reported) )
408424 }
409425 }
410426 }
411427 trace ! ( "load mir(instance={:?}, promoted={:?})" , instance, promoted) ;
412428 if let Some ( promoted) = promoted {
413- return Ok ( & self . tcx . promoted_mir ( did) [ promoted] ) ;
429+ return Ok ( & self . tcx_at ( ) . promoted_mir ( did) [ promoted] ) ;
414430 }
415431 match instance {
416432 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) )
419435 } else {
420436 throw_unsup ! ( NoMirFor ( def_id) )
421437 }
@@ -456,7 +472,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
456472 trace ! ( "resolve: {:?}, {:#?}" , def_id, substs) ;
457473 trace ! ( "param_env: {:#?}" , self . param_env) ;
458474 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) {
460476 Ok ( Some ( instance) ) => Ok ( instance) ,
461477 Ok ( None ) => throw_inval ! ( TooGeneric ) ,
462478
@@ -475,7 +491,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
475491 // have to support that case (mostly by skipping all caching).
476492 match frame. locals . get ( local) . and_then ( |state| state. layout . get ( ) ) {
477493 None => {
478- let layout = from_known_layout ( self . tcx , layout, || {
494+ let layout = from_known_layout ( self . tcx_at ( ) , layout, || {
479495 let local_ty = frame. body . local_decls [ local] . ty ;
480496 let local_ty =
481497 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> {
560576 let size = size. align_to ( align) ;
561577
562578 // 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 ( ) {
564580 throw_ub ! ( InvalidMeta ( "total size is bigger than largest supported object" ) ) ;
565581 }
566582 Ok ( Some ( ( size, align) ) )
@@ -576,7 +592,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
576592 let elem = layout. field ( self , 0 ) ?;
577593
578594 // 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 ( || {
580596 err_ub ! ( InvalidMeta ( "slice is bigger than largest supported object" ) )
581597 } ) ?;
582598 Ok ( Some ( ( size, elem. align . abi ) ) )
@@ -627,7 +643,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
627643 let mut locals = IndexVec :: from_elem ( dummy, & body. local_decls ) ;
628644
629645 // 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 ( ) ) {
631647 // statics and constants don't have `Storage*` statements, no need to look for them
632648 //
633649 // FIXME: The above is likely untrue. See
@@ -842,7 +858,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
842858 } else {
843859 self . param_env
844860 } ;
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 ( ) ) ) ?;
846862
847863 // Even though `ecx.const_eval` is called from `eval_const_to_op` we can never have a
848864 // 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> {
873889 // FIXME: We can hit delay_span_bug if this is an invalid const, interning finds
874890 // that problem, but we never run validation to show an error. Can we ensure
875891 // 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) ) ?;
877893 self . raw_const_to_mplace ( val)
878894 }
879895
0 commit comments