Auto merge of #86674 - Aaron1011:new-querify-limits, r=michaelwoerister
Query-ify global limit attribute handling Currently, we read various 'global limits' from inner attributes the crate root (`recursion_limit`, `move_size_limit`, `type_length_limit`, `const_eval_limit`). These limits are then stored in `Sessions`, allowing them to be access from a `TyCtxt` without registering a dependency on the crate root attributes. This PR moves the calculation of these global limits behind queries, so that we properly track dependencies on crate root attributes. During the setup of macro expansion (before we've created a `TyCtxt`), we need to access the recursion limit, which is now done by directly calling into the code shared by the normal query implementations.
This commit is contained in:
commit
969a6c2481
31 changed files with 173 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,46 @@
|
|||
//! 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::Session;
|
||||
use rustc_session::{Limit, Limits};
|
||||
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.limits = |tcx, ()| Limits {
|
||||
recursion_limit: get_recursion_limit(tcx.hir().krate_attrs(), tcx.sess),
|
||||
move_size_limit: get_limit(tcx.hir().krate_attrs(), tcx.sess, sym::move_size_limit, 0),
|
||||
type_length_limit: get_limit(
|
||||
tcx.hir().krate_attrs(),
|
||||
tcx.sess,
|
||||
sym::type_length_limit,
|
||||
1048576,
|
||||
),
|
||||
const_eval_limit: 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 +76,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);
|
||||
}
|
||||
|
|
|
@ -1725,4 +1725,8 @@ rustc_queries! {
|
|||
query conservative_is_privately_uninhabited(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
|
||||
desc { "conservatively checking if {:?} is privately uninhabited", key }
|
||||
}
|
||||
|
||||
query limits(key: ()) -> Limits {
|
||||
desc { "looking up limits" }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ use rustc_middle::ty::OpaqueTypeKey;
|
|||
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
|
||||
use rustc_session::config::{BorrowckMode, CrateType, OutputFilenames};
|
||||
use rustc_session::lint::{Level, Lint};
|
||||
use rustc_session::Limit;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::def_id::StableCrateId;
|
||||
use rustc_span::source_map::MultiSpan;
|
||||
|
@ -1569,6 +1570,22 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
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
|
||||
|
|
|
@ -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::Limits;
|
||||
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