Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions compiler/rustc_interface/src/limits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
use rustc_hir::limit::Limit;
use rustc_hir::{Attribute, find_attr};
use rustc_middle::query::Providers;
use rustc_session::Limits;
use rustc_session::{Limits, Session};

pub(crate) fn provide(providers: &mut Providers) {
providers.limits = |tcx, ()| {
let attrs = tcx.hir_krate_attrs();
Limits {
recursion_limit: get_recursion_limit(tcx.hir_krate_attrs()),
recursion_limit: get_recursion_limit(tcx.hir_krate_attrs(), tcx.sess),
move_size_limit: find_attr!(attrs, MoveSizeLimit { limit, .. } => *limit)
.unwrap_or(Limit::new(tcx.sess.opts.unstable_opts.move_size_limit.unwrap_or(0))),
type_length_limit: find_attr!(attrs, TypeLengthLimit { limit, .. } => *limit)
Expand All @@ -30,6 +30,13 @@ pub(crate) fn provide(providers: &mut Providers) {
}

// This one is separate because it must be read prior to macro expansion.
pub(crate) fn get_recursion_limit(attrs: &[Attribute]) -> Limit {
find_attr!(attrs, RecursionLimit { limit, .. } => *limit).unwrap_or(Limit::new(128))
pub(crate) fn get_recursion_limit(attrs: &[Attribute], sess: &Session) -> Limit {
let limit_from_crate =
find_attr!(attrs, RecursionLimit { limit, .. } => limit.0).unwrap_or(128);
Limit::new(
sess.opts
.unstable_opts
.min_recursion_limit
.map_or(limit_from_crate, |min| min.max(limit_from_crate)),
)
}
2 changes: 1 addition & 1 deletion compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1429,5 +1429,5 @@ fn get_recursion_limit(krate_attrs: &[ast::Attribute], sess: &Session) -> Limit
// So, no lints here to avoid duplicates.
ShouldEmit::EarlyFatal { also_emit_lints: false },
);
crate::limits::get_recursion_limit(attr.as_slice())
crate::limits::get_recursion_limit(attr.as_slice(), sess)
}
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(maximal_hir_to_mir_coverage, true);
tracked!(merge_functions, Some(MergeFunctions::Disabled));
tracked!(min_function_alignment, Some(Align::EIGHT));
tracked!(min_recursion_limit, Some(256));
tracked!(mir_emit_retag, true);
tracked!(mir_enable_passes, vec![("DestProp".to_string(), false)]);
tracked!(mir_opt_level, Some(4));
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2456,6 +2456,8 @@ options! {
"the directory metrics emitted by rustc are dumped into (implicitly enables default set of metrics)"),
min_function_alignment: Option<Align> = (None, parse_align, [TRACKED],
"align all functions to at least this many bytes. Must be a power of 2"),
min_recursion_limit: Option<usize> = (None, parse_opt_number, [TRACKED],
"set a minimum recursion limit (final limit = max(this, recursion_limit_from_crate))"),
mir_emit_retag: bool = (false, parse_bool, [TRACKED],
"emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
(default: no)"),
Expand Down
12 changes: 12 additions & 0 deletions src/doc/unstable-book/src/compiler-flags/min-recursive-limit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# `min-recursion-limit`

This flag sets a minimum recursion limit for the compiler. The final recursion limit is calculated as `max(min_recursion_limit, recursion_limit_from_crate)`. This cannot ever lower the recursion limit. Unless the current crate has an explicitly low `recursion_limit` attribute, any value less than the current default does not have an effect.

The recursion limit affects (among other things):

- macro expansion
- the trait solver
- const evaluation
- query depth

This flag is particularly useful when using the next trait solver (`-Z next-solver`), which may require a higher recursion limit for crates that were compiled successfully with the old solver.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//@ compile-flags: -Z min-recursion-limit=0
//@ check-pass

// Checks that `min-recursion-limit` cannot lower the default recursion limit

macro_rules! count {
() => {};
($_:tt $($rest:tt)*) => { count!($($rest)*) };
}

fn main() {
// 100
count!(
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//@ compile-flags: -Z min-recursion-limit=256
//@ check-pass
#![recursion_limit = "128"]

macro_rules! count {
() => {};
($_:tt $($rest:tt)*) => { count!($($rest)*) };
}

fn main() {
// 200
count!(
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
);
}
24 changes: 24 additions & 0 deletions tests/ui/recursion/recursion_limit/min-recursion-limit-cli-wins.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//@ compile-flags: -Z min-recursion-limit=64
//@ check-pass
#![recursion_limit = "256"]

macro_rules! count {
() => {};
($_:tt $($rest:tt)*) => { count!($($rest)*) };
}

fn main() {
// 200
count!(
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
);
}
23 changes: 23 additions & 0 deletions tests/ui/recursion/recursion_limit/min-recursion-limit-no-attr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//@ compile-flags: -Z min-recursion-limit=256
//@ check-pass

macro_rules! count {
() => {};
($_:tt $($rest:tt)*) => { count!($($rest)*) };
}

fn main() {
// 200
count!(
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a
);
}
Loading