pub(crate) mod bigint_promote;
pub(crate) mod context;
pub(crate) mod detection;
pub(crate) mod types;
mod policy;
pub(crate) mod ffi;
pub(crate) mod bindings;
pub(crate) mod tce;
pub(crate) mod marshal;
pub(crate) mod peephole;
pub(crate) mod hoist;
pub(crate) mod stmt;
pub(crate) mod expr;
pub(crate) mod program;
pub(crate) mod worklist;
pub(crate) mod affine_array;
pub(crate) mod narrow;
pub(crate) mod i64_map;
pub(crate) mod fast_div;
pub(crate) mod entry_guard;
pub(crate) mod strsearch;
pub(crate) mod slice;
pub use context::{RefinementContext, VariableCapabilities, empty_var_caps};
pub use detection::{collect_async_functions, collect_pipe_sender_params, collect_pipe_vars};
pub use program::{codegen_program, codegen_program_mapped, codegen_program_with_proven};
pub use slice::function_slice;
pub use marshal::codegen_native_tier_export;
pub use hoist::force_disable_for_test as force_disable_borrow_hoist_for_test;
pub use ffi::generate_c_header;
pub use bindings::{generate_python_bindings, generate_typescript_bindings};
pub use expr::{codegen_expr, codegen_assertion, codegen_term};
pub use stmt::codegen_stmt;
thread_local! {
static SEEDED_SELECT: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
}
pub(crate) fn seeded_select_enabled() -> bool {
SEEDED_SELECT.with(|c| c.get())
}
pub fn with_seeded_select<R>(f: impl FnOnce() -> R) -> R {
struct Restore(bool);
impl Drop for Restore {
fn drop(&mut self) {
SEEDED_SELECT.with(|c| c.set(self.0));
}
}
let _guard = SEEDED_SELECT.with(|c| {
let prev = c.get();
c.set(true);
Restore(prev)
});
f()
}
pub(crate) use ffi::{
CAbiClass, classify_type_for_c_abi, has_wasm_exports, has_c_exports, has_c_exports_with_text,
codegen_c_accessors, collect_c_export_ref_structs, collect_c_export_reference_types,
collect_c_export_value_type_structs, codegen_logos_runtime_preamble, mangle_type_for_c,
map_type_to_c_header, map_field_type_to_c,
};
pub(crate) use expr::{
codegen_expr_with_async, codegen_expr_boxed, codegen_expr_boxed_with_strings,
codegen_expr_boxed_with_types, codegen_interpolated_string, codegen_literal,
codegen_expr_with_async_and_strings, is_definitely_string_expr_with_vars,
is_definitely_string_expr, is_definitely_numeric_expr, collect_string_concat_operands,
};
pub(crate) use stmt::{get_root_identifier, is_copy_type, has_copy_element_type, has_copy_value_type};
pub(crate) use peephole::{
try_emit_for_range_pattern, try_emit_vec_fill_pattern, try_emit_swap_pattern,
try_emit_prefix_reverse,
try_emit_seq_copy_pattern, try_emit_seq_from_slice_pattern,
try_emit_bare_slice_push_pattern,
try_emit_vec_with_capacity_pattern, try_emit_merge_capacity_pattern,
try_emit_string_with_capacity_pattern,
try_emit_rotate_left_pattern,
try_emit_buffer_reuse_while,
body_mutates_collection, body_modifies_var, exprs_equal,
};
pub(crate) use types::is_recursive_field;
pub(crate) fn is_rust_keyword(name: &str) -> bool {
matches!(name,
"as" | "async" | "await" | "break" | "const" | "continue" | "crate" |
"dyn" | "else" | "enum" | "extern" | "false" | "fn" | "for" | "if" |
"impl" | "in" | "let" | "loop" | "match" | "mod" | "move" | "mut" |
"pub" | "ref" | "return" | "self" | "Self" | "static" | "struct" |
"super" | "trait" | "true" | "type" | "unsafe" | "use" | "where" |
"while" | "abstract" | "become" | "box" | "do" | "final" | "macro" |
"override" | "priv" | "try" | "typeof" | "unsized" | "virtual" | "yield"
)
}
pub(crate) fn escape_rust_ident(name: &str) -> String {
if is_rust_keyword(name) {
format!("r#{}", name)
} else {
name.to_string()
}
}
#[derive(Clone, Copy)]
pub(crate) enum FnRole {
Borrow,
MutBorrow,
ValueMutable,
}
pub(crate) fn encode_fn_roles(
borrow: &std::collections::HashSet<usize>,
mut_borrow: &std::collections::HashSet<usize>,
value_mutable: &std::collections::HashSet<usize>,
) -> String {
fn csv(s: &std::collections::HashSet<usize>) -> String {
let mut v: Vec<usize> = s.iter().copied().collect();
v.sort_unstable();
v.iter().map(|i| i.to_string()).collect::<Vec<_>>().join(",")
}
format!(
"fn_roles|b={}|m={}|v={}",
csv(borrow),
csv(mut_borrow),
csv(value_mutable)
)
}
pub(crate) fn fn_role_indices(
encoded: Option<&String>,
role: FnRole,
) -> std::collections::HashSet<usize> {
let empty = std::collections::HashSet::new();
let Some(rest) = encoded.and_then(|s| s.strip_prefix("fn_roles|")) else {
return empty;
};
let key = match role {
FnRole::Borrow => "b=",
FnRole::MutBorrow => "m=",
FnRole::ValueMutable => "v=",
};
for section in rest.split('|') {
if let Some(csv) = section.strip_prefix(key) {
return csv.split(',').filter_map(|i| i.parse().ok()).collect();
}
}
empty
}
pub(crate) fn is_fn_role_slot(ty: &str) -> bool {
ty.starts_with("fn_roles|")
}