Query-ify global limit attribute handling
This commit is contained in:
parent
90442458ac
commit
ff15b5e2c7
30 changed files with 153 additions and 91 deletions
|
@ -245,6 +245,8 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl rustc_session::HashStableContext for StableHashingContext<'a> {}
|
||||
|
||||
pub fn hash_stable_trait_impls<'a>(
|
||||
hcx: &mut StableHashingContext<'a>,
|
||||
hasher: &mut StableHasher,
|
||||
|
|
|
@ -10,38 +10,37 @@
|
|||
//! just peeks and looks for that attribute.
|
||||
|
||||
use crate::bug;
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::sync::OnceCell;
|
||||
use crate::ty;
|
||||
use rustc_ast::Attribute;
|
||||
use rustc_session::Limit;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
|
||||
use std::num::IntErrorKind;
|
||||
|
||||
pub fn update_limits(sess: &Session, krate: &ast::Crate) {
|
||||
update_limit(sess, krate, &sess.recursion_limit, sym::recursion_limit, 128);
|
||||
update_limit(sess, krate, &sess.move_size_limit, sym::move_size_limit, 0);
|
||||
update_limit(sess, krate, &sess.type_length_limit, sym::type_length_limit, 1048576);
|
||||
update_limit(sess, krate, &sess.const_eval_limit, sym::const_eval_limit, 1_000_000);
|
||||
pub fn provide(providers: &mut ty::query::Providers) {
|
||||
providers.recursion_limit = |tcx, ()| get_recursion_limit(tcx.hir().krate_attrs(), tcx.sess);
|
||||
providers.move_size_limit =
|
||||
|tcx, ()| get_limit(tcx.hir().krate_attrs(), tcx.sess, sym::move_size_limit, 0).0;
|
||||
providers.type_length_limit =
|
||||
|tcx, ()| get_limit(tcx.hir().krate_attrs(), tcx.sess, sym::type_length_limit, 1048576);
|
||||
providers.const_eval_limit =
|
||||
|tcx, ()| get_limit(tcx.hir().krate_attrs(), tcx.sess, sym::const_eval_limit, 1_000_000);
|
||||
}
|
||||
|
||||
fn update_limit(
|
||||
sess: &Session,
|
||||
krate: &ast::Crate,
|
||||
limit: &OnceCell<impl From<usize> + std::fmt::Debug>,
|
||||
name: Symbol,
|
||||
default: usize,
|
||||
) {
|
||||
for attr in &krate.attrs {
|
||||
pub fn get_recursion_limit(krate_attrs: &[Attribute], sess: &Session) -> Limit {
|
||||
get_limit(krate_attrs, sess, sym::recursion_limit, 128)
|
||||
}
|
||||
|
||||
fn get_limit(krate_attrs: &[Attribute], sess: &Session, name: Symbol, default: usize) -> Limit {
|
||||
for attr in krate_attrs {
|
||||
if !sess.check_name(attr, name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(s) = attr.value_str() {
|
||||
match s.as_str().parse() {
|
||||
Ok(n) => {
|
||||
limit.set(From::from(n)).unwrap();
|
||||
return;
|
||||
}
|
||||
Ok(n) => return Limit::new(n),
|
||||
Err(e) => {
|
||||
let mut err =
|
||||
sess.struct_span_err(attr.span, "`limit` must be a non-negative integer");
|
||||
|
@ -68,5 +67,5 @@ fn update_limit(
|
|||
}
|
||||
}
|
||||
}
|
||||
limit.set(From::from(default)).unwrap();
|
||||
return Limit::new(default);
|
||||
}
|
||||
|
|
|
@ -32,3 +32,7 @@ pub mod privacy;
|
|||
pub mod region;
|
||||
pub mod resolve_lifetime;
|
||||
pub mod stability;
|
||||
|
||||
pub fn provide(providers: &mut crate::ty::query::Providers) {
|
||||
limits::provide(providers);
|
||||
}
|
||||
|
|
|
@ -1712,4 +1712,26 @@ rustc_queries! {
|
|||
query conservative_is_privately_uninhabited(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
|
||||
desc { "conservatively checking if {:?} is privately uninhabited", key }
|
||||
}
|
||||
|
||||
/// The maximum recursion limit for potentially infinitely recursive
|
||||
/// operations such as auto-dereference and monomorphization.
|
||||
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" }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -221,7 +221,7 @@ fn layout_raw<'tcx>(
|
|||
ty::tls::with_related_context(tcx, move |icx| {
|
||||
let (param_env, ty) = query.into_parts();
|
||||
|
||||
if !tcx.sess.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));
|
||||
}
|
||||
|
||||
|
|
|
@ -1987,6 +1987,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
|
|||
util::provide(providers);
|
||||
print::provide(providers);
|
||||
super::util::bug::provide(providers);
|
||||
super::middle::provide(providers);
|
||||
*providers = ty::query::Providers {
|
||||
trait_impls_of: trait_def::trait_impls_of_provider,
|
||||
type_uninhabited_from: inhabitedness::type_uninhabited_from,
|
||||
|
|
|
@ -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> {
|
||||
let type_length_limit = self.tcx.sess.type_length_limit();
|
||||
let type_length_limit = self.tcx.type_length_limit(());
|
||||
if type_length_limit.value_within_limit(self.printed_type_count) {
|
||||
self.printed_type_count += 1;
|
||||
self.pretty_print_type(ty)
|
||||
|
|
|
@ -49,6 +49,7 @@ use rustc_serialize::opaque;
|
|||
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
|
||||
use rustc_session::utils::NativeLibKind;
|
||||
use rustc_session::CrateDisambiguator;
|
||||
use rustc_session::Limit;
|
||||
use rustc_target::spec::PanicStrategy;
|
||||
|
||||
use rustc_ast as ast;
|
||||
|
|
|
@ -206,8 +206,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
mut ty: Ty<'tcx>,
|
||||
normalize: impl Fn(Ty<'tcx>) -> Ty<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
let recursion_limit = self.recursion_limit(());
|
||||
for iteration in 0.. {
|
||||
if !self.sess.recursion_limit().value_within_limit(iteration) {
|
||||
if !recursion_limit.value_within_limit(iteration) {
|
||||
return self.ty_error_with_message(
|
||||
DUMMY_SP,
|
||||
&format!("reached the recursion limit finding the struct tail for {}", ty),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue