Query-ify global limit attribute handling
This commit is contained in:
parent
90442458ac
commit
ff15b5e2c7
30 changed files with 153 additions and 91 deletions
|
@ -98,7 +98,7 @@ pub(super) fn mk_eval_cx<'mir, 'tcx>(
|
|||
tcx,
|
||||
root_span,
|
||||
param_env,
|
||||
CompileTimeInterpreter::new(tcx.sess.const_eval_limit()),
|
||||
CompileTimeInterpreter::new(tcx.const_eval_limit(())),
|
||||
MemoryExtra { can_access_statics },
|
||||
)
|
||||
}
|
||||
|
@ -300,7 +300,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
|
|||
tcx,
|
||||
tcx.def_span(def.did),
|
||||
key.param_env,
|
||||
CompileTimeInterpreter::new(tcx.sess.const_eval_limit()),
|
||||
CompileTimeInterpreter::new(tcx.const_eval_limit(())),
|
||||
// Statics (and promoteds inside statics) may access other statics, because unlike consts
|
||||
// they do not have to behave "as if" they were evaluated at runtime.
|
||||
MemoryExtra { can_access_statics: is_static },
|
||||
|
|
|
@ -393,7 +393,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
|||
frame: Frame<'mir, 'tcx>,
|
||||
) -> InterpResult<'tcx, Frame<'mir, 'tcx>> {
|
||||
// Enforce stack size limit. Add 1 because this is run before the new frame is pushed.
|
||||
if !ecx.tcx.sess.recursion_limit().value_within_limit(ecx.stack().len() + 1) {
|
||||
if !ecx.recursion_limit.value_within_limit(ecx.stack().len() + 1) {
|
||||
throw_exhaust!(StackFrameLimitReached)
|
||||
} else {
|
||||
Ok(frame)
|
||||
|
|
|
@ -13,6 +13,7 @@ use rustc_middle::ty::layout::{self, TyAndLayout};
|
|||
use rustc_middle::ty::{
|
||||
self, query::TyCtxtAt, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable,
|
||||
};
|
||||
use rustc_session::Limit;
|
||||
use rustc_span::{Pos, Span};
|
||||
use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size, TargetDataLayout};
|
||||
|
||||
|
@ -39,6 +40,9 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
|
|||
|
||||
/// The virtual memory system.
|
||||
pub memory: Memory<'mir, 'tcx, M>,
|
||||
|
||||
/// The recursion limit (cached from `tcx.recursion_limit(())`)
|
||||
pub recursion_limit: Limit,
|
||||
}
|
||||
|
||||
// The Phantomdata exists to prevent this type from being `Send`. If it were sent across a thread
|
||||
|
@ -388,6 +392,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
tcx: tcx.at(root_span),
|
||||
param_env,
|
||||
memory: Memory::new(tcx, memory_extra),
|
||||
recursion_limit: tcx.recursion_limit(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -200,6 +200,7 @@ use rustc_middle::ty::{self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFold
|
|||
use rustc_middle::{middle::codegen_fn_attrs::CodegenFnAttrFlags, mir::visit::TyContext};
|
||||
use rustc_session::config::EntryFnType;
|
||||
use rustc_session::lint::builtin::LARGE_ASSIGNMENTS;
|
||||
use rustc_session::Limit;
|
||||
use rustc_span::source_map::{dummy_spanned, respan, Span, Spanned, DUMMY_SP};
|
||||
use rustc_target::abi::Size;
|
||||
use smallvec::SmallVec;
|
||||
|
@ -294,6 +295,7 @@ pub fn collect_crate_mono_items(
|
|||
|
||||
let mut visited = MTLock::new(FxHashSet::default());
|
||||
let mut inlining_map = MTLock::new(InliningMap::new());
|
||||
let recursion_limit = tcx.recursion_limit(());
|
||||
|
||||
{
|
||||
let visited: MTRef<'_, _> = &mut visited;
|
||||
|
@ -307,6 +309,7 @@ pub fn collect_crate_mono_items(
|
|||
dummy_spanned(root),
|
||||
visited,
|
||||
&mut recursion_depths,
|
||||
recursion_limit,
|
||||
inlining_map,
|
||||
);
|
||||
});
|
||||
|
@ -350,6 +353,7 @@ fn collect_items_rec<'tcx>(
|
|||
starting_point: Spanned<MonoItem<'tcx>>,
|
||||
visited: MTRef<'_, MTLock<FxHashSet<MonoItem<'tcx>>>>,
|
||||
recursion_depths: &mut DefIdMap<usize>,
|
||||
recursion_limit: Limit,
|
||||
inlining_map: MTRef<'_, MTLock<InliningMap<'tcx>>>,
|
||||
) {
|
||||
if !visited.lock_mut().insert(starting_point.node) {
|
||||
|
@ -409,8 +413,13 @@ fn collect_items_rec<'tcx>(
|
|||
debug_assert!(should_codegen_locally(tcx, &instance));
|
||||
|
||||
// Keep track of the monomorphization recursion depth
|
||||
recursion_depth_reset =
|
||||
Some(check_recursion_limit(tcx, instance, starting_point.span, recursion_depths));
|
||||
recursion_depth_reset = Some(check_recursion_limit(
|
||||
tcx,
|
||||
instance,
|
||||
starting_point.span,
|
||||
recursion_depths,
|
||||
recursion_limit,
|
||||
));
|
||||
check_type_length_limit(tcx, instance);
|
||||
|
||||
rustc_data_structures::stack::ensure_sufficient_stack(|| {
|
||||
|
@ -455,7 +464,7 @@ fn collect_items_rec<'tcx>(
|
|||
record_accesses(tcx, starting_point.node, neighbors.iter().map(|i| &i.node), inlining_map);
|
||||
|
||||
for neighbour in neighbors {
|
||||
collect_items_rec(tcx, neighbour, visited, recursion_depths, inlining_map);
|
||||
collect_items_rec(tcx, neighbour, visited, recursion_depths, recursion_limit, inlining_map);
|
||||
}
|
||||
|
||||
if let Some((def_id, depth)) = recursion_depth_reset {
|
||||
|
@ -523,6 +532,7 @@ fn check_recursion_limit<'tcx>(
|
|||
instance: Instance<'tcx>,
|
||||
span: Span,
|
||||
recursion_depths: &mut DefIdMap<usize>,
|
||||
recursion_limit: Limit,
|
||||
) -> (DefId, usize) {
|
||||
let def_id = instance.def_id();
|
||||
let recursion_depth = recursion_depths.get(&def_id).cloned().unwrap_or(0);
|
||||
|
@ -539,7 +549,7 @@ fn check_recursion_limit<'tcx>(
|
|||
// Code that needs to instantiate the same function recursively
|
||||
// more than the recursion limit is assumed to be causing an
|
||||
// infinite expansion.
|
||||
if !tcx.sess.recursion_limit().value_within_limit(adjusted_recursion_depth) {
|
||||
if !recursion_limit.value_within_limit(adjusted_recursion_depth) {
|
||||
let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32);
|
||||
let error = format!("reached the recursion limit while instantiating `{}`", shrunk);
|
||||
let mut err = tcx.sess.struct_span_fatal(span, &error);
|
||||
|
@ -577,7 +587,7 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
|
|||
// which means that rustc basically hangs.
|
||||
//
|
||||
// Bail out in these cases to avoid that bad user experience.
|
||||
if !tcx.sess.type_length_limit().value_within_limit(type_length) {
|
||||
if !tcx.type_length_limit(()).value_within_limit(type_length) {
|
||||
let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32);
|
||||
let msg = format!("reached the type-length limit while instantiating `{}`", shrunk);
|
||||
let mut diag = tcx.sess.struct_span_fatal(tcx.def_span(instance.def_id()), &msg);
|
||||
|
@ -814,7 +824,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
|||
|
||||
fn visit_operand(&mut self, operand: &mir::Operand<'tcx>, location: Location) {
|
||||
self.super_operand(operand, location);
|
||||
let limit = self.tcx.sess.move_size_limit();
|
||||
let limit = self.tcx.move_size_limit(());
|
||||
if limit == 0 {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
|
|||
use rustc_middle::mir::TerminatorKind;
|
||||
use rustc_middle::ty::TypeFoldable;
|
||||
use rustc_middle::ty::{self, subst::SubstsRef, InstanceDef, TyCtxt};
|
||||
use rustc_session::Limit;
|
||||
|
||||
// FIXME: check whether it is cheaper to precompute the entire call graph instead of invoking
|
||||
// this query riddiculously often.
|
||||
|
@ -30,7 +31,7 @@ crate fn mir_callgraph_reachable(
|
|||
);
|
||||
#[instrument(
|
||||
level = "debug",
|
||||
skip(tcx, param_env, target, stack, seen, recursion_limiter, caller)
|
||||
skip(tcx, param_env, target, stack, seen, recursion_limiter, caller, recursion_limit)
|
||||
)]
|
||||
fn process(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
@ -40,6 +41,7 @@ crate fn mir_callgraph_reachable(
|
|||
stack: &mut Vec<ty::Instance<'tcx>>,
|
||||
seen: &mut FxHashSet<ty::Instance<'tcx>>,
|
||||
recursion_limiter: &mut FxHashMap<DefId, usize>,
|
||||
recursion_limit: Limit,
|
||||
) -> bool {
|
||||
trace!(%caller);
|
||||
for &(callee, substs) in tcx.mir_inliner_callees(caller.def) {
|
||||
|
@ -96,11 +98,20 @@ crate fn mir_callgraph_reachable(
|
|||
if seen.insert(callee) {
|
||||
let recursion = recursion_limiter.entry(callee.def_id()).or_default();
|
||||
trace!(?callee, recursion = *recursion);
|
||||
if tcx.sess.recursion_limit().value_within_limit(*recursion) {
|
||||
if recursion_limit.value_within_limit(*recursion) {
|
||||
*recursion += 1;
|
||||
stack.push(callee);
|
||||
let found_recursion = ensure_sufficient_stack(|| {
|
||||
process(tcx, param_env, callee, target, stack, seen, recursion_limiter)
|
||||
process(
|
||||
tcx,
|
||||
param_env,
|
||||
callee,
|
||||
target,
|
||||
stack,
|
||||
seen,
|
||||
recursion_limiter,
|
||||
recursion_limit,
|
||||
)
|
||||
});
|
||||
if found_recursion {
|
||||
return true;
|
||||
|
@ -122,6 +133,7 @@ crate fn mir_callgraph_reachable(
|
|||
&mut Vec::new(),
|
||||
&mut FxHashSet::default(),
|
||||
&mut FxHashMap::default(),
|
||||
tcx.recursion_limit(()),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue