Skip to content

Commit 54e24c1

Browse files
committed
const-eval: make lint scope computation consistent
1 parent b316033 commit 54e24c1

File tree

4 files changed

+25
-30
lines changed

4 files changed

+25
-30
lines changed

compiler/rustc_const_eval/src/const_eval/error.rs

+2-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use std::mem;
22

33
use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage, Diagnostic, IntoDiagArg};
4-
use rustc_hir::CRATE_HIR_ID;
54
use rustc_middle::mir::interpret::{Provenance, ReportedErrorInfo};
65
use rustc_middle::mir::AssertKind;
76
use rustc_middle::query::TyCtxtAt;
@@ -156,7 +155,7 @@ where
156155
}
157156
}
158157

159-
/// Emit a lint from a const-eval situation.
158+
/// Emit a lint from a const-eval situation, with a backtrace.
160159
// Even if this is unused, please don't remove it -- chances are we will need to emit a lint during const-eval again in the future!
161160
pub(super) fn lint<'tcx, L>(
162161
tcx: TyCtxtAt<'tcx>,
@@ -168,12 +167,5 @@ pub(super) fn lint<'tcx, L>(
168167
{
169168
let (span, frames) = get_span_and_frames(tcx, &machine.stack);
170169

171-
tcx.emit_node_span_lint(
172-
lint,
173-
// We use the root frame for this so the crate that defines the const defines whether the
174-
// lint is emitted.
175-
machine.stack.first().and_then(|frame| frame.lint_root()).unwrap_or(CRATE_HIR_ID),
176-
span,
177-
decorator(frames),
178-
);
170+
tcx.emit_node_span_lint(lint, machine.best_lint_scope(*tcx), span, decorator(frames));
179171
}

compiler/rustc_const_eval/src/const_eval/eval_queries.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
114114
let err_diag = errors::MutablePtrInFinal { span: ecx.tcx.span, kind: intern_kind };
115115
ecx.tcx.emit_node_span_lint(
116116
lint::builtin::CONST_EVAL_MUTABLE_PTR_IN_FINAL_VALUE,
117-
ecx.best_lint_scope(),
117+
ecx.machine.best_lint_scope(*ecx.tcx),
118118
err_diag.span,
119119
err_diag,
120120
)

compiler/rustc_const_eval/src/const_eval/machine.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ use rustc_data_structures::fx::IndexEntry;
99
use rustc_hir::def_id::DefId;
1010
use rustc_hir::def_id::LocalDefId;
1111
use rustc_hir::LangItem;
12+
use rustc_hir::{self as hir, CRATE_HIR_ID};
1213
use rustc_middle::bug;
1314
use rustc_middle::mir;
1415
use rustc_middle::mir::AssertMessage;
1516
use rustc_middle::query::TyCtxtAt;
16-
use rustc_middle::ty;
1717
use rustc_middle::ty::layout::{FnAbiOf, TyAndLayout};
18+
use rustc_middle::ty::{self, TyCtxt};
1819
use rustc_session::lint::builtin::WRITES_THROUGH_IMMUTABLE_POINTER;
1920
use rustc_span::symbol::{sym, Symbol};
2021
use rustc_span::Span;
@@ -369,6 +370,15 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
369370
}
370371
}
371372

373+
impl<'tcx> CompileTimeMachine<'tcx> {
374+
#[inline(always)]
375+
/// Find the first stack frame that is within the current crate, if any.
376+
/// Otherwise, return the crate's HirId
377+
pub fn best_lint_scope(&self, tcx: TyCtxt<'tcx>) -> hir::HirId {
378+
self.stack.iter().find_map(|frame| frame.lint_root(tcx)).unwrap_or(CRATE_HIR_ID)
379+
}
380+
}
381+
372382
impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
373383
compile_time_machine!(<'tcx>);
374384

@@ -600,7 +610,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
600610
// By default, we stop after a million steps, but the user can disable this lint
601611
// to be able to run until the heat death of the universe or power loss, whichever
602612
// comes first.
603-
let hir_id = ecx.best_lint_scope();
613+
let hir_id = ecx.machine.best_lint_scope(*ecx.tcx);
604614
let is_error = ecx
605615
.tcx
606616
.lint_level_at_node(

compiler/rustc_const_eval/src/interpret/eval_context.rs

+10-17
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::{fmt, mem};
44
use either::{Either, Left, Right};
55
use tracing::{debug, info, info_span, instrument, trace};
66

7-
use hir::CRATE_HIR_ID;
87
use rustc_errors::DiagCtxt;
98
use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
109
use rustc_index::IndexVec;
@@ -271,13 +270,18 @@ impl<'tcx, Prov: Provenance, Extra> Frame<'tcx, Prov, Extra> {
271270
}
272271
}
273272

274-
pub fn lint_root(&self) -> Option<hir::HirId> {
275-
self.current_source_info().and_then(|source_info| {
276-
match &self.body.source_scopes[source_info.scope].local_data {
273+
pub fn lint_root(&self, tcx: TyCtxt<'tcx>) -> Option<hir::HirId> {
274+
// We first try to get a HirId via the current source scope,
275+
// and fall back to `body.source`.
276+
self.current_source_info()
277+
.and_then(|source_info| match &self.body.source_scopes[source_info.scope].local_data {
277278
mir::ClearCrossCrate::Set(data) => Some(data.lint_root),
278279
mir::ClearCrossCrate::Clear => None,
279-
}
280-
})
280+
})
281+
.or_else(|| {
282+
let def_id = self.body.source.def_id().as_local();
283+
def_id.map(|def_id| tcx.local_def_id_to_hir_id(def_id))
284+
})
281285
}
282286

283287
/// Returns the address of the buffer where the locals are stored. This is used by `Place` as a
@@ -509,17 +513,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
509513
self.stack().last().map_or(self.tcx.span, |f| f.current_span())
510514
}
511515

512-
/// Find the first stack frame that is within the current crate, if any;
513-
/// otherwise return the crate's HirId.
514-
#[inline(always)]
515-
pub fn best_lint_scope(&self) -> hir::HirId {
516-
self.stack()
517-
.iter()
518-
.find_map(|frame| frame.body.source.def_id().as_local())
519-
.map_or(CRATE_HIR_ID, |def_id| self.tcx.local_def_id_to_hir_id(def_id))
520-
}
521-
522-
#[inline(always)]
523516
pub(crate) fn stack(&self) -> &[Frame<'tcx, M::Provenance, M::FrameExtra>] {
524517
M::stack(self)
525518
}

0 commit comments

Comments
 (0)