mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 11:48:30 +00:00
Combine individual limit queries into single limits
query
This commit is contained in:
parent
ff15b5e2c7
commit
7e5a88a56c
@ -872,13 +872,11 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Mark the attributes as used, and ensure that
|
// We force these querie to run,
|
||||||
// they're not ill-formed. We force these queries
|
// since they might not otherwise get called.
|
||||||
// to run, since they might not otherwise get called.
|
// This marks the corresponding crate-level attributes
|
||||||
tcx.ensure().recursion_limit(());
|
// as used, and ensures that their values are valid.
|
||||||
tcx.ensure().move_size_limit(());
|
tcx.ensure().limits(());
|
||||||
tcx.ensure().type_length_limit(());
|
|
||||||
tcx.ensure().const_eval_limit(());
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -12,20 +12,29 @@
|
|||||||
use crate::bug;
|
use crate::bug;
|
||||||
use crate::ty;
|
use crate::ty;
|
||||||
use rustc_ast::Attribute;
|
use rustc_ast::Attribute;
|
||||||
use rustc_session::Limit;
|
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
|
use rustc_session::{Limit, Limits};
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
|
|
||||||
use std::num::IntErrorKind;
|
use std::num::IntErrorKind;
|
||||||
|
|
||||||
pub fn provide(providers: &mut ty::query::Providers) {
|
pub fn provide(providers: &mut ty::query::Providers) {
|
||||||
providers.recursion_limit = |tcx, ()| get_recursion_limit(tcx.hir().krate_attrs(), tcx.sess);
|
providers.limits = |tcx, ()| Limits {
|
||||||
providers.move_size_limit =
|
recursion_limit: get_recursion_limit(tcx.hir().krate_attrs(), tcx.sess),
|
||||||
|tcx, ()| get_limit(tcx.hir().krate_attrs(), tcx.sess, sym::move_size_limit, 0).0;
|
move_size_limit: get_limit(tcx.hir().krate_attrs(), tcx.sess, sym::move_size_limit, 0),
|
||||||
providers.type_length_limit =
|
type_length_limit: get_limit(
|
||||||
|tcx, ()| get_limit(tcx.hir().krate_attrs(), tcx.sess, sym::type_length_limit, 1048576);
|
tcx.hir().krate_attrs(),
|
||||||
providers.const_eval_limit =
|
tcx.sess,
|
||||||
|tcx, ()| get_limit(tcx.hir().krate_attrs(), tcx.sess, sym::const_eval_limit, 1_000_000);
|
sym::type_length_limit,
|
||||||
|
1048576,
|
||||||
|
),
|
||||||
|
const_eval_limit: get_limit(
|
||||||
|
tcx.hir().krate_attrs(),
|
||||||
|
tcx.sess,
|
||||||
|
sym::const_eval_limit,
|
||||||
|
1_000_000,
|
||||||
|
),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_recursion_limit(krate_attrs: &[Attribute], sess: &Session) -> Limit {
|
pub fn get_recursion_limit(krate_attrs: &[Attribute], sess: &Session) -> Limit {
|
||||||
|
@ -1713,25 +1713,7 @@ rustc_queries! {
|
|||||||
desc { "conservatively checking if {:?} is privately uninhabited", key }
|
desc { "conservatively checking if {:?} is privately uninhabited", key }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The maximum recursion limit for potentially infinitely recursive
|
query limits(key: ()) -> Limits {
|
||||||
/// operations such as auto-dereference and monomorphization.
|
desc { "looking up limits" }
|
||||||
query recursion_limit(key: ()) -> Limit {
|
|
||||||
desc { "looking up recursion limit" }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The size at which the `large_assignments` lint starts
|
|
||||||
/// being emitted.
|
|
||||||
query move_size_limit(key: ()) -> usize {
|
|
||||||
desc { "looking up move size limit" }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The maximum length of types during monomorphization.
|
|
||||||
query type_length_limit(key: ()) -> Limit {
|
|
||||||
desc { "looking up type length limit" }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The maximum blocks a const expression can evaluate.
|
|
||||||
query const_eval_limit(key: ()) -> Limit {
|
|
||||||
desc { "looking up const eval limit" }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ use rustc_middle::ty::OpaqueTypeKey;
|
|||||||
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
|
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
|
||||||
use rustc_session::config::{BorrowckMode, CrateType, OutputFilenames};
|
use rustc_session::config::{BorrowckMode, CrateType, OutputFilenames};
|
||||||
use rustc_session::lint::{Level, Lint};
|
use rustc_session::lint::{Level, Lint};
|
||||||
|
use rustc_session::Limit;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::def_id::StableCrateId;
|
use rustc_span::def_id::StableCrateId;
|
||||||
use rustc_span::source_map::MultiSpan;
|
use rustc_span::source_map::MultiSpan;
|
||||||
@ -1569,6 +1570,22 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
def_kind => (def_kind.article(), def_kind.descr(def_id)),
|
def_kind => (def_kind.article(), def_kind.descr(def_id)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn type_length_limit(self) -> Limit {
|
||||||
|
self.limits(()).type_length_limit
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn recursion_limit(self) -> Limit {
|
||||||
|
self.limits(()).recursion_limit
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn move_size_limit(self) -> Limit {
|
||||||
|
self.limits(()).move_size_limit
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn const_eval_limit(self) -> Limit {
|
||||||
|
self.limits(()).const_eval_limit
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A trait implemented for all `X<'a>` types that can be safely and
|
/// A trait implemented for all `X<'a>` types that can be safely and
|
||||||
|
@ -221,7 +221,7 @@ fn layout_raw<'tcx>(
|
|||||||
ty::tls::with_related_context(tcx, move |icx| {
|
ty::tls::with_related_context(tcx, move |icx| {
|
||||||
let (param_env, ty) = query.into_parts();
|
let (param_env, ty) = query.into_parts();
|
||||||
|
|
||||||
if !tcx.recursion_limit(()).value_within_limit(icx.layout_depth) {
|
if !tcx.recursion_limit().value_within_limit(icx.layout_depth) {
|
||||||
tcx.sess.fatal(&format!("overflow representing the type `{}`", ty));
|
tcx.sess.fatal(&format!("overflow representing the type `{}`", ty));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1437,7 +1437,7 @@ impl<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
|
fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
|
||||||
let type_length_limit = self.tcx.type_length_limit(());
|
let type_length_limit = self.tcx.type_length_limit();
|
||||||
if type_length_limit.value_within_limit(self.printed_type_count) {
|
if type_length_limit.value_within_limit(self.printed_type_count) {
|
||||||
self.printed_type_count += 1;
|
self.printed_type_count += 1;
|
||||||
self.pretty_print_type(ty)
|
self.pretty_print_type(ty)
|
||||||
|
@ -49,7 +49,7 @@ use rustc_serialize::opaque;
|
|||||||
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
|
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
|
||||||
use rustc_session::utils::NativeLibKind;
|
use rustc_session::utils::NativeLibKind;
|
||||||
use rustc_session::CrateDisambiguator;
|
use rustc_session::CrateDisambiguator;
|
||||||
use rustc_session::Limit;
|
use rustc_session::Limits;
|
||||||
use rustc_target::spec::PanicStrategy;
|
use rustc_target::spec::PanicStrategy;
|
||||||
|
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
|
@ -206,7 +206,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
mut ty: Ty<'tcx>,
|
mut ty: Ty<'tcx>,
|
||||||
normalize: impl Fn(Ty<'tcx>) -> Ty<'tcx>,
|
normalize: impl Fn(Ty<'tcx>) -> Ty<'tcx>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let recursion_limit = self.recursion_limit(());
|
let recursion_limit = self.recursion_limit();
|
||||||
for iteration in 0.. {
|
for iteration in 0.. {
|
||||||
if !recursion_limit.value_within_limit(iteration) {
|
if !recursion_limit.value_within_limit(iteration) {
|
||||||
return self.ty_error_with_message(
|
return self.ty_error_with_message(
|
||||||
|
@ -98,7 +98,7 @@ pub(super) fn mk_eval_cx<'mir, 'tcx>(
|
|||||||
tcx,
|
tcx,
|
||||||
root_span,
|
root_span,
|
||||||
param_env,
|
param_env,
|
||||||
CompileTimeInterpreter::new(tcx.const_eval_limit(())),
|
CompileTimeInterpreter::new(tcx.const_eval_limit()),
|
||||||
MemoryExtra { can_access_statics },
|
MemoryExtra { can_access_statics },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -300,7 +300,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
|
|||||||
tcx,
|
tcx,
|
||||||
tcx.def_span(def.did),
|
tcx.def_span(def.did),
|
||||||
key.param_env,
|
key.param_env,
|
||||||
CompileTimeInterpreter::new(tcx.const_eval_limit(())),
|
CompileTimeInterpreter::new(tcx.const_eval_limit()),
|
||||||
// Statics (and promoteds inside statics) may access other statics, because unlike consts
|
// 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.
|
// they do not have to behave "as if" they were evaluated at runtime.
|
||||||
MemoryExtra { can_access_statics: is_static },
|
MemoryExtra { can_access_statics: is_static },
|
||||||
|
@ -392,7 +392,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
tcx: tcx.at(root_span),
|
tcx: tcx.at(root_span),
|
||||||
param_env,
|
param_env,
|
||||||
memory: Memory::new(tcx, memory_extra),
|
memory: Memory::new(tcx, memory_extra),
|
||||||
recursion_limit: tcx.recursion_limit(()),
|
recursion_limit: tcx.recursion_limit(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +295,7 @@ pub fn collect_crate_mono_items(
|
|||||||
|
|
||||||
let mut visited = MTLock::new(FxHashSet::default());
|
let mut visited = MTLock::new(FxHashSet::default());
|
||||||
let mut inlining_map = MTLock::new(InliningMap::new());
|
let mut inlining_map = MTLock::new(InliningMap::new());
|
||||||
let recursion_limit = tcx.recursion_limit(());
|
let recursion_limit = tcx.recursion_limit();
|
||||||
|
|
||||||
{
|
{
|
||||||
let visited: MTRef<'_, _> = &mut visited;
|
let visited: MTRef<'_, _> = &mut visited;
|
||||||
@ -587,7 +587,7 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
|
|||||||
// which means that rustc basically hangs.
|
// which means that rustc basically hangs.
|
||||||
//
|
//
|
||||||
// Bail out in these cases to avoid that bad user experience.
|
// Bail out in these cases to avoid that bad user experience.
|
||||||
if !tcx.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 (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32);
|
||||||
let msg = format!("reached the type-length limit while instantiating `{}`", shrunk);
|
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);
|
let mut diag = tcx.sess.struct_span_fatal(tcx.def_span(instance.def_id()), &msg);
|
||||||
@ -824,7 +824,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
|||||||
|
|
||||||
fn visit_operand(&mut self, operand: &mir::Operand<'tcx>, location: Location) {
|
fn visit_operand(&mut self, operand: &mir::Operand<'tcx>, location: Location) {
|
||||||
self.super_operand(operand, location);
|
self.super_operand(operand, location);
|
||||||
let limit = self.tcx.move_size_limit(());
|
let limit = self.tcx.move_size_limit().0;
|
||||||
if limit == 0 {
|
if limit == 0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ crate fn mir_callgraph_reachable(
|
|||||||
&mut Vec::new(),
|
&mut Vec::new(),
|
||||||
&mut FxHashSet::default(),
|
&mut FxHashSet::default(),
|
||||||
&mut FxHashMap::default(),
|
&mut FxHashMap::default(),
|
||||||
tcx.recursion_limit(()),
|
tcx.recursion_limit(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,6 +112,20 @@ impl Mul<usize> for Limit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, HashStable_Generic)]
|
||||||
|
pub struct Limits {
|
||||||
|
/// The maximum recursion limit for potentially infinitely recursive
|
||||||
|
/// operations such as auto-dereference and monomorphization.
|
||||||
|
pub recursion_limit: Limit,
|
||||||
|
/// The size at which the `large_assignments` lint starts
|
||||||
|
/// being emitted.
|
||||||
|
pub move_size_limit: Limit,
|
||||||
|
/// The maximum length of types during monomorphization.
|
||||||
|
pub type_length_limit: Limit,
|
||||||
|
/// The maximum blocks a const expression can evaluate.
|
||||||
|
pub const_eval_limit: Limit,
|
||||||
|
}
|
||||||
|
|
||||||
/// Represents the data associated with a compilation
|
/// Represents the data associated with a compilation
|
||||||
/// session for a single crate.
|
/// session for a single crate.
|
||||||
pub struct Session {
|
pub struct Session {
|
||||||
|
@ -53,7 +53,7 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we have reached the recursion limit, error gracefully.
|
// If we have reached the recursion limit, error gracefully.
|
||||||
if !tcx.recursion_limit(()).value_within_limit(self.state.steps.len()) {
|
if !tcx.recursion_limit().value_within_limit(self.state.steps.len()) {
|
||||||
if !self.silence_errors {
|
if !self.silence_errors {
|
||||||
report_autoderef_recursion_limit_error(tcx, self.span, self.state.cur_ty);
|
report_autoderef_recursion_limit_error(tcx, self.span, self.state.cur_ty);
|
||||||
}
|
}
|
||||||
@ -217,7 +217,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
|
|||||||
|
|
||||||
pub fn report_autoderef_recursion_limit_error<'tcx>(tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'tcx>) {
|
pub fn report_autoderef_recursion_limit_error<'tcx>(tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'tcx>) {
|
||||||
// We've reached the recursion limit, error gracefully.
|
// We've reached the recursion limit, error gracefully.
|
||||||
let suggested_limit = tcx.recursion_limit(()) * 2;
|
let suggested_limit = tcx.recursion_limit() * 2;
|
||||||
let msg = format!("reached the recursion limit while auto-dereferencing `{:?}`", ty);
|
let msg = format!("reached the recursion limit while auto-dereferencing `{:?}`", ty);
|
||||||
let error_id = (DiagnosticMessageId::ErrorId(55), Some(span), msg);
|
let error_id = (DiagnosticMessageId::ErrorId(55), Some(span), msg);
|
||||||
let fresh = tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id);
|
let fresh = tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id);
|
||||||
|
@ -2310,7 +2310,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder<'_>) {
|
fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder<'_>) {
|
||||||
let current_limit = self.tcx.recursion_limit(());
|
let current_limit = self.tcx.recursion_limit();
|
||||||
let suggested_limit = current_limit * 2;
|
let suggested_limit = current_limit * 2;
|
||||||
err.help(&format!(
|
err.help(&format!(
|
||||||
"consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate (`{}`)",
|
"consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate (`{}`)",
|
||||||
|
@ -344,7 +344,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||||||
Reveal::UserFacing => ty,
|
Reveal::UserFacing => ty,
|
||||||
|
|
||||||
Reveal::All => {
|
Reveal::All => {
|
||||||
let recursion_limit = self.tcx().recursion_limit(());
|
let recursion_limit = self.tcx().recursion_limit();
|
||||||
if !recursion_limit.value_within_limit(self.depth) {
|
if !recursion_limit.value_within_limit(self.depth) {
|
||||||
let obligation = Obligation::with_depth(
|
let obligation = Obligation::with_depth(
|
||||||
self.cause.clone(),
|
self.cause.clone(),
|
||||||
@ -726,7 +726,7 @@ fn project_type<'cx, 'tcx>(
|
|||||||
) -> Result<ProjectedTy<'tcx>, ProjectionTyError<'tcx>> {
|
) -> Result<ProjectedTy<'tcx>, ProjectionTyError<'tcx>> {
|
||||||
debug!(?obligation, "project_type");
|
debug!(?obligation, "project_type");
|
||||||
|
|
||||||
if !selcx.tcx().recursion_limit(()).value_within_limit(obligation.recursion_depth) {
|
if !selcx.tcx().recursion_limit().value_within_limit(obligation.recursion_depth) {
|
||||||
debug!("project: overflow!");
|
debug!("project: overflow!");
|
||||||
// This should really be an immediate error, but some existing code
|
// This should really be an immediate error, but some existing code
|
||||||
// relies on being able to recover from this.
|
// relies on being able to recover from this.
|
||||||
|
@ -116,7 +116,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||||||
Reveal::UserFacing => ty,
|
Reveal::UserFacing => ty,
|
||||||
|
|
||||||
Reveal::All => {
|
Reveal::All => {
|
||||||
let recursion_limit = self.tcx().recursion_limit(());
|
let recursion_limit = self.tcx().recursion_limit();
|
||||||
if !recursion_limit.value_within_limit(self.anon_depth) {
|
if !recursion_limit.value_within_limit(self.anon_depth) {
|
||||||
let obligation = Obligation::with_depth(
|
let obligation = Obligation::with_depth(
|
||||||
self.cause.clone(),
|
self.cause.clone(),
|
||||||
|
@ -993,7 +993,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
obligation: &Obligation<'tcx, T>,
|
obligation: &Obligation<'tcx, T>,
|
||||||
error_obligation: &Obligation<'tcx, V>,
|
error_obligation: &Obligation<'tcx, V>,
|
||||||
) -> Result<(), OverflowError> {
|
) -> Result<(), OverflowError> {
|
||||||
if !self.infcx.tcx.recursion_limit(()).value_within_limit(obligation.recursion_depth) {
|
if !self.infcx.tcx.recursion_limit().value_within_limit(obligation.recursion_depth) {
|
||||||
match self.query_mode {
|
match self.query_mode {
|
||||||
TraitQueryMode::Standard => {
|
TraitQueryMode::Standard => {
|
||||||
self.infcx().report_overflow_error(error_obligation, true);
|
self.infcx().report_overflow_error(error_obligation, true);
|
||||||
|
@ -163,7 +163,7 @@ fn dtorck_constraint_for_ty<'tcx>(
|
|||||||
) -> Result<(), NoSolution> {
|
) -> Result<(), NoSolution> {
|
||||||
debug!("dtorck_constraint_for_ty({:?}, {:?}, {:?}, {:?})", span, for_ty, depth, ty);
|
debug!("dtorck_constraint_for_ty({:?}, {:?}, {:?}, {:?})", span, for_ty, depth, ty);
|
||||||
|
|
||||||
if !tcx.recursion_limit(()).value_within_limit(depth) {
|
if !tcx.recursion_limit().value_within_limit(depth) {
|
||||||
constraints.overflows.push(ty);
|
constraints.overflows.push(ty);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ impl<'tcx, F> NeedsDropTypes<'tcx, F> {
|
|||||||
seen_tys,
|
seen_tys,
|
||||||
query_ty: ty,
|
query_ty: ty,
|
||||||
unchecked_tys: vec![(ty, 0)],
|
unchecked_tys: vec![(ty, 0)],
|
||||||
recursion_limit: tcx.recursion_limit(()),
|
recursion_limit: tcx.recursion_limit(),
|
||||||
adt_components,
|
adt_components,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user