Skip to content

Commit 969a6c2

Browse files
committed
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.
2 parents 6e9b369 + 7e5a88a commit 969a6c2

File tree

31 files changed

+173
-91
lines changed

31 files changed

+173
-91
lines changed

compiler/rustc_interface/src/passes.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,6 @@ pub fn register_plugins<'a>(
211211
});
212212
}
213213

214-
sess.time("recursion_limit", || {
215-
middle::limits::update_limits(sess, &krate);
216-
});
217-
218214
let mut lint_store = rustc_lint::new_lint_store(
219215
sess.opts.debugging_opts.no_interleave_lints,
220216
sess.unstable_options(),
@@ -311,9 +307,11 @@ pub fn configure_and_expand(
311307

312308
// Create the config for macro expansion
313309
let features = sess.features_untracked();
310+
let recursion_limit =
311+
rustc_middle::middle::limits::get_recursion_limit(&krate.attrs, &sess);
314312
let cfg = rustc_expand::expand::ExpansionConfig {
315313
features: Some(&features),
316-
recursion_limit: sess.recursion_limit(),
314+
recursion_limit,
317315
trace_mac: sess.opts.debugging_opts.trace_macros,
318316
should_test: sess.opts.test,
319317
span_debug: sess.opts.debugging_opts.span_debug,
@@ -872,6 +870,13 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
872870
tcx.ensure().check_mod_unstable_api_usage(module);
873871
tcx.ensure().check_mod_const_bodies(module);
874872
});
873+
},
874+
{
875+
// We force these querie to run,
876+
// since they might not otherwise get called.
877+
// This marks the corresponding crate-level attributes
878+
// as used, and ensures that their values are valid.
879+
tcx.ensure().limits(());
875880
}
876881
);
877882
});

compiler/rustc_middle/src/ich/hcx.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> {
245245
}
246246
}
247247

248+
impl rustc_session::HashStableContext for StableHashingContext<'a> {}
249+
248250
pub fn hash_stable_trait_impls<'a>(
249251
hcx: &mut StableHashingContext<'a>,
250252
hasher: &mut StableHasher,

compiler/rustc_middle/src/middle/limits.rs

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,38 +10,46 @@
1010
//! just peeks and looks for that attribute.
1111
1212
use crate::bug;
13-
use rustc_ast as ast;
14-
use rustc_data_structures::sync::OnceCell;
13+
use crate::ty;
14+
use rustc_ast::Attribute;
1515
use rustc_session::Session;
16+
use rustc_session::{Limit, Limits};
1617
use rustc_span::symbol::{sym, Symbol};
1718

1819
use std::num::IntErrorKind;
1920

20-
pub fn update_limits(sess: &Session, krate: &ast::Crate) {
21-
update_limit(sess, krate, &sess.recursion_limit, sym::recursion_limit, 128);
22-
update_limit(sess, krate, &sess.move_size_limit, sym::move_size_limit, 0);
23-
update_limit(sess, krate, &sess.type_length_limit, sym::type_length_limit, 1048576);
24-
update_limit(sess, krate, &sess.const_eval_limit, sym::const_eval_limit, 1_000_000);
21+
pub fn provide(providers: &mut ty::query::Providers) {
22+
providers.limits = |tcx, ()| Limits {
23+
recursion_limit: get_recursion_limit(tcx.hir().krate_attrs(), tcx.sess),
24+
move_size_limit: get_limit(tcx.hir().krate_attrs(), tcx.sess, sym::move_size_limit, 0),
25+
type_length_limit: get_limit(
26+
tcx.hir().krate_attrs(),
27+
tcx.sess,
28+
sym::type_length_limit,
29+
1048576,
30+
),
31+
const_eval_limit: get_limit(
32+
tcx.hir().krate_attrs(),
33+
tcx.sess,
34+
sym::const_eval_limit,
35+
1_000_000,
36+
),
37+
}
38+
}
39+
40+
pub fn get_recursion_limit(krate_attrs: &[Attribute], sess: &Session) -> Limit {
41+
get_limit(krate_attrs, sess, sym::recursion_limit, 128)
2542
}
2643

27-
fn update_limit(
28-
sess: &Session,
29-
krate: &ast::Crate,
30-
limit: &OnceCell<impl From<usize> + std::fmt::Debug>,
31-
name: Symbol,
32-
default: usize,
33-
) {
34-
for attr in &krate.attrs {
44+
fn get_limit(krate_attrs: &[Attribute], sess: &Session, name: Symbol, default: usize) -> Limit {
45+
for attr in krate_attrs {
3546
if !sess.check_name(attr, name) {
3647
continue;
3748
}
3849

3950
if let Some(s) = attr.value_str() {
4051
match s.as_str().parse() {
41-
Ok(n) => {
42-
limit.set(From::from(n)).unwrap();
43-
return;
44-
}
52+
Ok(n) => return Limit::new(n),
4553
Err(e) => {
4654
let mut err =
4755
sess.struct_span_err(attr.span, "`limit` must be a non-negative integer");
@@ -68,5 +76,5 @@ fn update_limit(
6876
}
6977
}
7078
}
71-
limit.set(From::from(default)).unwrap();
79+
return Limit::new(default);
7280
}

compiler/rustc_middle/src/middle/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,7 @@ pub mod privacy;
3232
pub mod region;
3333
pub mod resolve_lifetime;
3434
pub mod stability;
35+
36+
pub fn provide(providers: &mut crate::ty::query::Providers) {
37+
limits::provide(providers);
38+
}

compiler/rustc_middle/src/query/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,4 +1725,8 @@ rustc_queries! {
17251725
query conservative_is_privately_uninhabited(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
17261726
desc { "conservatively checking if {:?} is privately uninhabited", key }
17271727
}
1728+
1729+
query limits(key: ()) -> Limits {
1730+
desc { "looking up limits" }
1731+
}
17281732
}

compiler/rustc_middle/src/ty/context.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ use rustc_middle::ty::OpaqueTypeKey;
5353
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
5454
use rustc_session::config::{BorrowckMode, CrateType, OutputFilenames};
5555
use rustc_session::lint::{Level, Lint};
56+
use rustc_session::Limit;
5657
use rustc_session::Session;
5758
use rustc_span::def_id::StableCrateId;
5859
use rustc_span::source_map::MultiSpan;
@@ -1569,6 +1570,22 @@ impl<'tcx> TyCtxt<'tcx> {
15691570
def_kind => (def_kind.article(), def_kind.descr(def_id)),
15701571
}
15711572
}
1573+
1574+
pub fn type_length_limit(self) -> Limit {
1575+
self.limits(()).type_length_limit
1576+
}
1577+
1578+
pub fn recursion_limit(self) -> Limit {
1579+
self.limits(()).recursion_limit
1580+
}
1581+
1582+
pub fn move_size_limit(self) -> Limit {
1583+
self.limits(()).move_size_limit
1584+
}
1585+
1586+
pub fn const_eval_limit(self) -> Limit {
1587+
self.limits(()).const_eval_limit
1588+
}
15721589
}
15731590

15741591
/// A trait implemented for all `X<'a>` types that can be safely and

compiler/rustc_middle/src/ty/layout.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ fn layout_raw<'tcx>(
221221
ty::tls::with_related_context(tcx, move |icx| {
222222
let (param_env, ty) = query.into_parts();
223223

224-
if !tcx.sess.recursion_limit().value_within_limit(icx.layout_depth) {
224+
if !tcx.recursion_limit().value_within_limit(icx.layout_depth) {
225225
tcx.sess.fatal(&format!("overflow representing the type `{}`", ty));
226226
}
227227

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1987,6 +1987,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
19871987
util::provide(providers);
19881988
print::provide(providers);
19891989
super::util::bug::provide(providers);
1990+
super::middle::provide(providers);
19901991
*providers = ty::query::Providers {
19911992
trait_impls_of: trait_def::trait_impls_of_provider,
19921993
type_uninhabited_from: inhabitedness::type_uninhabited_from,

compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1437,7 +1437,7 @@ impl<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
14371437
}
14381438

14391439
fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
1440-
let type_length_limit = self.tcx.sess.type_length_limit();
1440+
let type_length_limit = self.tcx.type_length_limit();
14411441
if type_length_limit.value_within_limit(self.printed_type_count) {
14421442
self.printed_type_count += 1;
14431443
self.pretty_print_type(ty)

compiler/rustc_middle/src/ty/query/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ use rustc_serialize::opaque;
4949
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
5050
use rustc_session::utils::NativeLibKind;
5151
use rustc_session::CrateDisambiguator;
52+
use rustc_session::Limits;
5253
use rustc_target::spec::PanicStrategy;
5354

5455
use rustc_ast as ast;

0 commit comments

Comments
 (0)