1
Fork 0

const-eval: make lint scope computation consistent

This commit is contained in:
Ralf Jung 2024-06-13 11:30:24 +02:00
parent b316033dd8
commit 54e24c1573
4 changed files with 25 additions and 30 deletions

View file

@ -1,7 +1,6 @@
use std::mem;
use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage, Diagnostic, IntoDiagArg};
use rustc_hir::CRATE_HIR_ID;
use rustc_middle::mir::interpret::{Provenance, ReportedErrorInfo};
use rustc_middle::mir::AssertKind;
use rustc_middle::query::TyCtxtAt;
@ -156,7 +155,7 @@ where
}
}
/// Emit a lint from a const-eval situation.
/// Emit a lint from a const-eval situation, with a backtrace.
// 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!
pub(super) fn lint<'tcx, L>(
tcx: TyCtxtAt<'tcx>,
@ -168,12 +167,5 @@ pub(super) fn lint<'tcx, L>(
{
let (span, frames) = get_span_and_frames(tcx, &machine.stack);
tcx.emit_node_span_lint(
lint,
// We use the root frame for this so the crate that defines the const defines whether the
// lint is emitted.
machine.stack.first().and_then(|frame| frame.lint_root()).unwrap_or(CRATE_HIR_ID),
span,
decorator(frames),
);
tcx.emit_node_span_lint(lint, machine.best_lint_scope(*tcx), span, decorator(frames));
}

View file

@ -114,7 +114,7 @@ fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
let err_diag = errors::MutablePtrInFinal { span: ecx.tcx.span, kind: intern_kind };
ecx.tcx.emit_node_span_lint(
lint::builtin::CONST_EVAL_MUTABLE_PTR_IN_FINAL_VALUE,
ecx.best_lint_scope(),
ecx.machine.best_lint_scope(*ecx.tcx),
err_diag.span,
err_diag,
)

View file

@ -9,12 +9,13 @@ use rustc_data_structures::fx::IndexEntry;
use rustc_hir::def_id::DefId;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::LangItem;
use rustc_hir::{self as hir, CRATE_HIR_ID};
use rustc_middle::bug;
use rustc_middle::mir;
use rustc_middle::mir::AssertMessage;
use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty;
use rustc_middle::ty::layout::{FnAbiOf, TyAndLayout};
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint::builtin::WRITES_THROUGH_IMMUTABLE_POINTER;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::Span;
@ -369,6 +370,15 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
}
}
impl<'tcx> CompileTimeMachine<'tcx> {
#[inline(always)]
/// Find the first stack frame that is within the current crate, if any.
/// Otherwise, return the crate's HirId
pub fn best_lint_scope(&self, tcx: TyCtxt<'tcx>) -> hir::HirId {
self.stack.iter().find_map(|frame| frame.lint_root(tcx)).unwrap_or(CRATE_HIR_ID)
}
}
impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
compile_time_machine!(<'tcx>);
@ -600,7 +610,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
// By default, we stop after a million steps, but the user can disable this lint
// to be able to run until the heat death of the universe or power loss, whichever
// comes first.
let hir_id = ecx.best_lint_scope();
let hir_id = ecx.machine.best_lint_scope(*ecx.tcx);
let is_error = ecx
.tcx
.lint_level_at_node(