1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//! Bounded-depth guard for the re-lowering walks.
//!
//! Both [`crate::extract_call_sites`] and
//! [`crate::extract_table_accesses`] descend through control-flow
//! statements (`IF` / `LOOP` / nested block) by *re-lowering* the
//! captured raw body text and recursing into the result. This is
//! sound only while the captured slice **strictly shrinks** on each
//! pass. On a malformed / parser-recovered unit (e.g. an `IF` whose
//! `END IF` is missing, so the text-scanner's `rfind("END IF")`
//! falls back to `text.len()` and the arm body re-captures almost
//! the whole input) the slice fails to shrink and the mutual
//! recursion is unbounded — a real stack-overflow / SIGABRT seen on
//! the bundled public fixture `corpus/synthetic/l1`.
//!
//! The guard caps recursion depth. Hitting the cap is **not**
//! silently swallowed: the walk records that it degraded a nested
//! body, the caller surfaces a typed
//! [`plsql_core::UnknownReason::AnalysisRecursionLimit`] +
//! `Diagnostic` with provenance, and the rest of the analysis
//! continues (R13: honest degradation, never crash, never hide
//! uncertainty — the anti-pattern is *not* to cap
//! silently).
/// Maximum re-lowering recursion depth. Real well-formed PL/SQL
/// nests far below this (the deepest private-estate control-flow body
/// re-lowered is < 30 levels); the cap exists only to make a
/// non-shrinking malformed slice terminate. Chosen high enough
/// that it never clips genuine extraction on well-formed input
/// and low enough that 128 stack frames of the walk cannot
/// overflow the default 8 MiB main-thread stack.
pub const MAX_RELOWER_DEPTH: usize = 128;
/// Outcome of a bounded re-lowering walk: whether the depth cap
/// was hit (so the caller can emit a typed degradation) and how
/// many distinct nested bodies were truncated.