| //@ revisions: become return |
| //@ [become] run-pass |
| #![allow(incomplete_features)] |
| #![feature(explicit_tail_calls)] |
| |
| // This is an identity function (`|x| x`), but implemented using recursion. |
| // Each step we increment accumulator and decrement the number. |
| // |
| // With normal calls this fails compilation because of the recursion limit, |
| // but with tail calls/`become` we don't grow the stack/spend recursion limit |
| // so this should compile. |
| const fn rec_id(n: u32) -> u32 { |
| const fn inner(acc: u32, n: u32) -> u32 { |
| match n { |
| 0 => acc, |
| #[cfg(r#become)] _ => become inner(acc + 1, n - 1), |
| #[cfg(r#return)] _ => return inner(acc + 1, n - 1), |
| //[return]~^ error: evaluation of constant value failed |
| } |
| } |
| |
| inner(0, n) |
| } |
| |
| // Some relatively big number that is higher than recursion limit |
| const ORIGINAL: u32 = 12345; |
| // Original number, but with identity function applied |
| // (this is the same, but requires execution of the recursion) |
| const ID_ED: u32 = rec_id(ORIGINAL); |
| // Assert to make absolutely sure the computation actually happens |
| const ASSERT: () = assert!(ORIGINAL == ID_ED); |
| |
| fn main() { |
| let _ = ASSERT; |
| } |