Skip to content

Commit 9b49e75

Browse files
committed
add new unstable flag for minimal recursion
1 parent 6f54d59 commit 9b49e75

File tree

10 files changed

+159
-5
lines changed

10 files changed

+159
-5
lines changed

compiler/rustc_interface/src/limits.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
use rustc_hir::limit::Limit;
1212
use rustc_hir::{Attribute, find_attr};
1313
use rustc_middle::query::Providers;
14-
use rustc_session::Limits;
14+
use rustc_session::{Limits, Session};
1515

1616
pub(crate) fn provide(providers: &mut Providers) {
1717
providers.limits = |tcx, ()| {
1818
let attrs = tcx.hir_krate_attrs();
1919
Limits {
20-
recursion_limit: get_recursion_limit(tcx.hir_krate_attrs()),
20+
recursion_limit: get_recursion_limit(tcx.hir_krate_attrs(), tcx.sess),
2121
move_size_limit: find_attr!(attrs, MoveSizeLimit { limit, .. } => *limit)
2222
.unwrap_or(Limit::new(tcx.sess.opts.unstable_opts.move_size_limit.unwrap_or(0))),
2323
type_length_limit: find_attr!(attrs, TypeLengthLimit { limit, .. } => *limit)
@@ -30,6 +30,12 @@ pub(crate) fn provide(providers: &mut Providers) {
3030
}
3131

3232
// This one is separate because it must be read prior to macro expansion.
33-
pub(crate) fn get_recursion_limit(attrs: &[Attribute]) -> Limit {
34-
find_attr!(attrs, RecursionLimit { limit, .. } => *limit).unwrap_or(Limit::new(128))
33+
pub(crate) fn get_recursion_limit(attrs: &[Attribute], sess: &Session) -> Limit {
34+
Limit::new(
35+
sess.opts
36+
.unstable_opts
37+
.min_recursion_limit
38+
.max(find_attr!(attrs, RecursionLimit { limit, .. } => limit.0))
39+
.unwrap_or(128),
40+
)
3541
}

compiler/rustc_interface/src/passes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1420,5 +1420,5 @@ fn get_recursion_limit(krate_attrs: &[ast::Attribute], sess: &Session) -> Limit
14201420
// So, no lints here to avoid duplicates.
14211421
ShouldEmit::EarlyFatal { also_emit_lints: false },
14221422
);
1423-
crate::limits::get_recursion_limit(attr.as_slice())
1423+
crate::limits::get_recursion_limit(attr.as_slice(), sess)
14241424
}

compiler/rustc_interface/src/tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,7 @@ fn test_unstable_options_tracking_hash() {
822822
tracked!(maximal_hir_to_mir_coverage, true);
823823
tracked!(merge_functions, Some(MergeFunctions::Disabled));
824824
tracked!(min_function_alignment, Some(Align::EIGHT));
825+
tracked!(min_recursion_limit, Some(256));
825826
tracked!(mir_emit_retag, true);
826827
tracked!(mir_enable_passes, vec![("DestProp".to_string(), false)]);
827828
tracked!(mir_opt_level, Some(4));

compiler/rustc_session/src/options.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2456,6 +2456,8 @@ options! {
24562456
"the directory metrics emitted by rustc are dumped into (implicitly enables default set of metrics)"),
24572457
min_function_alignment: Option<Align> = (None, parse_align, [TRACKED],
24582458
"align all functions to at least this many bytes. Must be a power of 2"),
2459+
min_recursion_limit: Option<usize> = (None, parse_opt_number, [TRACKED],
2460+
"set a minimum recursion limit (final limit = max(this, crate attribute))"),
24592461
mir_emit_retag: bool = (false, parse_bool, [TRACKED],
24602462
"emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
24612463
(default: no)"),
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# `min-recursion-limit`
2+
3+
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)`.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//@ compile-flags: -Z min-recursion-limit=256
2+
#![recursion_limit = "128"]
3+
4+
macro_rules! count {
5+
() => {};
6+
($_:tt $($rest:tt)*) => { count!($($rest)*) }; //~ ERROR recursion limit reached while expanding `count!`
7+
}
8+
9+
fn main() {
10+
count!(
11+
a a a a a a a a a a a a a a a a a a a a
12+
a a a a a a a a a a a a a a a a a a a a
13+
a a a a a a a a a a a a a a a a a a a a
14+
a a a a a a a a a a a a a a a a a a a a
15+
a a a a a a a a a a a a a a a a a a a a
16+
a a a a a a a a a a a a a a a a a a a a
17+
a a a a a a a a a a a a a a a a a a a a
18+
a a a a a a a a a a a a a a a a a a a a
19+
a a a a a a a a a a a a a a a a a a a a
20+
a a a a a a a a a a a a a a a a a a a a
21+
); // 200
22+
23+
count!( // this one is erroring, because recursion is more than 256
24+
a a a a a a a a a a a a a a a a a a a a
25+
a a a a a a a a a a a a a a a a a a a a
26+
a a a a a a a a a a a a a a a a a a a a
27+
a a a a a a a a a a a a a a a a a a a a
28+
a a a a a a a a a a a a a a a a a a a a
29+
a a a a a a a a a a a a a a a a a a a a
30+
a a a a a a a a a a a a a a a a a a a a
31+
a a a a a a a a a a a a a a a a a a a a
32+
a a a a a a a a a a a a a a a a a a a a
33+
a a a a a a a a a a a a a a a a a a a a
34+
a a a a a a a a a a a a a a a a a a a a
35+
a a a a a a a a a a a a a a a a a a a a
36+
a a a a a a a a a a a a a a a a a a a a
37+
a a a a a a a a a a a a a a a a a a a a
38+
a a a a a a a a a a a a a a a a a a a a
39+
);
40+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: recursion limit reached while expanding `count!`
2+
--> $DIR/min-recursion-limit-attr-wins.rs:6:31
3+
|
4+
LL | ($_:tt $($rest:tt)*) => { count!($($rest)*) };
5+
| ^^^^^^^^^^^^^^^^^
6+
...
7+
LL | / count!( // this one is erroring, because recursion is more than 256
8+
LL | | a a a a a a a a a a a a a a a a a a a a
9+
LL | | a a a a a a a a a a a a a a a a a a a a
10+
LL | | a a a a a a a a a a a a a a a a a a a a
11+
... |
12+
LL | | a a a a a a a a a a a a a a a a a a a a
13+
LL | | );
14+
| |_____- in this macro invocation
15+
|
16+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "512"]` attribute to your crate (`min_recursion_limit_attr_wins`)
17+
= note: this error originates in the macro `count` (in Nightly builds, run with -Z macro-backtrace for more info)
18+
19+
error: aborting due to 1 previous error
20+
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//@ compile-flags: -Z min-recursion-limit=64
2+
#![recursion_limit = "256"]
3+
4+
macro_rules! count {
5+
() => {};
6+
($_:tt $($rest:tt)*) => { count!($($rest)*) }; //~ ERROR recursion limit reached while expanding `count!`
7+
}
8+
9+
fn main() {
10+
count!(
11+
a a a a a a a a a a a a a a a a a a a a
12+
a a a a a a a a a a a a a a a a a a a a
13+
a a a a a a a a a a a a a a a a a a a a
14+
a a a a a a a a a a a a a a a a a a a a
15+
a a a a a a a a a a a a a a a a a a a a
16+
a a a a a a a a a a a a a a a a a a a a
17+
a a a a a a a a a a a a a a a a a a a a
18+
a a a a a a a a a a a a a a a a a a a a
19+
a a a a a a a a a a a a a a a a a a a a
20+
a a a a a a a a a a a a a a a a a a a a
21+
); // 200
22+
23+
count!( // this one is erroring, because recursion is more than 256
24+
a a a a a a a a a a a a a a a a a a a a
25+
a a a a a a a a a a a a a a a a a a a a
26+
a a a a a a a a a a a a a a a a a a a a
27+
a a a a a a a a a a a a a a a a a a a a
28+
a a a a a a a a a a a a a a a a a a a a
29+
a a a a a a a a a a a a a a a a a a a a
30+
a a a a a a a a a a a a a a a a a a a a
31+
a a a a a a a a a a a a a a a a a a a a
32+
a a a a a a a a a a a a a a a a a a a a
33+
a a a a a a a a a a a a a a a a a a a a
34+
a a a a a a a a a a a a a a a a a a a a
35+
a a a a a a a a a a a a a a a a a a a a
36+
a a a a a a a a a a a a a a a a a a a a
37+
a a a a a a a a a a a a a a a a a a a a
38+
a a a a a a a a a a a a a a a a a a a a
39+
);
40+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: recursion limit reached while expanding `count!`
2+
--> $DIR/min-recursion-limit-cli-wins.rs:6:31
3+
|
4+
LL | ($_:tt $($rest:tt)*) => { count!($($rest)*) };
5+
| ^^^^^^^^^^^^^^^^^
6+
...
7+
LL | / count!(
8+
LL | | a a a a a a a a a a a a a a a a a a a a
9+
LL | | a a a a a a a a a a a a a a a a a a a a
10+
LL | | a a a a a a a a a a a a a a a a a a a a
11+
... |
12+
LL | | a a a a a a a a a a a a a a a a a a a a
13+
LL | | ); // maybe less than 300, but more than 256
14+
| |_____- in this macro invocation
15+
|
16+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "512"]` attribute to your crate (`min_recursion_limit_cli_wins`)
17+
= note: this error originates in the macro `count` (in Nightly builds, run with -Z macro-backtrace for more info)
18+
19+
error: aborting due to 1 previous error
20+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//@ compile-flags: -Z min-recursion-limit=201
2+
//@ check-pass
3+
4+
macro_rules! count {
5+
() => {};
6+
($_:tt $($rest:tt)*) => { count!($($rest)*) };
7+
}
8+
9+
fn main() {
10+
count!(
11+
a a a a a a a a a a a a a a a a a a a a
12+
a a a a a a a a a a a a a a a a a a a a
13+
a a a a a a a a a a a a a a a a a a a a
14+
a a a a a a a a a a a a a a a a a a a a
15+
a a a a a a a a a a a a a a a a a a a a
16+
a a a a a a a a a a a a a a a a a a a a
17+
a a a a a a a a a a a a a a a a a a a a
18+
a a a a a a a a a a a a a a a a a a a a
19+
a a a a a a a a a a a a a a a a a a a a
20+
a a a a a a a a a a a a a a a a a a a a
21+
); // 200
22+
}

0 commit comments

Comments
 (0)