Check whether an expression mentions a constant with the given address. Iterative (stack-based) — immune to stack overflow on deeply nested input.
(e: &KExpr<M>, addr: &Address)
| 1062 | /// |
| 1063 | /// Primitives are resolved by address only — `Primitives::from_addr_names` |
| 1064 | /// receives a closure that always returns `None`, so the |
| 1065 | /// `M::MField<Name>` slot ends up as `()` (always, in Anon mode). |
| 1066 | pub fn new_with_lazy_anon( |
| 1067 | env: &'a mut KEnv<super::mode::Anon>, |
| 1068 | anon_env: &'a IxonEnv, |
| 1069 | ) -> Self { |
| 1070 | if !env.has_prims() { |
| 1071 | let prims = Primitives::from_addr_names(|_addr| None); |
| 1072 | let _ = env.set_prims(prims); |
| 1073 | } |
| 1074 | let mut tc = Self::new(env); |
| 1075 | tc.lazy_anon = |
| 1076 | Some(LazyAnonIngress { anon_env, faulted_addrs: FxHashSet::default() }); |
| 1077 | tc |
| 1078 | } |
| 1079 | } |
| 1080 | |
| 1081 | // ----------------------------------------------------------------------- |
| 1082 | // Free-standing helpers |
| 1083 | // ----------------------------------------------------------------------- |
| 1084 | |
| 1085 | /// Check whether an expression mentions a constant with the given address. |
| 1086 | /// Iterative (stack-based) — immune to stack overflow on deeply nested input. |
| 1087 | pub fn expr_mentions_addr<M: KernelMode>(e: &KExpr<M>, addr: &Address) -> bool { |
| 1088 | let mut stack: Vec<&KExpr<M>> = vec![e]; |
| 1089 | while let Some(e) = stack.pop() { |
| 1090 | match e.data() { |
| 1091 | ExprData::Const(id, _, _) => { |
| 1092 | if id.addr == *addr { |
| 1093 | return true; |
| 1094 | } |
| 1095 | }, |
| 1096 | ExprData::App(f, a, _) => { |
| 1097 | stack.push(f); |
| 1098 | stack.push(a); |
| 1099 | }, |
| 1100 | ExprData::Lam(_, _, ty, body, _) | ExprData::All(_, _, ty, body, _) => { |
| 1101 | stack.push(ty); |
| 1102 | stack.push(body); |
| 1103 | }, |
no test coverage detected