1use std::ffi::OsStr;
2
3pub const CODEGEN_STACK_BYTES: usize = 16 << 20;
5
6pub unsafe fn raise_codegen_stack_limit() {
14 if std::env::var_os("RUST_MIN_STACK").is_none() {
15 unsafe { std::env::set_var("RUST_MIN_STACK", CODEGEN_STACK_BYTES.to_string()) };
17 }
18}
19
20pub fn codegen_stack_is_sufficient() -> bool {
22 limit_is_sufficient(std::env::var_os("RUST_MIN_STACK").as_deref())
23}
24
25fn limit_is_sufficient(raw: Option<&OsStr>) -> bool {
29 raw.and_then(|v| v.to_str())
30 .and_then(|v| v.parse::<usize>().ok())
31 .is_some_and(|bytes| bytes >= CODEGEN_STACK_BYTES)
32}
33
34#[cfg(test)]
35mod tests {
36 use super::*;
37
38 #[test]
39 fn unset_is_insufficient() {
40 assert!(!limit_is_sufficient(None));
41 }
42
43 #[test]
44 fn zero_is_insufficient() {
45 assert!(!limit_is_sufficient(Some(OsStr::new("0"))));
46 }
47
48 #[test]
49 fn one_below_the_limit_is_insufficient() {
50 let value = (CODEGEN_STACK_BYTES - 1).to_string();
51 assert!(!limit_is_sufficient(Some(OsStr::new(&value))));
52 }
53
54 #[test]
55 fn exactly_the_limit_is_sufficient() {
56 let value = CODEGEN_STACK_BYTES.to_string();
57 assert!(limit_is_sufficient(Some(OsStr::new(&value))));
58 }
59
60 #[test]
61 fn above_the_limit_is_sufficient() {
62 let value = (CODEGEN_STACK_BYTES * 2).to_string();
63 assert!(limit_is_sufficient(Some(OsStr::new(&value))));
64 }
65
66 #[test]
67 fn surrounding_whitespace_is_insufficient() {
68 let value = format!(" {CODEGEN_STACK_BYTES} ");
69 assert!(!limit_is_sufficient(Some(OsStr::new(&value))));
70 }
71
72 #[test]
73 fn non_numeric_is_insufficient() {
74 assert!(!limit_is_sufficient(Some(OsStr::new("not-a-number"))));
75 }
76}