Skip to content

Commit

Permalink
Unrolled build for rust-lang#126388
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#126388 - RalfJung:const-eval-lint-scope, r=oli-obk

const-eval: make lint scope computation consistent

The first commit is some renaming for consistency, but otherwise unrelated. It just didn't feel worth a separate PR, but I can split this up if you prefer.

r? ``@oli-obk``
  • Loading branch information
rust-timer authored Jun 14, 2024
2 parents 0ef0dd2 + 54e24c1 commit 851128d
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 65 deletions.
16 changes: 4 additions & 12 deletions compiler/rustc_const_eval/src/const_eval/error.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
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;
use rustc_middle::ty::TyCtxt;
use rustc_middle::ty::{layout::LayoutError, ConstInt};
use rustc_span::{Span, Symbol};

use super::CompileTimeInterpreter;
use super::CompileTimeMachine;
use crate::errors::{self, FrameNote, ReportErrorExt};
use crate::interpret::{err_inval, err_machine_stop};
use crate::interpret::{ErrorHandled, Frame, InterpError, InterpErrorInfo, MachineStopType};
Expand Down Expand Up @@ -156,24 +155,17 @@ 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>,
machine: &CompileTimeInterpreter<'tcx>,
machine: &CompileTimeMachine<'tcx>,
lint: &'static rustc_session::lint::Lint,
decorator: impl FnOnce(Vec<errors::FrameNote>) -> L,
) where
L: for<'a> rustc_errors::LintDiagnostic<'a, ()>,
{
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));
}
24 changes: 12 additions & 12 deletions compiler/rustc_const_eval/src/const_eval/eval_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc_span::def_id::LocalDefId;
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::{self, Abi};

use super::{CanAccessMutGlobal, CompileTimeEvalContext, CompileTimeInterpreter};
use super::{CanAccessMutGlobal, CompileTimeInterpCx, CompileTimeMachine};
use crate::const_eval::CheckAlignment;
use crate::errors::ConstEvalError;
use crate::errors::{self, DanglingPtrInFinal};
Expand All @@ -32,7 +32,7 @@ use crate::CTRL_C_RECEIVED;
// Returns a pointer to where the result lives
#[instrument(level = "trace", skip(ecx, body))]
fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
ecx: &mut CompileTimeEvalContext<'tcx>,
ecx: &mut CompileTimeInterpCx<'tcx>,
cid: GlobalId<'tcx>,
body: &'tcx mir::Body<'tcx>,
) -> InterpResult<'tcx, R> {
Expand Down Expand Up @@ -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,
)
Expand All @@ -139,13 +139,13 @@ pub(crate) fn mk_eval_cx_to_read_const_val<'tcx>(
root_span: Span,
param_env: ty::ParamEnv<'tcx>,
can_access_mut_global: CanAccessMutGlobal,
) -> CompileTimeEvalContext<'tcx> {
) -> CompileTimeInterpCx<'tcx> {
debug!("mk_eval_cx: {:?}", param_env);
InterpCx::new(
tcx,
root_span,
param_env,
CompileTimeInterpreter::new(can_access_mut_global, CheckAlignment::No),
CompileTimeMachine::new(can_access_mut_global, CheckAlignment::No),
)
}

Expand All @@ -156,7 +156,7 @@ pub fn mk_eval_cx_for_const_val<'tcx>(
param_env: ty::ParamEnv<'tcx>,
val: mir::ConstValue<'tcx>,
ty: Ty<'tcx>,
) -> Option<(CompileTimeEvalContext<'tcx>, OpTy<'tcx>)> {
) -> Option<(CompileTimeInterpCx<'tcx>, OpTy<'tcx>)> {
let ecx = mk_eval_cx_to_read_const_val(tcx.tcx, tcx.span, param_env, CanAccessMutGlobal::No);
let op = ecx.const_val_to_op(val, ty, None).ok()?;
Some((ecx, op))
Expand All @@ -170,7 +170,7 @@ pub fn mk_eval_cx_for_const_val<'tcx>(
/// encounter an `Indirect` they cannot handle.
#[instrument(skip(ecx), level = "debug")]
pub(super) fn op_to_const<'tcx>(
ecx: &CompileTimeEvalContext<'tcx>,
ecx: &CompileTimeInterpCx<'tcx>,
op: &OpTy<'tcx>,
for_diagnostics: bool,
) -> ConstValue<'tcx> {
Expand Down Expand Up @@ -328,14 +328,14 @@ pub trait InterpretationResult<'tcx> {
/// evaluation query.
fn make_result(
mplace: MPlaceTy<'tcx>,
ecx: &mut InterpCx<'tcx, CompileTimeInterpreter<'tcx>>,
ecx: &mut InterpCx<'tcx, CompileTimeMachine<'tcx>>,
) -> Self;
}

impl<'tcx> InterpretationResult<'tcx> for ConstAlloc<'tcx> {
fn make_result(
mplace: MPlaceTy<'tcx>,
_ecx: &mut InterpCx<'tcx, CompileTimeInterpreter<'tcx>>,
_ecx: &mut InterpCx<'tcx, CompileTimeMachine<'tcx>>,
) -> Self {
ConstAlloc { alloc_id: mplace.ptr().provenance.unwrap().alloc_id(), ty: mplace.layout.ty }
}
Expand Down Expand Up @@ -383,7 +383,7 @@ fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>(
// they do not have to behave "as if" they were evaluated at runtime.
// For consts however we want to ensure they behave "as if" they were evaluated at runtime,
// so we have to reject reading mutable global memory.
CompileTimeInterpreter::new(CanAccessMutGlobal::from(is_static), CheckAlignment::Error),
CompileTimeMachine::new(CanAccessMutGlobal::from(is_static), CheckAlignment::Error),
);
let res = ecx.load_mir(cid.instance.def, cid.promoted);
res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, body)).map_err(|error| {
Expand Down Expand Up @@ -417,7 +417,7 @@ fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>(

#[inline(always)]
fn const_validate_mplace<'tcx>(
ecx: &InterpCx<'tcx, CompileTimeInterpreter<'tcx>>,
ecx: &InterpCx<'tcx, CompileTimeMachine<'tcx>>,
mplace: &MPlaceTy<'tcx>,
cid: GlobalId<'tcx>,
) -> Result<(), ErrorHandled> {
Expand Down Expand Up @@ -447,7 +447,7 @@ fn const_validate_mplace<'tcx>(

#[inline(always)]
fn report_validation_error<'tcx>(
ecx: &InterpCx<'tcx, CompileTimeInterpreter<'tcx>>,
ecx: &InterpCx<'tcx, CompileTimeMachine<'tcx>>,
error: InterpErrorInfo<'tcx>,
alloc_id: AllocId,
) -> ErrorHandled {
Expand Down
26 changes: 18 additions & 8 deletions compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -44,7 +45,7 @@ const TINY_LINT_TERMINATOR_LIMIT: usize = 20;
const PROGRESS_INDICATOR_START: usize = 4_000_000;

/// Extra machine state for CTFE, and the Machine instance
pub struct CompileTimeInterpreter<'tcx> {
pub struct CompileTimeMachine<'tcx> {
/// The number of terminators that have been evaluated.
///
/// This is used to produce lints informing the user that the compiler is not stuck.
Expand Down Expand Up @@ -89,12 +90,12 @@ impl From<bool> for CanAccessMutGlobal {
}
}

impl<'tcx> CompileTimeInterpreter<'tcx> {
impl<'tcx> CompileTimeMachine<'tcx> {
pub(crate) fn new(
can_access_mut_global: CanAccessMutGlobal,
check_alignment: CheckAlignment,
) -> Self {
CompileTimeInterpreter {
CompileTimeMachine {
num_evaluated_steps: 0,
stack: Vec::new(),
can_access_mut_global,
Expand Down Expand Up @@ -163,7 +164,7 @@ impl<K: Hash + Eq, V> interpret::AllocMap<K, V> for FxIndexMap<K, V> {
}
}

pub(crate) type CompileTimeEvalContext<'tcx> = InterpCx<'tcx, CompileTimeInterpreter<'tcx>>;
pub(crate) type CompileTimeInterpCx<'tcx> = InterpCx<'tcx, CompileTimeMachine<'tcx>>;

#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum MemoryKind {
Expand Down Expand Up @@ -195,7 +196,7 @@ impl interpret::MayLeak for ! {
}
}

impl<'tcx> CompileTimeEvalContext<'tcx> {
impl<'tcx> CompileTimeInterpCx<'tcx> {
fn location_triple_for_span(&self, span: Span) -> (Symbol, u32, u32) {
let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo());
Expand Down Expand Up @@ -369,7 +370,16 @@ impl<'tcx> CompileTimeEvalContext<'tcx> {
}
}

impl<'tcx> interpret::Machine<'tcx> for CompileTimeInterpreter<'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>);

type MemoryKind = MemoryKind;
Expand Down Expand Up @@ -600,7 +610,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeInterpreter<'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(
Expand Down
16 changes: 8 additions & 8 deletions compiler/rustc_const_eval/src/const_eval/valtrees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc_target::abi::{Abi, VariantIdx};
use tracing::{debug, instrument, trace};

use super::eval_queries::{mk_eval_cx_to_read_const_val, op_to_const};
use super::machine::CompileTimeEvalContext;
use super::machine::CompileTimeInterpCx;
use super::{ValTreeCreationError, ValTreeCreationResult, VALTREE_MAX_NODES};
use crate::const_eval::CanAccessMutGlobal;
use crate::errors::MaxNumNodesInConstErr;
Expand All @@ -21,7 +21,7 @@ use crate::interpret::{

#[instrument(skip(ecx), level = "debug")]
fn branches<'tcx>(
ecx: &CompileTimeEvalContext<'tcx>,
ecx: &CompileTimeInterpCx<'tcx>,
place: &MPlaceTy<'tcx>,
n: usize,
variant: Option<VariantIdx>,
Expand Down Expand Up @@ -59,7 +59,7 @@ fn branches<'tcx>(

#[instrument(skip(ecx), level = "debug")]
fn slice_branches<'tcx>(
ecx: &CompileTimeEvalContext<'tcx>,
ecx: &CompileTimeInterpCx<'tcx>,
place: &MPlaceTy<'tcx>,
num_nodes: &mut usize,
) -> ValTreeCreationResult<'tcx> {
Expand All @@ -77,7 +77,7 @@ fn slice_branches<'tcx>(

#[instrument(skip(ecx), level = "debug")]
fn const_to_valtree_inner<'tcx>(
ecx: &CompileTimeEvalContext<'tcx>,
ecx: &CompileTimeInterpCx<'tcx>,
place: &MPlaceTy<'tcx>,
num_nodes: &mut usize,
) -> ValTreeCreationResult<'tcx> {
Expand Down Expand Up @@ -219,7 +219,7 @@ fn reconstruct_place_meta<'tcx>(

#[instrument(skip(ecx), level = "debug", ret)]
fn create_valtree_place<'tcx>(
ecx: &mut CompileTimeEvalContext<'tcx>,
ecx: &mut CompileTimeInterpCx<'tcx>,
layout: TyAndLayout<'tcx>,
valtree: ty::ValTree<'tcx>,
) -> MPlaceTy<'tcx> {
Expand Down Expand Up @@ -364,7 +364,7 @@ pub fn valtree_to_const_value<'tcx>(

/// Put a valtree into memory and return a reference to that.
fn valtree_to_ref<'tcx>(
ecx: &mut CompileTimeEvalContext<'tcx>,
ecx: &mut CompileTimeInterpCx<'tcx>,
valtree: ty::ValTree<'tcx>,
pointee_ty: Ty<'tcx>,
) -> Immediate {
Expand All @@ -380,7 +380,7 @@ fn valtree_to_ref<'tcx>(

#[instrument(skip(ecx), level = "debug")]
fn valtree_into_mplace<'tcx>(
ecx: &mut CompileTimeEvalContext<'tcx>,
ecx: &mut CompileTimeInterpCx<'tcx>,
place: &MPlaceTy<'tcx>,
valtree: ty::ValTree<'tcx>,
) {
Expand Down Expand Up @@ -457,6 +457,6 @@ fn valtree_into_mplace<'tcx>(
}
}

fn dump_place<'tcx>(ecx: &CompileTimeEvalContext<'tcx>, place: &MPlaceTy<'tcx>) {
fn dump_place<'tcx>(ecx: &CompileTimeInterpCx<'tcx>, place: &MPlaceTy<'tcx>) {
trace!("{:?}", ecx.dump_place(&PlaceTy::from(place.clone())));
}
27 changes: 10 additions & 17 deletions compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use std::{fmt, mem};
use either::{Either, Left, Right};
use tracing::{debug, info, info_span, instrument, trace};

use hir::CRATE_HIR_ID;
use rustc_errors::DiagCtxt;
use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
use rustc_index::IndexVec;
Expand Down Expand Up @@ -271,13 +270,18 @@ impl<'tcx, Prov: Provenance, Extra> Frame<'tcx, Prov, Extra> {
}
}

pub fn lint_root(&self) -> Option<hir::HirId> {
self.current_source_info().and_then(|source_info| {
match &self.body.source_scopes[source_info.scope].local_data {
pub fn lint_root(&self, tcx: TyCtxt<'tcx>) -> Option<hir::HirId> {
// We first try to get a HirId via the current source scope,
// and fall back to `body.source`.
self.current_source_info()
.and_then(|source_info| match &self.body.source_scopes[source_info.scope].local_data {
mir::ClearCrossCrate::Set(data) => Some(data.lint_root),
mir::ClearCrossCrate::Clear => None,
}
})
})
.or_else(|| {
let def_id = self.body.source.def_id().as_local();
def_id.map(|def_id| tcx.local_def_id_to_hir_id(def_id))
})
}

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

/// Find the first stack frame that is within the current crate, if any;
/// otherwise return the crate's HirId.
#[inline(always)]
pub fn best_lint_scope(&self) -> hir::HirId {
self.stack()
.iter()
.find_map(|frame| frame.body.source.def_id().as_local())
.map_or(CRATE_HIR_ID, |def_id| self.tcx.local_def_id_to_hir_id(def_id))
}

#[inline(always)]
pub(crate) fn stack(&self) -> &[Frame<'tcx, M::Provenance, M::FrameExtra>] {
M::stack(self)
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/intern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub trait HasStaticRootDefId {
fn static_def_id(&self) -> Option<LocalDefId>;
}

impl HasStaticRootDefId for const_eval::CompileTimeInterpreter<'_> {
impl HasStaticRootDefId for const_eval::CompileTimeMachine<'_> {
fn static_def_id(&self) -> Option<LocalDefId> {
Some(self.static_root_ids?.1)
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_const_eval/src/interpret/util.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::const_eval::{CompileTimeEvalContext, CompileTimeInterpreter, InterpretationResult};
use crate::const_eval::{CompileTimeInterpCx, CompileTimeMachine, InterpretationResult};
use rustc_hir::def_id::LocalDefId;
use rustc_middle::mir;
use rustc_middle::mir::interpret::{Allocation, InterpResult, Pointer};
Expand Down Expand Up @@ -84,7 +84,7 @@ where
impl<'tcx> InterpretationResult<'tcx> for mir::interpret::ConstAllocation<'tcx> {
fn make_result(
mplace: MPlaceTy<'tcx>,
ecx: &mut InterpCx<'tcx, CompileTimeInterpreter<'tcx>>,
ecx: &mut InterpCx<'tcx, CompileTimeMachine<'tcx>>,
) -> Self {
let alloc_id = mplace.ptr().provenance.unwrap().alloc_id();
let alloc = ecx.memory.alloc_map.swap_remove(&alloc_id).unwrap().1;
Expand All @@ -93,7 +93,7 @@ impl<'tcx> InterpretationResult<'tcx> for mir::interpret::ConstAllocation<'tcx>
}

pub(crate) fn create_static_alloc<'tcx>(
ecx: &mut CompileTimeEvalContext<'tcx>,
ecx: &mut CompileTimeInterpCx<'tcx>,
static_def_id: LocalDefId,
layout: TyAndLayout<'tcx>,
) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
Expand Down
Loading

0 comments on commit 851128d

Please sign in to comment.