From dadd81792e088e66f044ec2668aaf521ff09d164 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 7 Nov 2019 19:28:12 -0500 Subject: [PATCH] Fix generating CTFE backtrace on optimized MIR During MIR optimization, we may inline function calls acrross crates. While we can inline the corresponding scopes into `Body.source_scopes`, we cannot inline the corresponding data from `source_scope_local_data`, since it references crate-local data. This commit makes us fall back to the root lint level when generating a CTFE backtrace, if it was not possible to find crate-local data for a scope in `source_scope_local_data`. Fixes #66137 --- src/librustc/mir/mod.rs | 8 ++++++++ src/librustc_mir/interpret/eval_context.rs | 7 ++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index fd2063e2da984..5a9854f9c90a5 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -105,6 +105,14 @@ pub struct Body<'tcx> { /// Crate-local information for each source scope, that can't (and /// needn't) be tracked across crates. + /// + /// Before optimizations run, every scope in `source_scopes` is guarnateed + /// to have an entry in `source_scope_local_data` (assuming it is `ClearCrossCrate::Set`). + /// + /// However, after optimizations are run, there may be some scopes with no entry + /// in `source_scope_local_data:`. This is due to the fact that MIR inlining can + /// cause scopes from a different crate to be inlined into this `Body`, which + /// cannot have crate-local data. pub source_scope_local_data: ClearCrossCrate>, /// The yield type of the function, if it is a generator. diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 92358ad247e18..c710e942116a9 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -816,7 +816,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { block.terminator().source_info }; match body.source_scope_local_data { - mir::ClearCrossCrate::Set(ref ivs) => Some(ivs[source_info.scope].lint_root), + // The scope may have been inlined from a different crate, in which + // case we will not have crate-local data for it. If that is the case, + // we just use our root lint level. + mir::ClearCrossCrate::Set(ref ivs) => { + ivs.get(source_info.scope).map(|d| d.lint_root) + } mir::ClearCrossCrate::Clear => None, } });