use std::collections::{HashMap, HashSet};
use std::fmt::Write;

use crate::analysis::registry::{FieldType, TypeDef, TypeRegistry};
use crate::analysis::types::RustNames;
use crate::ast::stmt::{BinaryOpKind, Expr, Literal, ReadSource, Stmt, TypeExpr};
use crate::intern::{Interner, Symbol};

use super::context::{RefinementContext, VariableCapabilities, emit_refinement_check, analyze_variable_capabilities};
use super::detection::{
    requires_async_stmt, calls_async_function, collect_mutable_vars, collect_mutable_vars_stmt,
    collect_crdt_register_fields, collect_boxed_fields, collect_expr_identifiers,
    collect_stmt_identifiers, expr_debug_prefix, expr_indexes_collection,
    get_root_identifier_for_mutability, is_copy_type_expr, is_hashable_type,
};
use super::expr::{
    codegen_expr, codegen_expr_with_async, codegen_expr_boxed,
    codegen_expr_boxed_with_strings, codegen_expr_boxed_with_types,
    codegen_interpolated_string, codegen_literal, codegen_assertion,
    codegen_expr_with_async_and_strings, is_definitely_string_expr_with_vars,
    is_definitely_string_expr, is_definitely_numeric_expr,
    collect_string_concat_operands,
};
use super::peephole::{
    try_emit_for_range_pattern, try_emit_vec_fill_pattern, try_emit_swap_pattern,
    try_emit_seq_copy_pattern, try_emit_seq_from_slice_pattern,
    try_emit_vec_with_capacity_pattern, try_emit_merge_capacity_pattern,
    try_emit_rotate_left_pattern, try_emit_buffer_reuse_while,
    try_emit_drain_tail_in_while,
    body_mutates_collection, body_modifies_var, exprs_equal, simplify_1based_index,
    collect_indexed_arrays,
};
use super::types::{
    codegen_type_expr, infer_rust_type_from_expr, infer_numeric_type,
    infer_variant_type_annotation,
};
use super::escape_rust_ident;

pub fn codegen_stmt<'a>(
    stmt: &Stmt<'a>,
    interner: &Interner,
    indent: usize,
    mutable_vars: &HashSet<Symbol>,
    ctx: &mut RefinementContext<'a>,
    lww_fields: &HashSet<(String, String)>,
    mv_fields: &HashSet<(String, String)>,  // Phase 49b: MVRegister fields (no timestamp)
    synced_vars: &mut HashSet<Symbol>,  // Phase 52: Track synced variables
    var_caps: &HashMap<Symbol, VariableCapabilities>,  // Phase 56: Mount+Sync detection
    async_functions: &HashSet<Symbol>,  // Phase 54: Functions that are async
    pipe_vars: &HashSet<Symbol>,  // Phase 54: Pipe declarations (have _tx/_rx suffixes)
    boxed_fields: &HashSet<(String, String, String)>,  // Phase 102: Recursive enum fields
    registry: &TypeRegistry,  // Phase 103: For type annotations on polymorphic enums
    type_env: &crate::analysis::types::TypeEnv,
) -> String {
    let indent_str = "    ".repeat(indent);
    let mut output = String::new();
    let names = RustNames::new(interner);

    // OPT-1C: Take liveness snapshot before any recursion.
    // None = no liveness info → conservative clone.
    // Recursive calls (If/While/etc. bodies) see None → conservative clone.
    let live_vars_after: Option<HashSet<Symbol>> = ctx.take_live_vars_after();

    match stmt {
        Stmt::Let { var, ty, value, mutable } => {
            let var_name = names.ident(*var);

            // Register collection type for direct indexing optimization.
            // Check explicit type annotation first, then infer from Expr::New.
            if let Some(TypeExpr::Generic { base, params }) = ty {
                let base_name = interner.resolve(*base);
                match base_name {
                    "Seq" | "List" | "Vec" => {
                        let rust_type = if !params.is_empty() {
                            format!("LogosSeq<{}>", codegen_type_expr(&params[0], interner))
                        } else {
                            "LogosSeq<()>".to_string()
                        };
                        ctx.register_variable_type(*var, rust_type);
                    }
                    "Map" | "HashMap" => {
                        let rust_type = if params.len() >= 2 {
                            format!("LogosMap<{}, {}>", codegen_type_expr(&params[0], interner), codegen_type_expr(&params[1], interner))
                        } else {
                            "LogosMap<String, String>".to_string()
                        };
                        ctx.register_variable_type(*var, rust_type);
                    }
                    _ => {}
                }
            } else if let Expr::New { type_name, type_args, .. } = value {
                let type_str = interner.resolve(*type_name);
                match type_str {
                    "Seq" | "List" | "Vec" => {
                        let rust_type = if !type_args.is_empty() {
                            format!("LogosSeq<{}>", codegen_type_expr(&type_args[0], interner))
                        } else {
                            "LogosSeq<()>".to_string()
                        };
                        ctx.register_variable_type(*var, rust_type);
                    }
                    "Map" | "HashMap" => {
                        let rust_type = if type_args.len() >= 2 {
                            format!("LogosMap<{}, {}>", codegen_type_expr(&type_args[0], interner), codegen_type_expr(&type_args[1], interner))
                        } else {
                            "LogosMap<String, String>".to_string()
                        };
                        ctx.register_variable_type(*var, rust_type);
                    }
                    _ => {}
                }
            } else if let Expr::List(items) = value {
                // Infer element type from first literal in the list for Copy elimination
                let elem_type = items.first()
                    .map(|e| infer_rust_type_from_expr(e, interner))
                    .unwrap_or_else(|| "_".to_string());
                ctx.register_variable_type(*var, format!("LogosSeq<{}>", elem_type));
            } else if let Expr::Identifier(src_sym) = value {
                // Propagate type from source variable: `Let result be arr` inherits arr's type.
                // For borrow params (&[T]), the copy becomes Vec<T> (owned).
                if let Some(src_type) = ctx.get_variable_types().get(src_sym).cloned() {
                    if src_type.starts_with("&[") {
                        // Propagate borrow type — rebinding the slice, not copying
                        ctx.register_variable_type(*var, src_type);
                    } else if src_type.starts_with("&mut [") {
                        // Mutable borrow param consumed into alias → propagate &mut [T]
                        // so the alias continues to be treated as the in-place mutable borrow.
                        ctx.register_variable_type(*var, src_type);
                    } else if !src_type.starts_with("fn_borrow:") && !src_type.starts_with("fn_mut_borrow:") {
                        ctx.register_variable_type(*var, src_type);
                    }
                }
            } else if let Expr::Copy { expr: inner } = value {
                // `Copy of items ... of arr` or `Copy of arr` produces same collection type
                let src_sym = match inner {
                    Expr::Slice { collection, .. } => {
                        if let Expr::Identifier(s) = collection { Some(*s) } else { None }
                    }
                    Expr::Identifier(s) => Some(*s),
                    _ => None,
                };
                if let Some(s) = src_sym {
                    if let Some(src_type) = ctx.get_variable_types().get(&s).cloned() {
                        if src_type.starts_with("LogosSeq") || src_type.starts_with("Vec") || src_type.starts_with("&[") {
                            let elem = if src_type.starts_with("LogosSeq<") {
                                src_type.strip_prefix("LogosSeq<").and_then(|t| t.strip_suffix('>')).unwrap_or("_")
                            } else if src_type.starts_with("Vec<") {
                                src_type.strip_prefix("Vec<").and_then(|t| t.strip_suffix('>')).unwrap_or("_")
                            } else {
                                src_type.strip_prefix("&[").and_then(|t| t.strip_suffix(']')).unwrap_or("_")
                            };
                            ctx.register_variable_type(*var, format!("LogosSeq<{}>", elem));
                        } else if src_type.starts_with("LogosMap") {
                            ctx.register_variable_type(*var, src_type);
                        }
                    }
                }
            }

            // Infer result type from function call return types
            if !ctx.get_variable_types().contains_key(var) {
                if let Expr::Call { function, .. } = value {
                    if let Some(rt) = ctx.get_fn_return(function).cloned() {
                        ctx.register_variable_type(*var, rt);
                    }
                }
            }

            // Register scalar types for mixed Float*Int arithmetic coercion
            if !ctx.get_variable_types().contains_key(var) {
                let inferred = infer_rust_type_from_expr(value, interner);
                if inferred != "_" {
                    ctx.register_variable_type(*var, inferred);
                } else {
                    // Try deeper numeric type inference for expressions like `4.0 * pi * pi`
                    let numeric = infer_numeric_type(value, interner, ctx.get_variable_types());
                    if numeric != "unknown" {
                        ctx.register_variable_type(*var, numeric.to_string());
                    }
                }
            }

            // OPT: Single-char text variable → u8 byte.
            // If this variable is pre-registered as __single_char_u8, emit u8 instead of String.
            let is_single_char_u8 = ctx.get_variable_types().get(var)
                .map_or(false, |t| t == "__single_char_u8");

            if is_single_char_u8 {
                if let Expr::Literal(Literal::Text(sym)) = value {
                    let text = interner.resolve(*sym);
                    if text.len() == 1 {
                        let ch = text.as_bytes()[0];
                        let is_mutable = *mutable || mutable_vars.contains(var);
                        if is_mutable {
                            writeln!(output, "{}let mut {}: u8 = b'{}';", indent_str, var_name, ch as char).unwrap();
                        } else {
                            writeln!(output, "{}let {}: u8 = b'{}';", indent_str, var_name, ch as char).unwrap();
                        }
                        // Don't register as string var — it's a u8 now
                        return output;
                    }
                }
            }

            // Materialize Expr::Slice on LogosSeq as Vec<T> to avoid dangling
            // &[T] borrows from temporary Ref guards. Stored as Vec (not LogosSeq)
            // so that downstream `copy of` can wrap with LogosSeq::from_vec()
            // for zero-copy ownership transfer instead of deep_clone.
            if let Expr::Slice { collection, start, end } = value {
                if let Expr::Identifier(coll_sym) = collection {
                    if let Some(coll_type) = ctx.get_variable_types().get(coll_sym).cloned() {
                        if coll_type.starts_with("LogosSeq<") {
                            let elem_type = coll_type.strip_prefix("LogosSeq<")
                                .and_then(|t| t.strip_suffix('>'))
                                .unwrap_or("_");
                            let coll_name = names.ident(*coll_sym);
                            let start_str = codegen_expr_boxed_with_types(
                                start, interner, synced_vars, boxed_fields, registry, async_functions,
                                ctx.get_string_vars(), ctx.get_variable_types()
                            );
                            let end_str = codegen_expr_boxed_with_types(
                                end, interner, synced_vars, boxed_fields, registry, async_functions,
                                ctx.get_string_vars(), ctx.get_variable_types()
                            );
                            let is_mutable = *mutable || mutable_vars.contains(var);
                            let mutk = if is_mutable { "mut " } else { "" };
                            writeln!(output, "{}let {}{}: Vec<{}> = {}.borrow()[({} - 1) as usize..{} as usize].to_vec();",
                                indent_str, mutk, var_name, elem_type, coll_name, start_str, end_str).unwrap();
                            // Register as Vec<T> — indexing works directly, and `copy of`
                            // wraps with LogosSeq::from_vec(x.clone()) for one-copy semantics.
                            ctx.register_variable_type(*var, format!("Vec<{}>", elem_type));
                            if is_definitely_string_expr_with_vars(value, ctx.get_string_vars()) {
                                ctx.register_string_var(*var);
                            }
                            return output;
                        } else if coll_type.starts_with("&[") {
                            let elem_type = coll_type.strip_prefix("&[")
                                .and_then(|t| t.strip_suffix(']'))
                                .unwrap_or("_");
                            let coll_name = names.ident(*coll_sym);
                            let start_str = codegen_expr_boxed_with_types(
                                start, interner, synced_vars, boxed_fields, registry, async_functions,
                                ctx.get_string_vars(), ctx.get_variable_types()
                            );
                            let end_str = codegen_expr_boxed_with_types(
                                end, interner, synced_vars, boxed_fields, registry, async_functions,
                                ctx.get_string_vars(), ctx.get_variable_types()
                            );
                            let is_mutable = *mutable || mutable_vars.contains(var);
                            let mutk = if is_mutable { "mut " } else { "" };
                            // Direct slice of borrow param — no .borrow() needed
                            writeln!(output, "{}let {}{}: Vec<{}> = {}[({} - 1) as usize..{} as usize].to_vec();",
                                indent_str, mutk, var_name, elem_type, coll_name, start_str, end_str).unwrap();
                            ctx.register_variable_type(*var, format!("Vec<{}>", elem_type));
                            if is_definitely_string_expr_with_vars(value, ctx.get_string_vars()) {
                                ctx.register_string_var(*var);
                            }
                            return output;
                        }
                    }
                }
            }

            // Phase 54+: Use codegen_expr_boxed with string+type tracking for proper codegen
            let mut value_str = codegen_expr_boxed_with_types(
                value, interner, synced_vars, boxed_fields, registry, async_functions,
                ctx.get_string_vars(), ctx.get_variable_types()
            );

            // Grand Challenge: Variable is mutable if explicitly marked OR if it's a Set target
            let is_mutable = *mutable || mutable_vars.contains(var);

            // Reference semantics: clone LogosSeq/LogosMap on assignment to share the Rc.
            // Borrow param (&[T]) assigned to mutable local → convert to owned.
            if let Expr::Identifier(src_sym) = value {
                if let Some(src_type) = ctx.get_variable_types().get(src_sym) {
                    if src_type.starts_with("LogosSeq") || src_type.starts_with("LogosMap") {
                        value_str = format!("{}.clone()", value_str);
                    } else if is_mutable && src_type.starts_with("&[") {
                        value_str = format!("{}.to_vec()", value_str);
                    }
                }
            }

            // Phase 103: Get explicit type annotation or infer for multi-param generic enums
            let type_annotation = ty.map(|t| codegen_type_expr(t, interner))
                .or_else(|| infer_variant_type_annotation(value, registry, interner));

            match (is_mutable, type_annotation) {
                (true, Some(t)) => writeln!(output, "{}let mut {}: {} = {};", indent_str, var_name, t, value_str).unwrap(),
                (true, None) => writeln!(output, "{}let mut {} = {};", indent_str, var_name, value_str).unwrap(),
                (false, Some(t)) => writeln!(output, "{}let {}: {} = {};", indent_str, var_name, t, value_str).unwrap(),
                (false, None) => writeln!(output, "{}let {} = {};", indent_str, var_name, value_str).unwrap(),
            }

            // Track string variables for proper concatenation in subsequent expressions
            if is_definitely_string_expr_with_vars(value, ctx.get_string_vars()) {
                ctx.register_string_var(*var);
            }

            // Phase 43C: Handle refinement type
            if let Some(TypeExpr::Refinement { base: _, var: bound_var, predicate }) = ty {
                emit_refinement_check(&var_name, *bound_var, predicate, interner, &indent_str, &mut output);
                ctx.register(*var, *bound_var, predicate);
            }
        }

        Stmt::Set { target, value } => {
            let target_name = names.ident(*target);

            // OPT: Single-char u8 variable → emit byte literal assignment.
            let is_target_single_char_u8 = ctx.get_variable_types().get(target)
                .map_or(false, |t| t == "__single_char_u8");
            if is_target_single_char_u8 {
                if let Expr::Literal(Literal::Text(sym)) = value {
                    let text = interner.resolve(*sym);
                    if text.len() == 1 {
                        let ch = text.as_bytes()[0];
                        writeln!(output, "{}{} = b'{}';", indent_str, target_name, ch as char).unwrap();
                        return output;
                    }
                }
            }

            let string_vars = ctx.get_string_vars();
            let var_types = ctx.get_variable_types();

            // Optimization: detect self-append pattern (result = result + x + y)
            // and emit write!(result, "{}{}", x, y) instead of result = format!(...).
            // This is O(n) amortized (in-place append) vs O(n²) (full copy each iteration).
            let used_write = if ctx.is_string_var(*target)
                && is_definitely_string_expr_with_vars(value, string_vars)
            {
                let mut operands = Vec::new();
                collect_string_concat_operands(value, string_vars, &mut operands);

                // Need at least 2 operands, leftmost must be the target variable
                if operands.len() >= 2 && matches!(operands[0], Expr::Identifier(sym) if *sym == *target) {
                    // Check no other operand references target (would cause borrow conflict)
                    let tail = &operands[1..];
                    let mut tail_ids = HashSet::new();
                    for op in tail {
                        collect_expr_identifiers(op, &mut tail_ids);
                    }

                    if !tail_ids.contains(target) {
                        if tail.len() == 1 {
                            // Single operand: use push/push_str for zero-format-overhead append
                            let operand = tail[0];
                            if let Expr::Literal(Literal::Text(sym)) = operand {
                                let text = interner.resolve(*sym);
                                if text.len() == 1 {
                                    let ch = text.chars().next().unwrap();
                                    writeln!(output, "{}{}.push('{}');",
                                        indent_str, target_name, ch).unwrap();
                                } else {
                                    writeln!(output, "{}{}.push_str(\"{}\");",
                                        indent_str, target_name, text).unwrap();
                                }
                            } else if let Expr::Identifier(sym) = operand {
                                if var_types.get(sym).map_or(false, |t| t == "__single_char_u8") {
                                    // OPT: u8 single-char var → push(ch as char)
                                    let val_str = codegen_expr_boxed_with_types(
                                        operand, interner, synced_vars, boxed_fields, registry, async_functions,
                                        string_vars, var_types
                                    );
                                    writeln!(output, "{}{}.push({} as char);",
                                        indent_str, target_name, val_str).unwrap();
                                } else if string_vars.contains(sym) {
                                    let val_str = codegen_expr_boxed_with_types(
                                        operand, interner, synced_vars, boxed_fields, registry, async_functions,
                                        string_vars, var_types
                                    );
                                    writeln!(output, "{}{}.push_str(&{});",
                                        indent_str, target_name, val_str).unwrap();
                                } else {
                                    // Non-string single operand: use write!
                                    let val_str = codegen_expr_boxed_with_types(
                                        operand, interner, synced_vars, boxed_fields, registry, async_functions,
                                        string_vars, var_types
                                    );
                                    writeln!(output, "{}write!({}, \"{{}}\", {}).unwrap();",
                                        indent_str, target_name, val_str).unwrap();
                                }
                            } else {
                                // Non-string single operand: use write!
                                let val_str = codegen_expr_boxed_with_types(
                                    operand, interner, synced_vars, boxed_fields, registry, async_functions,
                                    string_vars, var_types
                                );
                                writeln!(output, "{}write!({}, \"{{}}\", {}).unwrap();",
                                    indent_str, target_name, val_str).unwrap();
                            }
                        } else {
                            // Multiple operands: use write!() with format string
                            let placeholders: String = tail.iter().map(|_| "{}").collect::<Vec<_>>().join("");
                            let values: Vec<String> = tail.iter().map(|e| {
                                if let Expr::Literal(Literal::Text(sym)) = e {
                                    format!("\"{}\"", interner.resolve(*sym))
                                } else {
                                    codegen_expr_boxed_with_types(
                                        e, interner, synced_vars, boxed_fields, registry, async_functions,
                                        string_vars, var_types
                                    )
                                }
                            }).collect();
                            writeln!(output, "{}write!({}, \"{}\", {}).unwrap();",
                                indent_str, target_name, placeholders, values.join(", ")).unwrap();
                        }
                        true
                    } else {
                        false
                    }
                } else {
                    false
                }
            } else {
                false
            };

            if !used_write {
                // &mut borrow call-site transformation:
                // `Set x to f(x, ...)` where f has fn_mut_borrow at the target position
                // → `f(&mut x, ...)` (no assignment, mutation is in-place)
                let mut used_mut_borrow = false;
                if let Expr::Call { function, args } = value {
                    let callee_mut_borrow_indices: HashSet<usize> = var_types.get(function)
                        .and_then(|t| t.strip_prefix("fn_mut_borrow:"))
                        .map(|s| s.split(',').filter_map(|idx| idx.parse().ok()).collect())
                        .unwrap_or_default();
                    if !callee_mut_borrow_indices.is_empty() {
                        // Check if target is at a mut_borrow position
                        let target_at_mut_borrow = args.iter().enumerate()
                            .any(|(i, a)| {
                                callee_mut_borrow_indices.contains(&i)
                                    && matches!(a, Expr::Identifier(sym) if *sym == *target)
                            });
                        if target_at_mut_borrow {
                            let callee_borrow_indices: HashSet<usize> = var_types.get(function)
                                .and_then(|t| t.strip_prefix("fn_borrow:"))
                                .map(|s| s.split(',').filter_map(|idx| idx.parse().ok()).collect())
                                .unwrap_or_default();
                            let func_name = names.ident(*function);
                            let args_str: Vec<String> = args.iter().enumerate()
                                .map(|(i, a)| {
                                    let s = codegen_expr_boxed_with_types(
                                        a, interner, synced_vars, boxed_fields, registry,
                                        async_functions, string_vars, var_types
                                    );
                                    if callee_mut_borrow_indices.contains(&i) {
                                        // Mut borrow param: pass &mut [T] reference
                                        if let Expr::Identifier(sym) = a {
                                            if let Some(ty) = var_types.get(sym) {
                                                let ty = ty.split("|__hl:").next().unwrap_or(ty.as_str());
                                                if ty.starts_with("&mut [") {
                                                    return s; // Already &mut slice
                                                }
                                                if ty.starts_with("LogosSeq") {
                                                    return format!("&mut *{}.borrow_mut()", s);
                                                }
                                            }
                                            // Unknown type — default to LogosSeq
                                            return format!("&mut *{}.borrow_mut()", s);
                                        }
                                        format!("&mut {}", s)
                                    } else if callee_borrow_indices.contains(&i) {
                                        if let Expr::Identifier(sym) = a {
                                            if let Some(ty) = var_types.get(sym) {
                                                let ty = ty.split("|__hl:").next().unwrap_or(ty.as_str());
                                                if ty.starts_with("&[") || ty.starts_with("&mut [") {
                                                    return s;
                                                }
                                                if ty.starts_with("Vec<") {
                                                    return format!("&{}", s);
                                                }
                                                if ty.starts_with("LogosSeq") {
                                                    return format!("&*{}.borrow()", s);
                                                }
                                            }
                                            // Unknown type — default to LogosSeq
                                            return format!("&*{}.borrow()", s);
                                        }
                                        format!("&*{}.borrow()", s)
                                    } else {
                                        s
                                    }
                                })
                                .collect();
                            let await_suffix = if async_functions.contains(function) { ".await" } else { "" };
                            writeln!(output, "{}{}({}){};", indent_str, func_name, args_str.join(", "), await_suffix).unwrap();
                            used_mut_borrow = true;
                        }
                    }
                }

                // OPT-1B: Last-use clone elimination for `Set x to f(x, ...)`.
                // When the target variable appears as a direct non-borrow argument
                // and doesn't appear in other arg sub-expressions, skip cloning it
                // since the old value is immediately overwritten by the result.
                let value_str = if used_mut_borrow {
                    String::new() // Already emitted above
                } else if let Expr::Call { function, args } = value {
                    let target_positions: Vec<usize> = args.iter().enumerate()
                        .filter(|(_, a)| matches!(a, Expr::Identifier(sym) if *sym == *target))
                        .map(|(i, _)| i)
                        .collect();

                    let mut other_ids = HashSet::new();
                    for (i, a) in args.iter().enumerate() {
                        if target_positions.contains(&i) { continue; }
                        collect_expr_identifiers(a, &mut other_ids);
                    }
                    let target_in_others = other_ids.contains(target);

                    let callee_borrow_indices: HashSet<usize> = var_types.get(function)
                        .and_then(|t| t.strip_prefix("fn_borrow:"))
                        .map(|s| s.split(',').filter_map(|idx| idx.parse().ok()).collect())
                        .unwrap_or_default();

                    let can_move = target_positions.len() == 1
                        && !callee_borrow_indices.contains(&target_positions[0])
                        && !target_in_others
                        && var_types.get(target).map_or(false, |t| !is_copy_type(t));

                    if can_move {
                        let func_name = names.ident(*function);
                        let move_pos = target_positions[0];
                        let args_str: Vec<String> = args.iter().enumerate()
                            .map(|(i, a)| {
                                let s = codegen_expr_boxed_with_types(
                                    a, interner, synced_vars, boxed_fields, registry,
                                    async_functions, string_vars, var_types
                                );
                                if callee_borrow_indices.contains(&i) {
                                    if let Expr::Identifier(sym) = a {
                                        if let Some(ty) = var_types.get(sym) {
                                            let ty = ty.split("|__hl:").next().unwrap_or(ty.as_str());
                                            if ty.starts_with("&[") || ty.starts_with("&mut [") {
                                                return s;
                                            }
                                            if ty.starts_with("Vec<") {
                                                return format!("&{}", s);
                                            }
                                            if ty.starts_with("LogosSeq") {
                                                if *sym == *target {
                                                    return format!("&*{}.clone().borrow()", s);
                                                }
                                                return format!("&*{}.borrow()", s);
                                            }
                                        }
                                        if *sym == *target {
                                            return format!("&*{}.clone().borrow()", s);
                                        }
                                        return format!("&*{}.borrow()", s);
                                    }
                                    format!("&*{}.borrow()", s)
                                } else if i == move_pos {
                                    s // Move: no .clone()
                                } else {
                                    if let Expr::Identifier(sym) = a {
                                        if let Some(ty) = var_types.get(sym) {
                                            if !is_copy_type(ty) {
                                                return format!("{}.clone()", s);
                                            }
                                        }
                                    }
                                    s
                                }
                            })
                            .collect();
                        if async_functions.contains(function) {
                            format!("{}({}).await", func_name, args_str.join(", "))
                        } else {
                            format!("{}({})", func_name, args_str.join(", "))
                        }
                    } else {
                        // OPT-1C: Cross-variable last-use move.
                        // Build the call manually so we can move args that are not live
                        // after this statement instead of cloning them.
                        //
                        // Safety conditions for moving arg at position i:
                        //   1. Liveness info is available (live_vars_after is Some)
                        //   2. The variable is NOT live after this statement
                        //   3. The variable does NOT appear in any other arg expression
                        //      (moving it first would invalidate a borrow in a later arg)
                        let func_name = names.ident(*function);
                        let args_str: Vec<String> = args.iter().enumerate()
                            .map(|(i, a)| {
                                let s = codegen_expr_boxed_with_types(
                                    a, interner, synced_vars, boxed_fields, registry,
                                    async_functions, string_vars, var_types
                                );
                                if callee_borrow_indices.contains(&i) {
                                    if let Expr::Identifier(sym) = a {
                                        if let Some(ty) = var_types.get(sym) {
                                            let ty = ty.split("|__hl:").next().unwrap_or(ty.as_str());
                                            if ty.starts_with("&[") || ty.starts_with("&mut [") {
                                                return s;
                                            }
                                            if ty.starts_with("Vec<") {
                                                return format!("&{}", s);
                                            }
                                            if ty.starts_with("LogosSeq") {
                                                if *sym == *target {
                                                    return format!("&*{}.clone().borrow()", s);
                                                }
                                                return format!("&*{}.borrow()", s);
                                            }
                                        }
                                        if *sym == *target {
                                            return format!("&*{}.clone().borrow()", s);
                                        }
                                        return format!("&*{}.borrow()", s);
                                    }
                                    format!("&*{}.borrow()", s)
                                } else if let Expr::Identifier(sym) = a {
                                    if let Some(ty) = var_types.get(sym) {
                                        if !is_copy_type(ty) {
                                            // Can move only when liveness says it's dead AND
                                            // the variable isn't referenced in any other arg.
                                            let can_move_opt1c = live_vars_after
                                                .as_ref()
                                                .map(|live| {
                                                    if live.contains(sym) {
                                                        return false;
                                                    }
                                                    // Check it doesn't appear in other args
                                                    let mut other_ids = HashSet::new();
                                                    for (j, other_a) in args.iter().enumerate() {
                                                        if j == i { continue; }
                                                        collect_expr_identifiers(other_a, &mut other_ids);
                                                    }
                                                    !other_ids.contains(sym)
                                                })
                                                .unwrap_or(false);
                                            if can_move_opt1c {
                                                return s; // Move: dead after this stmt, safe
                                            }
                                            return format!("{}.clone()", s);
                                        }
                                    }
                                    s
                                } else {
                                    s
                                }
                            })
                            .collect();
                        if async_functions.contains(function) {
                            format!("{}({}).await", func_name, args_str.join(", "))
                        } else {
                            format!("{}({})", func_name, args_str.join(", "))
                        }
                    }
                } else {
                    let mut vs = codegen_expr_boxed_with_types(
                        value, interner, synced_vars, boxed_fields, registry,
                        async_functions, string_vars, var_types
                    );
                    // Reference semantics: clone LogosSeq/LogosMap on assignment to share the Rc.
                    if let Expr::Identifier(src_sym) = value {
                        if let Some(src_type) = var_types.get(src_sym) {
                            if src_type.starts_with("LogosSeq") || src_type.starts_with("LogosMap") {
                                vs = format!("{}.clone()", vs);
                            }
                        }
                    }
                    vs
                };
                if !used_mut_borrow {
                    writeln!(output, "{}{} = {};", indent_str, target_name, value_str).unwrap();
                }
            }

            // Phase 43C: Check if this variable has a refinement constraint
            if let Some((bound_var, predicate)) = ctx.get_constraint(*target) {
                emit_refinement_check(&target_name, bound_var, predicate, interner, &indent_str, &mut output);
            }
        }

        Stmt::Call { function, args } => {
            let func_name = names.ident(*function);
            let variable_types = ctx.get_variable_types();
            // Check if callee has borrow params (encoded as "fn_borrow:0,1" in variable_types)
            let callee_borrow_indices: HashSet<usize> = variable_types.get(function)
                .and_then(|t| t.strip_prefix("fn_borrow:"))
                .map(|s| s.split(',').filter_map(|i| i.parse().ok()).collect())
                .unwrap_or_default();
            // Check if callee has mutable borrow params (encoded as "fn_mut_borrow:0,1")
            let callee_mut_borrow_indices: HashSet<usize> = variable_types.get(function)
                .and_then(|t| t.strip_prefix("fn_mut_borrow:"))
                .map(|s| s.split(',').filter_map(|i| i.parse().ok()).collect())
                .unwrap_or_default();
            let args_str: Vec<String> = args.iter().enumerate().map(|(i, a)| {
                let s = codegen_expr_with_async(a, interner, synced_vars, async_functions, variable_types);
                if callee_mut_borrow_indices.contains(&i) {
                    // Mut borrow param: pass &mut [T] reference
                    if let Expr::Identifier(sym) = a {
                        if let Some(ty) = variable_types.get(sym) {
                            let ty = ty.split("|__hl:").next().unwrap_or(ty.as_str());
                            if ty.starts_with("&mut [") {
                                return s; // Already &mut slice
                            }
                            if ty.starts_with("LogosSeq") {
                                return format!("&mut *{}.borrow_mut()", s);
                            }
                        }
                        // Unknown type — default to LogosSeq
                        return format!("&mut *{}.borrow_mut()", s);
                    }
                    format!("&mut {}", s)
                } else if callee_borrow_indices.contains(&i) {
                    // Borrow param: pass &[T] reference instead of moving
                    if let Expr::Identifier(sym) = a {
                        if let Some(ty) = variable_types.get(sym) {
                            let ty = ty.split("|__hl:").next().unwrap_or(ty.as_str());
                            if ty.starts_with("&[") || ty.starts_with("&mut [") {
                                return s; // Already a slice — pass through
                            }
                            if ty.starts_with("Vec<") {
                                return format!("&{}", s);
                            }
                            if ty.starts_with("LogosSeq") {
                                return format!("&*{}.borrow()", s);
                            }
                        }
                        // Unknown type — default to LogosSeq
                        return format!("&*{}.borrow()", s);
                    }
                    format!("&*{}.borrow()", s)
                } else {
                    // Regular param: clone non-Copy identifiers to avoid move-after-use.
                    // LogosSeq/LogosMap .clone() is O(1) Rc clone — exactly what we want
                    // for reference semantics.
                    if let Expr::Identifier(sym) = a {
                        if let Some(ty) = variable_types.get(sym) {
                            if !is_copy_type(ty) {
                                return format!("{}.clone()", s);
                            }
                        }
                    }
                    s
                }
            }).collect();
            // Add .await if calling an async function
            let await_suffix = if async_functions.contains(function) { ".await" } else { "" };
            writeln!(output, "{}{}({}){};", indent_str, func_name, args_str.join(", "), await_suffix).unwrap();
        }

        Stmt::If { cond, then_block, else_block } => {
            let cond_str = codegen_expr_with_async(cond, interner, synced_vars, async_functions, ctx.get_variable_types());
            writeln!(output, "{}if {} {{", indent_str, cond_str).unwrap();
            ctx.push_scope();
            {
                let block_refs: Vec<&Stmt> = then_block.iter().collect();
                let mut bi = 0;
                while bi < block_refs.len() {
                    if let Some((code, skip)) = try_emit_seq_from_slice_pattern(&block_refs, bi, interner, indent + 1, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env) {
                        output.push_str(&code);
                        bi += 1 + skip;
                        continue;
                    }
                    if let Some((code, skip)) = try_emit_seq_copy_pattern(&block_refs, bi, interner, indent + 1, ctx) {
                        output.push_str(&code);
                        bi += 1 + skip;
                        continue;
                    }
                    if let Some((code, skip)) = try_emit_rotate_left_pattern(&block_refs, bi, interner, indent + 1, ctx.get_variable_types()) {
                        output.push_str(&code);
                        bi += 1 + skip;
                        continue;
                    }
                    output.push_str(&codegen_stmt(block_refs[bi], interner, indent + 1, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env));
                    bi += 1;
                }
            }
            ctx.pop_scope();
            if let Some(else_stmts) = else_block {
                writeln!(output, "{}}} else {{", indent_str).unwrap();
                ctx.push_scope();
                {
                    let block_refs: Vec<&Stmt> = else_stmts.iter().collect();
                    let mut bi = 0;
                    while bi < block_refs.len() {
                        if let Some((code, skip)) = try_emit_seq_from_slice_pattern(&block_refs, bi, interner, indent + 1, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env) {
                            output.push_str(&code);
                            bi += 1 + skip;
                            continue;
                        }
                        if let Some((code, skip)) = try_emit_seq_copy_pattern(&block_refs, bi, interner, indent + 1, ctx) {
                            output.push_str(&code);
                            bi += 1 + skip;
                            continue;
                        }
                        if let Some((code, skip)) = try_emit_rotate_left_pattern(&block_refs, bi, interner, indent + 1, ctx.get_variable_types()) {
                            output.push_str(&code);
                            bi += 1 + skip;
                            continue;
                        }
                        output.push_str(&codegen_stmt(block_refs[bi], interner, indent + 1, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env));
                        bi += 1;
                    }
                }
                ctx.pop_scope();
            }
            writeln!(output, "{}}}", indent_str).unwrap();
        }

        Stmt::While { cond, body, decreasing: _ } => {
            // decreasing is compile-time only, ignored at runtime

            // OPT: Loop bounds hoisting.
            // Collect all `length of X` symbols from condition AND body where X is
            // not modified in the loop. Emit hoisted `let x_len = (x.len() as i64);`
            // bindings before the loop. Register a sentinel in variable_types so that
            // Expr::Length codegen emits the hoisted name directly (no string replacement).
            let mut all_length_syms_raw = extract_length_expr_syms(cond);
            collect_length_syms_from_stmts(body, &mut all_length_syms_raw);
            let mut seen = HashSet::new();
            let all_length_syms: Vec<Symbol> = all_length_syms_raw
                .into_iter()
                .filter(|s| seen.insert(*s))
                .collect();

            let mut hoisted_syms: Vec<(Symbol, Option<String>)> = Vec::new();
            for len_sym in &all_length_syms {
                if !body_mutates_collection(body, *len_sym) && !body_modifies_var(body, *len_sym) {
                    let name = interner.resolve(*len_sym);
                    let hoisted_name = format!("{}_len", name);
                    writeln!(output, "{}let {} = ({}.len() as i64);", indent_str, hoisted_name, name).unwrap();
                    let old_type = ctx.get_variable_types().get(len_sym).cloned();
                    // Append hoisted sentinel to existing type string. Expr::Length checks
                    // for |__hl: suffix to emit the hoisted name. All other type checks
                    // use starts_with() so the suffix doesn't interfere.
                    let new_type = match &old_type {
                        Some(existing) => format!("{}|__hl:{}", existing, hoisted_name),
                        None => format!("|__hl:{}", hoisted_name),
                    };
                    ctx.register_variable_type(*len_sym, new_type);
                    hoisted_syms.push((*len_sym, old_type));
                }
            }

            // OPT-9: Emit assert! hints for arrays indexed by the while-loop counter.
            // For `while counter <= bound:` or `while counter < bound:`, find arrays
            // indexed by counter in the body and emit assert!((bound as usize) <= arr.len()).
            // This helps LLVM elide bounds checks inside the loop.
            if let Expr::BinaryOp { op, left, right } = cond {
                let counter_and_bound: Option<(Symbol, &Expr)> = match op {
                    BinaryOpKind::LtEq | BinaryOpKind::Lt => {
                        if let Expr::Identifier(sym) = left {
                            Some((*sym, *right))
                        } else {
                            None
                        }
                    }
                    _ => None,
                };
                if let Some((counter_sym, bound_expr)) = counter_and_bound {
                    let indexed_arrays = collect_indexed_arrays(body, counter_sym);
                    let indexed_arrays: Vec<Symbol> = indexed_arrays.into_iter().filter(|arr_sym| {
                        match ctx.get_variable_types().get(arr_sym) {
                            Some(t) if t.contains("HashMap") => false,
                            _ => true,
                        }
                    }).collect();
                    for arr_sym in &indexed_arrays {
                        let arr_name = interner.resolve(*arr_sym);
                        let bound_str = codegen_expr_with_async(bound_expr, interner, synced_vars, async_functions, ctx.get_variable_types());
                        writeln!(output, "{}unsafe {{ std::hint::assert_unchecked(({} as usize) <= {}.len()); }}",
                            indent_str, bound_str, arr_name).unwrap();
                    }
                }
            }

            let cond_str = codegen_expr_with_async(cond, interner, synced_vars, async_functions, ctx.get_variable_types());
            writeln!(output, "{}while {} {{", indent_str, cond_str).unwrap();
            ctx.push_scope();

            // OPT-5: Extract sentinel context from while condition.
            // For `While counter < limit:`, detect `Set counter to limit` inside If blocks
            // as sentinel exits and replace with `break`.
            let sentinel_ctx: Option<(Symbol, &Expr)> = match cond {
                Expr::BinaryOp { op: BinaryOpKind::Lt, left, right } => {
                    if let Expr::Identifier(sym) = left {
                        Some((*sym, *right))
                    } else {
                        None
                    }
                }
                _ => None,
            };

            // Peephole: process body statements with peephole optimizations.
            let body_refs: Vec<&Stmt> = body.iter().collect();
            let mut bi = 0;
            while bi < body_refs.len() {
                if let Some((code, skip)) = try_emit_buffer_reuse_while(&body_refs, bi, interner, indent + 1, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env) {
                    output.push_str(&code);
                    bi += 1 + skip;
                    continue;
                }
                if let Some((code, skip)) = try_emit_seq_from_slice_pattern(&body_refs, bi, interner, indent + 1, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env) {
                    output.push_str(&code);
                    bi += 1 + skip;
                    continue;
                }
                if let Some((code, skip)) = try_emit_vec_fill_pattern(&body_refs, bi, interner, indent + 1, ctx) {
                    output.push_str(&code);
                    bi += 1 + skip;
                    continue;
                }
                if let Some((code, skip)) = try_emit_vec_with_capacity_pattern(&body_refs, bi, interner, indent + 1, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env) {
                    output.push_str(&code);
                    bi += 1 + skip;
                    continue;
                }
                if let Some((code, skip)) = try_emit_merge_capacity_pattern(&body_refs, bi, interner, indent + 1, ctx) {
                    output.push_str(&code);
                    bi += 1 + skip;
                    continue;
                }
                if let Some((code, skip)) = try_emit_for_range_pattern(&body_refs, bi, interner, indent + 1, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env) {
                    output.push_str(&code);
                    bi += 1 + skip;
                    continue;
                }
                if let Some((code, skip)) = try_emit_swap_pattern(&body_refs, bi, interner, indent + 1, ctx.get_variable_types()) {
                    output.push_str(&code);
                    bi += 1 + skip;
                    continue;
                }
                if let Some((code, skip)) = try_emit_seq_copy_pattern(&body_refs, bi, interner, indent + 1, ctx) {
                    output.push_str(&code);
                    bi += 1 + skip;
                    continue;
                }
                if let Some((code, skip)) = try_emit_rotate_left_pattern(&body_refs, bi, interner, indent + 1, ctx.get_variable_types()) {
                    output.push_str(&code);
                    bi += 1 + skip;
                    continue;
                }
                // Drain-tail optimization: If a branch in the while body is a
                // loop-invariant sequential drain (push-from-array + increment), emit
                // extend_from_slice + break instead of element-by-element push.
                if let Some(code) = try_emit_drain_tail_in_while(
                    body_refs[bi], cond, interner, indent + 1,
                    mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps,
                    async_functions, pipe_vars, boxed_fields, registry, type_env,
                ) {
                    output.push_str(&code);
                    bi += 1;
                    continue;
                }
                // OPT-5: Sentinel → break transformation.
                // If this statement is an If whose then_block ends with `Set counter to limit`,
                // emit break instead of the sentinel set.
                if let Some((counter_sym, limit_expr)) = &sentinel_ctx {
                    if let Some(code) = try_emit_sentinel_break(
                        body_refs[bi], *counter_sym, limit_expr, interner, indent + 1,
                        mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps,
                        async_functions, pipe_vars, boxed_fields, registry, type_env,
                    ) {
                        output.push_str(&code);
                        bi += 1;
                        continue;
                    }
                }
                output.push_str(&codegen_stmt(body_refs[bi], interner, indent + 1, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env));
                bi += 1;
            }
            ctx.pop_scope();

            // Restore original variable_types for hoisted symbols.
            // variable_types is a flat HashMap (not scoped), so push/pop_scope doesn't clean it.
            for (sym, old_type) in hoisted_syms {
                if let Some(old) = old_type {
                    ctx.register_variable_type(sym, old);
                } else {
                    ctx.get_variable_types_mut().remove(&sym);
                }
            }

            writeln!(output, "{}}}", indent_str).unwrap();
        }

        Stmt::Repeat { pattern, iterable, body } => {
            use crate::ast::stmt::Pattern;

            // Generate pattern string for Rust code
            let pattern_str = match pattern {
                Pattern::Identifier(sym) => interner.resolve(*sym).to_string(),
                Pattern::Tuple(syms) => {
                    let names = syms.iter()
                        .map(|s| interner.resolve(*s))
                        .collect::<Vec<_>>()
                        .join(", ");
                    format!("({})", names)
                }
            };

            let iter_str = codegen_expr_with_async(iterable, interner, synced_vars, async_functions, ctx.get_variable_types());

            // OPT-PAR: Automatic parallelization for commutative reduction patterns.
            // Detect: Repeat for x in coll: Set acc = acc + expr(x)
            // Emit: acc += coll.par_iter().copied().map(|x| expr).sum::<i64>()
            let par_emitted = if let Pattern::Identifier(var_sym) = pattern {
                if let Some(par_code) = try_emit_parallel_reduction(
                    *var_sym, &pattern_str, &iter_str, iterable, body,
                    interner, indent, ctx,
                    synced_vars, async_functions,
                ) {
                    output.push_str(&par_code);
                    true
                } else {
                    false
                }
            } else {
                false
            };

            if par_emitted {
                // Parallel code already emitted — skip normal loop codegen
            } else if body.iter().any(|s| {
                requires_async_stmt(s) || calls_async_function(s, async_functions)
            }) {
                // Use while-let with explicit iterator for async compatibility
                writeln!(output, "{}let mut __iter = ({}).into_iter();", indent_str, iter_str).unwrap();
                writeln!(output, "{}while let Some({}) = __iter.next() {{", indent_str, pattern_str).unwrap();
            } else {
                // Determine iteration strategy based on collection type
                let is_logos_seq = if let Expr::Identifier(coll_sym) = iterable {
                    ctx.get_variable_types().get(coll_sym)
                        .map(|s| s.split("|__hl:").next().unwrap_or(s.as_str()))
                        .map_or(false, |t| t.starts_with("LogosSeq"))
                } else {
                    false
                };

                if is_logos_seq {
                    // LogosSeq: snapshot the inner vec for iteration.
                    // .to_vec() returns an owned Vec<T> — safe to iterate while
                    // allowing mutations to the LogosSeq during/after the loop.
                    writeln!(output, "{}for {} in {}.to_vec() {{", indent_str, pattern_str, iter_str).unwrap();
                } else {
                // Optimization: for known Vec<T>/&[T] with Copy element type,
                // use .iter().copied() instead of .clone() to avoid copying the entire collection.
                // For slices, must use .iter() since .clone() on &[T] clones the reference, not the data.
                let (use_iter_copied, use_iter_cloned) = if let Expr::Identifier(coll_sym) = iterable {
                    if let Some(coll_type_raw) = ctx.get_variable_types().get(coll_sym) {
                        // Strip |__hl: hoisting suffix so strip_suffix(']') works correctly.
                        let coll_type = coll_type_raw.split("|__hl:").next().unwrap_or(coll_type_raw.as_str());
                        if coll_type.starts_with("&[") {
                            // Slice type: must use .iter() (can't move/clone a borrowed slice)
                            let elem = coll_type.strip_prefix("&[").and_then(|s| s.strip_suffix(']')).unwrap_or("_");
                            if is_copy_type(elem) {
                                (true, false)
                            } else {
                                (false, true)
                            }
                        } else if coll_type.starts_with("Vec") && has_copy_element_type(coll_type)
                            && !body_mutates_collection(body, *coll_sym)
                        {
                            (true, false)
                        } else if coll_type.starts_with("Vec")
                            && !body_mutates_collection(body, *coll_sym)
                        {
                            // Non-Copy element type, but body doesn't mutate the collection:
                            // use .iter().cloned() for lazy per-element cloning instead of
                            // .clone() which copies the entire collection upfront.
                            (false, true)
                        } else {
                            (false, false)
                        }
                    } else {
                        (false, false)
                    }
                } else {
                    (false, false)
                };

                if use_iter_copied {
                    writeln!(output, "{}for {} in {}.iter().copied() {{", indent_str, pattern_str, iter_str).unwrap();
                } else if use_iter_cloned {
                    writeln!(output, "{}for {} in {}.iter().cloned() {{", indent_str, pattern_str, iter_str).unwrap();
                } else {
                    // Clone the collection before iterating to avoid moving it.
                    // This allows the collection to be reused after the loop.
                    writeln!(output, "{}for {} in {}.clone() {{", indent_str, pattern_str, iter_str).unwrap();
                }
                }
            }
            if !par_emitted {
                ctx.push_scope();
                // Peephole: process body statements with swap, seq-copy, and rotate-left detection
                {
                    let body_refs: Vec<&Stmt> = body.iter().collect();
                    let mut bi = 0;
                    while bi < body_refs.len() {
                        if let Some((code, skip)) = try_emit_swap_pattern(&body_refs, bi, interner, indent + 1, ctx.get_variable_types()) {
                            output.push_str(&code);
                            bi += 1 + skip;
                            continue;
                        }
                        if let Some((code, skip)) = try_emit_seq_from_slice_pattern(&body_refs, bi, interner, indent + 1, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env) {
                            output.push_str(&code);
                            bi += 1 + skip;
                            continue;
                        }
                        if let Some((code, skip)) = try_emit_seq_copy_pattern(&body_refs, bi, interner, indent + 1, ctx) {
                            output.push_str(&code);
                            bi += 1 + skip;
                            continue;
                        }
                        if let Some((code, skip)) = try_emit_rotate_left_pattern(&body_refs, bi, interner, indent + 1, ctx.get_variable_types()) {
                            output.push_str(&code);
                            bi += 1 + skip;
                            continue;
                        }
                        output.push_str(&codegen_stmt(body_refs[bi], interner, indent + 1, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env));
                        bi += 1;
                    }
                }
                ctx.pop_scope();
                writeln!(output, "{}}}", indent_str).unwrap();
            }
        }

        Stmt::Return { value } => {
            if let Some(v) = value {
                let value_str = codegen_expr_boxed_with_types(v, interner, synced_vars, boxed_fields, registry, async_functions, ctx.get_string_vars(), ctx.get_variable_types());
                // If returning a borrowed slice param (or copy of one), wrap in LogosSeq
                let slice_sym = match v {
                    Expr::Identifier(sym) => Some(*sym),
                    Expr::Copy { expr: inner } => {
                        if let Expr::Identifier(sym) = inner { Some(*sym) } else { None }
                    }
                    _ => None,
                };
                let needs_to_vec = slice_sym
                    .and_then(|sym| ctx.get_variable_types().get(&sym))
                    .map(|t| t.starts_with("&["))
                    .unwrap_or(false);
                // If returning a &mut borrow param, the mutation was in-place — just return
                let is_mut_borrow_return = if let Expr::Identifier(sym) = v {
                    ctx.get_variable_types().get(sym)
                        .map(|t| t.starts_with("&mut ["))
                        .unwrap_or(false)
                } else {
                    false
                };
                if is_mut_borrow_return {
                    writeln!(output, "{}return;", indent_str).unwrap();
                } else if needs_to_vec {
                    writeln!(output, "{}return LogosSeq::from_vec({}.to_vec());", indent_str, value_str).unwrap();
                } else {
                    writeln!(output, "{}return {};", indent_str, value_str).unwrap();
                }
            } else {
                writeln!(output, "{}return;", indent_str).unwrap();
            }
        }

        Stmt::Break => {
            writeln!(output, "{}break;", indent_str).unwrap();
        }

        Stmt::Assert { proposition } => {
            let condition = codegen_assertion(proposition, interner);
            writeln!(output, "{}debug_assert!({});", indent_str, condition).unwrap();
        }

        // Phase 35: Trust with documented justification
        Stmt::Trust { proposition, justification } => {
            let reason = interner.resolve(*justification);
            // Strip quotes if present (string literals include their quotes)
            let reason_clean = reason.trim_matches('"');
            writeln!(output, "{}// TRUST: {}", indent_str, reason_clean).unwrap();
            let condition = codegen_assertion(proposition, interner);
            writeln!(output, "{}debug_assert!({});", indent_str, condition).unwrap();
        }

        Stmt::RuntimeAssert { condition } => {
            let cond_str = codegen_expr_with_async(condition, interner, synced_vars, async_functions, ctx.get_variable_types());
            writeln!(output, "{}debug_assert!({});", indent_str, cond_str).unwrap();
        }

        // Phase 50: Security Check - mandatory runtime guard (NEVER optimized out)
        Stmt::Check { subject, predicate, is_capability, object, source_text, span } => {
            let subj_name = interner.resolve(*subject);
            let pred_name = interner.resolve(*predicate).to_lowercase();

            let call = if *is_capability {
                let obj_sym = object.expect("capability must have object");
                let obj_word = interner.resolve(obj_sym);

                // Phase 50: Type-based resolution
                // "Check that user can publish the document" -> find variable of type Document
                // First try to find a variable whose type matches the object word
                let obj_name = ctx.find_variable_by_type(obj_word, interner)
                    .unwrap_or_else(|| obj_word.to_string());

                format!("{}.can_{}(&{})", subj_name, pred_name, obj_name)
            } else {
                format!("{}.is_{}()", subj_name, pred_name)
            };

            writeln!(output, "{}if !({}) {{", indent_str, call).unwrap();
            writeln!(output, "{}    logicaffeine_system::panic_with(\"Security Check Failed at line {}: {}\");",
                     indent_str, span.start, source_text).unwrap();
            writeln!(output, "{}}}", indent_str).unwrap();
        }

        // Phase 51: P2P Networking - Listen on network address
        Stmt::Listen { address } => {
            let addr_str = codegen_expr_with_async(address, interner, synced_vars, async_functions, ctx.get_variable_types());
            // Pass &str instead of String
            writeln!(output, "{}logicaffeine_system::network::listen(&{}).await.expect(\"Failed to listen\");",
                     indent_str, addr_str).unwrap();
        }

        // Phase 51: P2P Networking - Connect to remote peer
        Stmt::ConnectTo { address } => {
            let addr_str = codegen_expr_with_async(address, interner, synced_vars, async_functions, ctx.get_variable_types());
            // Pass &str instead of String
            writeln!(output, "{}logicaffeine_system::network::connect(&{}).await.expect(\"Failed to connect\");",
                     indent_str, addr_str).unwrap();
        }

        // Phase 51: P2P Networking - Create PeerAgent remote handle
        Stmt::LetPeerAgent { var, address } => {
            let var_name = interner.resolve(*var);
            let addr_str = codegen_expr_with_async(address, interner, synced_vars, async_functions, ctx.get_variable_types());
            // Pass &str instead of String
            writeln!(output, "{}let {} = logicaffeine_system::network::PeerAgent::new(&{}).expect(\"Invalid address\");",
                     indent_str, var_name, addr_str).unwrap();
        }

        // Phase 51: Sleep - supports Duration literals or milliseconds
        Stmt::Sleep { milliseconds } => {
            let expr_str = codegen_expr_with_async(milliseconds, interner, synced_vars, async_functions, ctx.get_variable_types());
            let inferred_type = infer_rust_type_from_expr(milliseconds, interner);

            if inferred_type == "std::time::Duration" {
                // Duration type: use directly (already a std::time::Duration)
                writeln!(output, "{}tokio::time::sleep({}).await;",
                         indent_str, expr_str).unwrap();
            } else {
                // Assume milliseconds (integer) - legacy behavior
                writeln!(output, "{}tokio::time::sleep(std::time::Duration::from_millis({} as u64)).await;",
                         indent_str, expr_str).unwrap();
            }
        }

        // Phase 52/56: Sync CRDT variable on topic
        Stmt::Sync { var, topic } => {
            let var_name = interner.resolve(*var);
            let topic_str = codegen_expr_with_async(topic, interner, synced_vars, async_functions, ctx.get_variable_types());

            // Phase 56: Check if this variable is also mounted
            if let Some(caps) = var_caps.get(var) {
                if caps.mounted {
                    // Both Mount and Sync: use Distributed<T>
                    // Mount statement will handle the Distributed::mount call
                    // Here we just track it as synced
                    synced_vars.insert(*var);
                    return output;  // Skip - Mount will emit Distributed<T>
                }
            }

            // Sync-only: use Synced<T>
            writeln!(
                output,
                "{}let {} = logicaffeine_system::crdt::Synced::new({}, &{}).await;",
                indent_str, var_name, var_name, topic_str
            ).unwrap();
            synced_vars.insert(*var);
        }

        // Phase 53/56: Mount persistent CRDT from journal
        Stmt::Mount { var, path } => {
            let var_name = interner.resolve(*var);
            let path_str = codegen_expr_with_async(path, interner, synced_vars, async_functions, ctx.get_variable_types());

            // Phase 56: Check if this variable is also synced
            if let Some(caps) = var_caps.get(var) {
                if caps.synced {
                    // Both Mount and Sync: use Distributed<T>
                    let topic_str = caps.sync_topic.as_ref()
                        .map(|s| s.as_str())
                        .unwrap_or("\"default\"");
                    writeln!(
                        output,
                        "{}let {} = logicaffeine_system::distributed::Distributed::mount(vfs.clone(), &{}, Some({}.to_string())).await.expect(\"Failed to mount\");",
                        indent_str, var_name, path_str, topic_str
                    ).unwrap();
                    synced_vars.insert(*var);
                    return output;
                }
            }

            // Mount-only: use Persistent<T>
            writeln!(
                output,
                "{}let {} = logicaffeine_system::storage::Persistent::mount(vfs.clone(), &{}).await.expect(\"Failed to mount\");",
                indent_str, var_name, path_str
            ).unwrap();
            synced_vars.insert(*var);
        }

        // =====================================================================
        // Phase 54: Go-like Concurrency Codegen
        // =====================================================================

        Stmt::LaunchTask { function, args } => {
            let fn_name = names.ident(*function);
            // Phase 54: When passing a pipe variable, pass the sender (_tx)
            let args_str: Vec<String> = args.iter()
                .map(|a| {
                    if let Expr::Identifier(sym) = a {
                        if pipe_vars.contains(sym) {
                            return format!("{}_tx.clone()", interner.resolve(*sym));
                        }
                    }
                    codegen_expr_with_async(a, interner, synced_vars, async_functions, ctx.get_variable_types())
                })
                .collect();
            // Phase 54: Add .await only if the function is async
            let await_suffix = if async_functions.contains(function) { ".await" } else { "" };
            writeln!(
                output,
                "{}tokio::spawn(async move {{ {}({}){await_suffix}; }});",
                indent_str, fn_name, args_str.join(", ")
            ).unwrap();
        }

        Stmt::LaunchTaskWithHandle { handle, function, args } => {
            let handle_name = interner.resolve(*handle);
            let fn_name = names.ident(*function);
            // Phase 54: When passing a pipe variable, pass the sender (_tx)
            let args_str: Vec<String> = args.iter()
                .map(|a| {
                    if let Expr::Identifier(sym) = a {
                        if pipe_vars.contains(sym) {
                            return format!("{}_tx.clone()", interner.resolve(*sym));
                        }
                    }
                    codegen_expr_with_async(a, interner, synced_vars, async_functions, ctx.get_variable_types())
                })
                .collect();
            // Phase 54: Add .await only if the function is async
            let await_suffix = if async_functions.contains(function) { ".await" } else { "" };
            writeln!(
                output,
                "{}let {} = tokio::spawn(async move {{ {}({}){await_suffix} }});",
                indent_str, handle_name, fn_name, args_str.join(", ")
            ).unwrap();
        }

        Stmt::CreatePipe { var, element_type, capacity } => {
            let var_name = interner.resolve(*var);
            let type_name = interner.resolve(*element_type);
            let cap = capacity.unwrap_or(32);
            // Map LOGOS types to Rust types
            let rust_type = match type_name {
                "Int" => "i64",
                "Nat" => "u64",
                "Text" => "String",
                "Bool" => "bool",
                _ => type_name,
            };
            writeln!(
                output,
                "{}let ({}_tx, mut {}_rx) = tokio::sync::mpsc::channel::<{}>({});",
                indent_str, var_name, var_name, rust_type, cap
            ).unwrap();
        }

        Stmt::SendPipe { value, pipe } => {
            let val_str = codegen_expr_boxed_with_types(value, interner, synced_vars, boxed_fields, registry, async_functions, ctx.get_string_vars(), ctx.get_variable_types());
            let pipe_str = codegen_expr_with_async(pipe, interner, synced_vars, async_functions, ctx.get_variable_types());
            // Phase 54: Check if pipe is a local declaration (has _tx suffix) or parameter (no suffix)
            let is_local_pipe = if let Expr::Identifier(sym) = pipe {
                pipe_vars.contains(sym)
            } else {
                false
            };
            if is_local_pipe {
                writeln!(
                    output,
                    "{}{}_tx.send({}).await.expect(\"pipe send failed\");",
                    indent_str, pipe_str, val_str
                ).unwrap();
            } else {
                writeln!(
                    output,
                    "{}{}.send({}).await.expect(\"pipe send failed\");",
                    indent_str, pipe_str, val_str
                ).unwrap();
            }
        }

        Stmt::ReceivePipe { var, pipe } => {
            let var_name = interner.resolve(*var);
            let pipe_str = codegen_expr_with_async(pipe, interner, synced_vars, async_functions, ctx.get_variable_types());
            // Phase 54: Check if pipe is a local declaration (has _rx suffix) or parameter (no suffix)
            let is_local_pipe = if let Expr::Identifier(sym) = pipe {
                pipe_vars.contains(sym)
            } else {
                false
            };
            if is_local_pipe {
                writeln!(
                    output,
                    "{}let {} = {}_rx.recv().await.expect(\"pipe closed\");",
                    indent_str, var_name, pipe_str
                ).unwrap();
            } else {
                writeln!(
                    output,
                    "{}let {} = {}.recv().await.expect(\"pipe closed\");",
                    indent_str, var_name, pipe_str
                ).unwrap();
            }
        }

        Stmt::TrySendPipe { value, pipe, result } => {
            let val_str = codegen_expr_boxed_with_types(value, interner, synced_vars, boxed_fields, registry, async_functions, ctx.get_string_vars(), ctx.get_variable_types());
            let pipe_str = codegen_expr_with_async(pipe, interner, synced_vars, async_functions, ctx.get_variable_types());
            // Phase 54: Check if pipe is a local declaration
            let is_local_pipe = if let Expr::Identifier(sym) = pipe {
                pipe_vars.contains(sym)
            } else {
                false
            };
            let suffix = if is_local_pipe { "_tx" } else { "" };
            if let Some(res) = result {
                let res_name = interner.resolve(*res);
                writeln!(
                    output,
                    "{}let {} = {}{}.try_send({}).is_ok();",
                    indent_str, res_name, pipe_str, suffix, val_str
                ).unwrap();
            } else {
                writeln!(
                    output,
                    "{}let _ = {}{}.try_send({});",
                    indent_str, pipe_str, suffix, val_str
                ).unwrap();
            }
        }

        Stmt::TryReceivePipe { var, pipe } => {
            let var_name = interner.resolve(*var);
            let pipe_str = codegen_expr_with_async(pipe, interner, synced_vars, async_functions, ctx.get_variable_types());
            // Phase 54: Check if pipe is a local declaration
            let is_local_pipe = if let Expr::Identifier(sym) = pipe {
                pipe_vars.contains(sym)
            } else {
                false
            };
            let suffix = if is_local_pipe { "_rx" } else { "" };
            writeln!(
                output,
                "{}let {} = {}{}.try_recv().ok();",
                indent_str, var_name, pipe_str, suffix
            ).unwrap();
        }

        Stmt::StopTask { handle } => {
            let handle_str = codegen_expr_with_async(handle, interner, synced_vars, async_functions, ctx.get_variable_types());
            writeln!(output, "{}{}.abort();", indent_str, handle_str).unwrap();
        }

        Stmt::Select { branches } => {
            use crate::ast::stmt::SelectBranch;

            writeln!(output, "{}tokio::select! {{", indent_str).unwrap();
            for branch in branches {
                match branch {
                    SelectBranch::Receive { var, pipe, body } => {
                        let var_name = interner.resolve(*var);
                        let pipe_str = codegen_expr_with_async(pipe, interner, synced_vars, async_functions, ctx.get_variable_types());
                        // Check if pipe is a local declaration (has _rx suffix) or a parameter (no suffix)
                        let is_local_pipe = if let Expr::Identifier(sym) = pipe {
                            pipe_vars.contains(sym)
                        } else {
                            false
                        };
                        let suffix = if is_local_pipe { "_rx" } else { "" };
                        writeln!(
                            output,
                            "{}    {} = {}{}.recv() => {{",
                            indent_str, var_name, pipe_str, suffix
                        ).unwrap();
                        writeln!(
                            output,
                            "{}        if let Some({}) = {} {{",
                            indent_str, var_name, var_name
                        ).unwrap();
                        for stmt in *body {
                            let stmt_code = codegen_stmt(stmt, interner, indent + 3, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env);
                            write!(output, "{}", stmt_code).unwrap();
                        }
                        writeln!(output, "{}        }}", indent_str).unwrap();
                        writeln!(output, "{}    }}", indent_str).unwrap();
                    }
                    SelectBranch::Timeout { milliseconds, body } => {
                        let ms_str = codegen_expr_with_async(milliseconds, interner, synced_vars, async_functions, ctx.get_variable_types());
                        // Convert seconds to milliseconds if the value looks like seconds
                        writeln!(
                            output,
                            "{}    _ = tokio::time::sleep(std::time::Duration::from_secs({} as u64)) => {{",
                            indent_str, ms_str
                        ).unwrap();
                        for stmt in *body {
                            let stmt_code = codegen_stmt(stmt, interner, indent + 2, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env);
                            write!(output, "{}", stmt_code).unwrap();
                        }
                        writeln!(output, "{}    }}", indent_str).unwrap();
                    }
                }
            }
            writeln!(output, "{}}}", indent_str).unwrap();
        }

        Stmt::Give { object, recipient } => {
            // Move semantics: pass ownership without borrowing
            let obj_str = codegen_expr_with_async(object, interner, synced_vars, async_functions, ctx.get_variable_types());
            let recv_str = codegen_expr_with_async(recipient, interner, synced_vars, async_functions, ctx.get_variable_types());
            writeln!(output, "{}{}({});", indent_str, recv_str, obj_str).unwrap();
        }

        Stmt::Show { object, recipient } => {
            // OPT: Show single-char u8 variable → println!("{}", ch as char)
            if let Expr::Identifier(sym) = object {
                if ctx.get_variable_types().get(sym).map_or(false, |t| t == "__single_char_u8") {
                    let var_name = names.ident(*sym);
                    writeln!(output, "{}println!(\"{{}}\", {} as char);", indent_str, var_name).unwrap();
                    return output;
                }
            }
            // Optimization: Show with InterpolatedString → println! directly
            if let Expr::InterpolatedString(parts) = object {
                let recv_name = if let Expr::Identifier(sym) = recipient {
                    interner.resolve(*sym).to_string()
                } else {
                    String::new()
                };
                if recv_name == "show" {
                    // Emit println! directly — no intermediate String allocation
                    let mut fmt_str = String::new();
                    let mut args = Vec::new();
                    for part in parts {
                        match part {
                            crate::ast::stmt::StringPart::Literal(sym) => {
                                let text = interner.resolve(*sym);
                                for ch in text.chars() {
                                    match ch {
                                        '{' => fmt_str.push_str("{{"),
                                        '}' => fmt_str.push_str("}}"),
                                        '\n' => fmt_str.push_str("\\n"),
                                        '\t' => fmt_str.push_str("\\t"),
                                        '\r' => fmt_str.push_str("\\r"),
                                        _ => fmt_str.push(ch),
                                    }
                                }
                            }
                            crate::ast::stmt::StringPart::Expr { value, format_spec, debug } => {
                                if *debug {
                                    let debug_prefix = expr_debug_prefix(value, interner);
                                    for ch in debug_prefix.chars() {
                                        match ch {
                                            '{' => fmt_str.push_str("{{"),
                                            '}' => fmt_str.push_str("}}"),
                                            _ => fmt_str.push(ch),
                                        }
                                    }
                                    fmt_str.push('=');
                                }
                                let needs_float_cast = if let Some(spec) = format_spec {
                                    let spec_str = interner.resolve(*spec);
                                    if spec_str == "$" {
                                        fmt_str.push('$');
                                        fmt_str.push_str("{:.2}");
                                        true
                                    } else if spec_str.starts_with('.') {
                                        fmt_str.push_str(&format!("{{:{}}}", spec_str));
                                        true
                                    } else {
                                        fmt_str.push_str(&format!("{{:{}}}", spec_str));
                                        false
                                    }
                                } else {
                                    fmt_str.push_str("{}");
                                    false
                                };
                                let arg_str = codegen_expr_with_async_and_strings(value, interner, synced_vars, async_functions, ctx.get_string_vars(), ctx.get_variable_types());
                                if needs_float_cast {
                                    args.push(format!("{} as f64", arg_str));
                                } else {
                                    args.push(arg_str);
                                }
                            }
                        }
                    }
                    writeln!(output, "{}println!(\"{}\"{});", indent_str, fmt_str,
                        args.iter().map(|a| format!(", {}", a)).collect::<String>()).unwrap();
                } else {
                    let obj_str = codegen_expr_with_async_and_strings(object, interner, synced_vars, async_functions, ctx.get_string_vars(), ctx.get_variable_types());
                    let recv_str = codegen_expr_with_async(recipient, interner, synced_vars, async_functions, ctx.get_variable_types());
                    writeln!(output, "{}{}(&{});", indent_str, recv_str, obj_str).unwrap();
                }
            } else {
                // Borrow semantics: pass immutable reference
                // Use string_vars for proper concatenation of string variables
                let obj_str = codegen_expr_with_async_and_strings(object, interner, synced_vars, async_functions, ctx.get_string_vars(), ctx.get_variable_types());
                let recv_str = codegen_expr_with_async(recipient, interner, synced_vars, async_functions, ctx.get_variable_types());
                writeln!(output, "{}{}(&{});", indent_str, recv_str, obj_str).unwrap();
            }
        }

        Stmt::SetField { object, field, value } => {
            let obj_str = codegen_expr_with_async(object, interner, synced_vars, async_functions, ctx.get_variable_types());
            let field_name = interner.resolve(*field);
            let value_str = codegen_expr_boxed_with_types(value, interner, synced_vars, boxed_fields, registry, async_functions, ctx.get_string_vars(), ctx.get_variable_types());

            // Phase 49: Check if this field is an LWWRegister or MVRegister
            // LWW needs .set(value, timestamp), MV needs .set(value)
            let is_lww = lww_fields.iter().any(|(_, f)| f == field_name);
            let is_mv = mv_fields.iter().any(|(_, f)| f == field_name);
            if is_lww {
                // LWWRegister needs a timestamp - use current system time in microseconds
                writeln!(output, "{}{}.{}.set({}, std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_micros() as u64);", indent_str, obj_str, field_name, value_str).unwrap();
            } else if is_mv {
                // MVRegister just needs the value
                writeln!(output, "{}{}.{}.set({});", indent_str, obj_str, field_name, value_str).unwrap();
            } else {
                writeln!(output, "{}{}.{} = {};", indent_str, obj_str, field_name, value_str).unwrap();
            }
        }

        Stmt::StructDef { .. } => {
            // Struct definitions are handled in codegen_program, not here
        }

        Stmt::FunctionDef { .. } => {
            // Function definitions are handled in codegen_program, not here
        }

        Stmt::Inspect { target, arms, .. } => {
            let target_str = codegen_expr_with_async(target, interner, synced_vars, async_functions, ctx.get_variable_types());

            writeln!(output, "{}match {} {{", indent_str, target_str).unwrap();

            for arm in arms {
                // Phase 102: Track which bindings come from boxed fields for inner Inspects
                // Use NAMES (strings) not symbols, because parser may create different symbols
                // for the same identifier in different syntactic positions.
                // Must be per-arm so bindings from other arms don't leak into this arm's scope.
                let mut inner_boxed_binding_names: HashSet<String> = HashSet::new();
                if let Some(variant) = arm.variant {
                    let variant_name = interner.resolve(variant);
                    // Get the enum name from the arm, or fallback to just variant name
                    let enum_name_str = arm.enum_name.map(|e| interner.resolve(e));
                    let enum_prefix = enum_name_str
                        .map(|e| format!("{}::", e))
                        .unwrap_or_default();

                    if arm.bindings.is_empty() {
                        // Unit variant pattern
                        writeln!(output, "{}    {}{} => {{", indent_str, enum_prefix, variant_name).unwrap();
                    } else {
                        // Pattern with bindings
                        // Phase 102: Check which bindings are from boxed fields
                        let bindings_str: Vec<String> = arm.bindings.iter()
                            .map(|(field, binding)| {
                                let field_name = interner.resolve(*field);
                                let binding_name = interner.resolve(*binding);

                                // Check if this field is boxed
                                if let Some(enum_name) = enum_name_str {
                                    let key = (enum_name.to_string(), variant_name.to_string(), field_name.to_string());
                                    if boxed_fields.contains(&key) {
                                        inner_boxed_binding_names.insert(binding_name.to_string());
                                    }
                                }

                                if field_name == binding_name {
                                    format!("ref {}", field_name)
                                } else {
                                    format!("{}: ref {}", field_name, binding_name)
                                }
                            })
                            .collect();
                        writeln!(output, "{}    {}{} {{ {} }} => {{", indent_str, enum_prefix, variant_name, bindings_str.join(", ")).unwrap();
                    }
                } else {
                    // Otherwise (wildcard) pattern
                    writeln!(output, "{}    _ => {{", indent_str).unwrap();
                }

                ctx.push_scope();

                // Register pattern-bound variable types from Inspect arms so that
                // type inference (e.g. for mixed Int/Real coercion) works correctly.
                if let Some(variant_sym) = arm.variant {
                    if let Some((_enum_name, variant_def)) = registry.find_variant(variant_sym) {
                        for (field_sym, binding_sym) in &arm.bindings {
                            if let Some(field_def) = variant_def.fields.iter().find(|f| f.name == *field_sym) {
                                let rust_type = super::types::codegen_field_type(&field_def.ty, interner);
                                ctx.register_variable_type(*binding_sym, rust_type);
                            }
                        }
                    }
                }

                // Generate explicit dereferences for boxed bindings at the start of the arm
                // With ref bindings, boxed fields need double deref: ref -> Box -> inner
                for binding_name in &inner_boxed_binding_names {
                    writeln!(output, "{}        let {} = (**{}).clone();", indent_str, binding_name, binding_name).unwrap();
                }

                // Clone non-boxed ref bindings to get owned values
                if let Some(_) = arm.variant {
                    for (_field, binding) in &arm.bindings {
                        let binding_name = interner.resolve(*binding);
                        if !inner_boxed_binding_names.contains(binding_name) {
                            writeln!(output, "{}        let {} = {}.clone();", indent_str, binding_name, binding_name).unwrap();
                        }
                    }
                }

                for stmt in arm.body {
                    // Phase 102: Handle inner Inspect statements with boxed bindings
                    // Note: Since we now dereference boxed bindings at the start of the arm,
                    // inner matches don't need the `*` dereference operator.
                    let inner_stmt_code = if let Stmt::Inspect { target: inner_target, .. } = stmt {
                        // Check if the inner target is a boxed binding (already dereferenced above)
                        // Use name comparison since symbols may differ between binding and reference
                        if let Expr::Identifier(sym) = inner_target {
                            let target_name = interner.resolve(*sym);
                            if inner_boxed_binding_names.contains(target_name) {
                                // Generate match (binding was already dereferenced at arm start)
                                let mut inner_output = String::new();
                                writeln!(inner_output, "{}match {} {{", "    ".repeat(indent + 2), target_name).unwrap();

                                if let Stmt::Inspect { arms: inner_arms, .. } = stmt {
                                    for inner_arm in inner_arms.iter() {
                                        if let Some(v) = inner_arm.variant {
                                            let v_name = interner.resolve(v);
                                            let inner_enum_prefix = inner_arm.enum_name
                                                .map(|e| format!("{}::", interner.resolve(e)))
                                                .unwrap_or_default();

                                            if inner_arm.bindings.is_empty() {
                                                writeln!(inner_output, "{}    {}{} => {{", "    ".repeat(indent + 2), inner_enum_prefix, v_name).unwrap();
                                            } else {
                                                let bindings: Vec<String> = inner_arm.bindings.iter()
                                                    .map(|(f, b)| {
                                                        let fn_name = interner.resolve(*f);
                                                        let bn_name = interner.resolve(*b);
                                                        if fn_name == bn_name { format!("ref {}", fn_name) }
                                                        else { format!("{}: ref {}", fn_name, bn_name) }
                                                    })
                                                    .collect();
                                                writeln!(inner_output, "{}    {}{} {{ {} }} => {{", "    ".repeat(indent + 2), inner_enum_prefix, v_name, bindings.join(", ")).unwrap();
                                            }
                                        } else {
                                            writeln!(inner_output, "{}    _ => {{", "    ".repeat(indent + 2)).unwrap();
                                        }

                                        ctx.push_scope();
                                        for inner_stmt in inner_arm.body {
                                            inner_output.push_str(&codegen_stmt(inner_stmt, interner, indent + 4, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env));
                                        }
                                        ctx.pop_scope();
                                        writeln!(inner_output, "{}    }}", "    ".repeat(indent + 2)).unwrap();
                                    }
                                }
                                writeln!(inner_output, "{}}}", "    ".repeat(indent + 2)).unwrap();
                                inner_output
                            } else {
                                codegen_stmt(stmt, interner, indent + 2, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env)
                            }
                        } else {
                            codegen_stmt(stmt, interner, indent + 2, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env)
                        }
                    } else {
                        codegen_stmt(stmt, interner, indent + 2, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env)
                    };
                    output.push_str(&inner_stmt_code);
                }
                ctx.pop_scope();
                writeln!(output, "{}    }}", indent_str).unwrap();
            }

            writeln!(output, "{}}}", indent_str).unwrap();
        }

        Stmt::Push { value, collection } => {
            let val_str = codegen_expr_boxed_with_types(value, interner, synced_vars, boxed_fields, registry, async_functions, ctx.get_string_vars(), ctx.get_variable_types());
            let coll_str = codegen_expr_with_async(collection, interner, synced_vars, async_functions, ctx.get_variable_types());
            writeln!(output, "{}{}.push({});", indent_str, coll_str, val_str).unwrap();
        }

        Stmt::Pop { collection, into } => {
            let coll_str = codegen_expr_with_async(collection, interner, synced_vars, async_functions, ctx.get_variable_types());
            match into {
                Some(var) => {
                    let var_name = names.ident(*var);
                    // Unwrap the Option returned by pop() - panics if empty
                    writeln!(output, "{}let {} = {}.pop().expect(\"Pop from empty collection\");", indent_str, var_name, coll_str).unwrap();
                }
                None => {
                    writeln!(output, "{}{}.pop();", indent_str, coll_str).unwrap();
                }
            }
        }

        Stmt::Add { value, collection } => {
            let val_str = codegen_expr_boxed_with_types(value, interner, synced_vars, boxed_fields, registry, async_functions, ctx.get_string_vars(), ctx.get_variable_types());
            let coll_str = codegen_expr_with_async(collection, interner, synced_vars, async_functions, ctx.get_variable_types());
            writeln!(output, "{}{}.insert({});", indent_str, coll_str, val_str).unwrap();
        }

        Stmt::Remove { value, collection } => {
            let val_str = codegen_expr_boxed_with_types(value, interner, synced_vars, boxed_fields, registry, async_functions, ctx.get_string_vars(), ctx.get_variable_types());
            let coll_str = codegen_expr_with_async(collection, interner, synced_vars, async_functions, ctx.get_variable_types());
            writeln!(output, "{}{}.remove(&{});", indent_str, coll_str, val_str).unwrap();
        }

        Stmt::SetIndex { collection, index, value } => {
            let coll_str = codegen_expr_with_async(collection, interner, synced_vars, async_functions, ctx.get_variable_types());
            let value_str = codegen_expr_boxed_with_types(value, interner, synced_vars, boxed_fields, registry, async_functions, ctx.get_string_vars(), ctx.get_variable_types());

            // Direct indexing for known collection types (avoids trait dispatch)
            // Strip |__hl: hoisting suffix so type matching works correctly.
            let known_type = if let Expr::Identifier(sym) = collection {
                ctx.get_variable_types().get(sym).map(|s| s.split("|__hl:").next().unwrap_or(s.as_str()))
            } else {
                None
            };

            match known_type {
                Some(t) if t.starts_with("LogosSeq") => {
                    // Use borrow_mut() for interior mutability — no &mut needed on the variable.
                    let is_zero_based_counter = if let Expr::Identifier(idx_sym) = index {
                        ctx.get_variable_types().get(idx_sym).map_or(false, |t| t == "__zero_based_i64")
                    } else {
                        false
                    };
                    let index_part = if is_zero_based_counter {
                        let idx_name = codegen_expr_with_async(index, interner, synced_vars, async_functions, ctx.get_variable_types());
                        format!("{} as usize", idx_name)
                    } else {
                        simplify_1based_index(index, interner, true)
                    };
                    // If RHS reads from the same collection, evaluate into a temp first
                    // to avoid simultaneous borrow() and borrow_mut() on the same RefCell.
                    let needs_tmp = if let Expr::Identifier(coll_sym) = collection {
                        expr_indexes_collection(value, *coll_sym)
                    } else {
                        false
                    };
                    if needs_tmp {
                        writeln!(output, "{}let __set_val = {};", indent_str, value_str).unwrap();
                        writeln!(output, "{}{}.borrow_mut()[{}] = __set_val;", indent_str, coll_str, index_part).unwrap();
                    } else {
                        writeln!(output, "{}{}.borrow_mut()[{}] = {};", indent_str, coll_str, index_part, value_str).unwrap();
                    }
                }
                Some(t) if t.starts_with("LogosMap") => {
                    let index_str = codegen_expr_with_async(index, interner, synced_vars, async_functions, ctx.get_variable_types());
                    writeln!(output, "{}{}.insert({}, {});", indent_str, coll_str, index_str, value_str).unwrap();
                }
                Some(t) if t.starts_with("Vec") || t.starts_with("&mut [") || t.starts_with("&[") => {
                    // OPT-8: Check if index is a zero-based counter
                    let is_zero_based_counter = if let Expr::Identifier(idx_sym) = index {
                        ctx.get_variable_types().get(idx_sym).map_or(false, |t| t == "__zero_based_i64")
                    } else {
                        false
                    };
                    let index_part = if is_zero_based_counter {
                        let idx_name = codegen_expr_with_async(index, interner, synced_vars, async_functions, ctx.get_variable_types());
                        format!("{} as usize", idx_name)
                    } else {
                        simplify_1based_index(index, interner, true)
                    };
                    writeln!(output, "{}{}[{}] = {};", indent_str, coll_str, index_part, value_str).unwrap();
                }
                Some(t) if t.starts_with("std::collections::HashMap") || t.starts_with("HashMap") || t.starts_with("rustc_hash::FxHashMap") || t.starts_with("FxHashMap") => {
                    let index_str = codegen_expr_with_async(index, interner, synced_vars, async_functions, ctx.get_variable_types());
                    writeln!(output, "{}{}.insert({}, {});", indent_str, coll_str, index_str, value_str).unwrap();
                }
                _ => {
                    let index_str = codegen_expr_with_async(index, interner, synced_vars, async_functions, ctx.get_variable_types());
                    // Fallback: polymorphic indexing via trait.
                    // If the value expression reads from the same collection being written,
                    // we need a temporary binding to avoid aliasing (&mut coll vs &coll).
                    let needs_tmp = if let Expr::Identifier(coll_sym) = collection {
                        expr_indexes_collection(value, *coll_sym)
                    } else {
                        false
                    };
                    if needs_tmp {
                        writeln!(output, "{}let __set_tmp = {};", indent_str, value_str).unwrap();
                        writeln!(output, "{}LogosIndexMut::logos_set(&mut {}, {}, __set_tmp);", indent_str, coll_str, index_str).unwrap();
                    } else {
                        writeln!(output, "{}LogosIndexMut::logos_set(&mut {}, {}, {});", indent_str, coll_str, index_str, value_str).unwrap();
                    }
                }
            }
        }

        // Phase 8.5: Zone (memory arena) block
        Stmt::Zone { name, capacity, source_file, body } => {
            let zone_name = interner.resolve(*name);

            // Generate zone creation based on type
            if let Some(path_sym) = source_file {
                // Memory-mapped file zone
                let path = interner.resolve(*path_sym);
                writeln!(
                    output,
                    "{}let {} = logicaffeine_system::memory::Zone::new_mapped(\"{}\").expect(\"Failed to map file\");",
                    indent_str, zone_name, path
                ).unwrap();
            } else {
                // Heap arena zone
                let cap = capacity.unwrap_or(4096); // Default 4KB
                writeln!(
                    output,
                    "{}let {} = logicaffeine_system::memory::Zone::new_heap({});",
                    indent_str, zone_name, cap
                ).unwrap();
            }

            // Open block scope
            writeln!(output, "{}{{", indent_str).unwrap();
            ctx.push_scope();

            // Generate body statements
            for stmt in *body {
                output.push_str(&codegen_stmt(stmt, interner, indent + 1, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env));
            }

            ctx.pop_scope();
            writeln!(output, "{}}}", indent_str).unwrap();
        }

        // Phase 9: Concurrent execution block (async, I/O-bound)
        // Generates tokio::join! for concurrent task execution
        // Phase 51: Variables used across multiple tasks are cloned to avoid move issues
        Stmt::Concurrent { tasks } => {
            // Collect Let statements to generate tuple destructuring
            let let_bindings: Vec<_> = tasks.iter().filter_map(|s| {
                if let Stmt::Let { var, .. } = s {
                    Some(interner.resolve(*var).to_string())
                } else {
                    None
                }
            }).collect();

            // Collect variables DEFINED in this block (to exclude from cloning)
            let defined_vars: HashSet<Symbol> = tasks.iter().filter_map(|s| {
                if let Stmt::Let { var, .. } = s {
                    Some(*var)
                } else {
                    None
                }
            }).collect();

            // Check if there are intra-block dependencies (a later task uses a var from earlier task)
            // If so, fall back to sequential execution
            let mut has_intra_dependency = false;
            let mut seen_defs: HashSet<Symbol> = HashSet::new();
            for s in *tasks {
                // Check if this task uses any variable defined by previous tasks in this block
                let mut used_in_task: HashSet<Symbol> = HashSet::new();
                collect_stmt_identifiers(s, &mut used_in_task);
                for used_var in &used_in_task {
                    if seen_defs.contains(used_var) {
                        has_intra_dependency = true;
                        break;
                    }
                }
                // Track variables defined by this task
                if let Stmt::Let { var, .. } = s {
                    seen_defs.insert(*var);
                }
                if has_intra_dependency {
                    break;
                }
            }

            // Collect ALL variables used in task expressions (not just Call args)
            // Exclude variables defined within this block
            let mut used_syms: HashSet<Symbol> = HashSet::new();
            for s in *tasks {
                collect_stmt_identifiers(s, &mut used_syms);
            }
            // Remove variables that are defined in this block
            for def_var in &defined_vars {
                used_syms.remove(def_var);
            }
            let used_vars: HashSet<String> = used_syms.iter()
                .map(|sym| interner.resolve(*sym).to_string())
                .collect();

            // If there are intra-block dependencies, execute sequentially
            if has_intra_dependency {
                // Generate sequential Let bindings
                for stmt in *tasks {
                    output.push_str(&codegen_stmt(stmt, interner, indent, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env));
                }
            } else {
                // Generate concurrent execution with tokio::join!
                if !let_bindings.is_empty() {
                    // Generate tuple destructuring for concurrent Let bindings
                    writeln!(output, "{}let ({}) = tokio::join!(", indent_str, let_bindings.join(", ")).unwrap();
                } else {
                    writeln!(output, "{}tokio::join!(", indent_str).unwrap();
                }

                for (i, stmt) in tasks.iter().enumerate() {
                    // For Let statements, generate only the VALUE so the async block returns it
                    // For Call statements, generate the call with .await
                    let inner_code = match stmt {
                        Stmt::Let { value, .. } => {
                            // Return the value expression directly (not "let x = value;")
                            // Phase 54+: Use codegen_expr_with_async to handle all nested async calls
                            codegen_expr_with_async(value, interner, synced_vars, async_functions, ctx.get_variable_types())
                        }
                        Stmt::Call { function, args } => {
                            let func_name = interner.resolve(*function);
                            let args_str: Vec<String> = args.iter()
                                .map(|a| codegen_expr_with_async(a, interner, synced_vars, async_functions, ctx.get_variable_types()))
                                .collect();
                            // Only add .await for async functions
                            let await_suffix = if async_functions.contains(function) { ".await" } else { "" };
                            format!("{}({}){}", func_name, args_str.join(", "), await_suffix)
                        }
                        _ => {
                            // Fallback for other statement types
                            let inner = codegen_stmt(stmt, interner, indent + 1, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env);
                            inner.trim().to_string()
                        }
                    };

                    // For tasks that use shared variables, wrap in a block that clones them
                    if !used_vars.is_empty() && i < tasks.len() - 1 {
                        // Clone variables for all tasks except the last one
                        let clones: Vec<String> = used_vars.iter()
                            .map(|v| format!("let {} = {}.clone();", v, v))
                            .collect();
                        write!(output, "{}    {{ {} async move {{ {} }} }}",
                               indent_str, clones.join(" "), inner_code).unwrap();
                    } else {
                        // Last task can use original variables
                        write!(output, "{}    async {{ {} }}", indent_str, inner_code).unwrap();
                    }

                    if i < tasks.len() - 1 {
                        writeln!(output, ",").unwrap();
                    } else {
                        writeln!(output).unwrap();
                    }
                }

                writeln!(output, "{});", indent_str).unwrap();
            }
        }

        // Phase 9: Parallel execution block (CPU-bound)
        // Generates rayon::join for two tasks, or thread::spawn for 3+ tasks
        Stmt::Parallel { tasks } => {
            // Collect Let statements to generate tuple destructuring
            let let_bindings: Vec<_> = tasks.iter().filter_map(|s| {
                if let Stmt::Let { var, .. } = s {
                    Some(interner.resolve(*var).to_string())
                } else {
                    None
                }
            }).collect();

            if tasks.len() == 2 {
                // Use rayon::join for exactly 2 tasks
                if !let_bindings.is_empty() {
                    writeln!(output, "{}let ({}) = rayon::join(", indent_str, let_bindings.join(", ")).unwrap();
                } else {
                    writeln!(output, "{}rayon::join(", indent_str).unwrap();
                }

                for (i, stmt) in tasks.iter().enumerate() {
                    // For Let statements, generate only the VALUE so the closure returns it
                    let inner_code = match stmt {
                        Stmt::Let { value, .. } => {
                            // Return the value expression directly (not "let x = value;")
                            codegen_expr_with_async(value, interner, synced_vars, async_functions, ctx.get_variable_types())
                        }
                        Stmt::Call { function, args } => {
                            let func_name = interner.resolve(*function);
                            let variable_types = ctx.get_variable_types();
                            let callee_borrow_indices: HashSet<usize> = variable_types.get(function)
                                .and_then(|t| t.strip_prefix("fn_borrow:"))
                                .map(|s| s.split(',').filter_map(|idx| idx.parse().ok()).collect())
                                .unwrap_or_default();
                            let args_str: Vec<String> = args.iter().enumerate()
                                .map(|(idx, a)| {
                                    let s = codegen_expr_with_async(a, interner, synced_vars, async_functions, variable_types);
                                    if callee_borrow_indices.contains(&idx) {
                                        if let Expr::Identifier(sym) = a {
                                            if let Some(ty) = variable_types.get(sym) {
                                                if ty.starts_with("&[") {
                                                    return s;
                                                }
                                            }
                                        }
                                        format!("&{}", s)
                                    } else { s }
                                })
                                .collect();
                            format!("{}({})", func_name, args_str.join(", "))
                        }
                        _ => {
                            // Fallback for other statement types
                            let inner = codegen_stmt(stmt, interner, indent + 1, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env);
                            inner.trim().to_string()
                        }
                    };
                    write!(output, "{}    || {{ {} }}", indent_str, inner_code).unwrap();
                    if i == 0 {
                        writeln!(output, ",").unwrap();
                    } else {
                        writeln!(output).unwrap();
                    }
                }
                writeln!(output, "{});", indent_str).unwrap();
            } else {
                // For 3+ tasks, use thread::spawn pattern
                writeln!(output, "{}{{", indent_str).unwrap();
                writeln!(output, "{}    let handles: Vec<_> = vec![", indent_str).unwrap();
                for stmt in *tasks {
                    // For Let statements, generate only the VALUE so the closure returns it
                    let inner_code = match stmt {
                        Stmt::Let { value, .. } => {
                            codegen_expr_with_async(value, interner, synced_vars, async_functions, ctx.get_variable_types())
                        }
                        Stmt::Call { function, args } => {
                            let func_name = interner.resolve(*function);
                            let variable_types = ctx.get_variable_types();
                            let callee_borrow_indices: HashSet<usize> = variable_types.get(function)
                                .and_then(|t| t.strip_prefix("fn_borrow:"))
                                .map(|s| s.split(',').filter_map(|idx| idx.parse().ok()).collect())
                                .unwrap_or_default();
                            let args_str: Vec<String> = args.iter().enumerate()
                                .map(|(idx, a)| {
                                    let s = codegen_expr_with_async(a, interner, synced_vars, async_functions, variable_types);
                                    if callee_borrow_indices.contains(&idx) {
                                        if let Expr::Identifier(sym) = a {
                                            if let Some(ty) = variable_types.get(sym) {
                                                if ty.starts_with("&[") {
                                                    return s;
                                                }
                                            }
                                        }
                                        format!("&{}", s)
                                    } else { s }
                                })
                                .collect();
                            format!("{}({})", func_name, args_str.join(", "))
                        }
                        _ => {
                            let inner = codegen_stmt(stmt, interner, indent + 2, mutable_vars, ctx, lww_fields, mv_fields, synced_vars, var_caps, async_functions, pipe_vars, boxed_fields, registry, type_env);
                            inner.trim().to_string()
                        }
                    };
                    writeln!(output, "{}        std::thread::spawn(move || {{ {} }}),",
                             indent_str, inner_code).unwrap();
                }
                writeln!(output, "{}    ];", indent_str).unwrap();
                writeln!(output, "{}    for h in handles {{ h.join().unwrap(); }}", indent_str).unwrap();
                writeln!(output, "{}}}", indent_str).unwrap();
            }
        }

        // Phase 10: Read from console or file
        // Phase 53: File reads now use async VFS
        Stmt::ReadFrom { var, source } => {
            let var_name = interner.resolve(*var);
            match source {
                ReadSource::Console => {
                    writeln!(output, "{}let {} = logicaffeine_system::io::read_line();", indent_str, var_name).unwrap();
                }
                ReadSource::File(path_expr) => {
                    let path_str = codegen_expr_with_async(path_expr, interner, synced_vars, async_functions, ctx.get_variable_types());
                    // Phase 53: Use VFS with async
                    writeln!(
                        output,
                        "{}let {} = vfs.read_to_string(&{}).await.expect(\"Failed to read file\");",
                        indent_str, var_name, path_str
                    ).unwrap();
                }
            }
        }

        // Phase 10: Write to file
        // Phase 53: File writes now use async VFS
        Stmt::WriteFile { content, path } => {
            let content_str = codegen_expr_with_async(content, interner, synced_vars, async_functions, ctx.get_variable_types());
            let path_str = codegen_expr_with_async(path, interner, synced_vars, async_functions, ctx.get_variable_types());
            // Phase 53: Use VFS with async
            writeln!(
                output,
                "{}vfs.write(&{}, {}.as_bytes()).await.expect(\"Failed to write file\");",
                indent_str, path_str, content_str
            ).unwrap();
        }

        // Phase 46: Spawn an agent
        Stmt::Spawn { agent_type, name } => {
            let type_name = interner.resolve(*agent_type);
            let agent_name = interner.resolve(*name);
            // Generate agent spawn with tokio channel
            writeln!(
                output,
                "{}let {} = tokio::spawn(async move {{ /* {} agent loop */ }});",
                indent_str, agent_name, type_name
            ).unwrap();
        }

        // Phase 46: Send message to agent
        Stmt::SendMessage { message, destination } => {
            let msg_str = codegen_expr_with_async(message, interner, synced_vars, async_functions, ctx.get_variable_types());
            let dest_str = codegen_expr_with_async(destination, interner, synced_vars, async_functions, ctx.get_variable_types());
            writeln!(
                output,
                "{}{}.send({}).await.expect(\"Failed to send message\");",
                indent_str, dest_str, msg_str
            ).unwrap();
        }

        // Phase 46: Await response from agent
        Stmt::AwaitMessage { source, into } => {
            let src_str = codegen_expr_with_async(source, interner, synced_vars, async_functions, ctx.get_variable_types());
            let var_name = interner.resolve(*into);
            writeln!(
                output,
                "{}let {} = {}.recv().await.expect(\"Failed to receive message\");",
                indent_str, var_name, src_str
            ).unwrap();
        }

        // Phase 49: Merge CRDT state
        Stmt::MergeCrdt { source, target } => {
            let src_str = codegen_expr_with_async(source, interner, synced_vars, async_functions, ctx.get_variable_types());
            let tgt_str = codegen_expr_with_async(target, interner, synced_vars, async_functions, ctx.get_variable_types());
            writeln!(
                output,
                "{}{}.merge(&{});",
                indent_str, tgt_str, src_str
            ).unwrap();
        }

        // Phase 49: Increment GCounter
        // Phase 52: If object is synced, wrap in .mutate() for auto-publish
        Stmt::IncreaseCrdt { object, field, amount } => {
            let field_name = interner.resolve(*field);
            let amount_str = codegen_expr_with_async(amount, interner, synced_vars, async_functions, ctx.get_variable_types());

            // Check if the root object is synced
            let root_sym = get_root_identifier(object);
            if let Some(sym) = root_sym {
                if synced_vars.contains(&sym) {
                    // Synced: use .mutate() for auto-publish
                    let obj_name = interner.resolve(sym);
                    writeln!(
                        output,
                        "{}{}.mutate(|inner| inner.{}.increment({} as u64)).await;",
                        indent_str, obj_name, field_name, amount_str
                    ).unwrap();
                    return output;
                }
            }

            // Not synced: direct access
            let obj_str = codegen_expr_with_async(object, interner, synced_vars, async_functions, ctx.get_variable_types());
            writeln!(
                output,
                "{}{}.{}.increment({} as u64);",
                indent_str, obj_str, field_name, amount_str
            ).unwrap();
        }

        // Phase 49b: Decrement PNCounter
        Stmt::DecreaseCrdt { object, field, amount } => {
            let field_name = interner.resolve(*field);
            let amount_str = codegen_expr_with_async(amount, interner, synced_vars, async_functions, ctx.get_variable_types());

            // Check if the root object is synced
            let root_sym = get_root_identifier(object);
            if let Some(sym) = root_sym {
                if synced_vars.contains(&sym) {
                    // Synced: use .mutate() for auto-publish
                    let obj_name = interner.resolve(sym);
                    writeln!(
                        output,
                        "{}{}.mutate(|inner| inner.{}.decrement({} as u64)).await;",
                        indent_str, obj_name, field_name, amount_str
                    ).unwrap();
                    return output;
                }
            }

            // Not synced: direct access
            let obj_str = codegen_expr_with_async(object, interner, synced_vars, async_functions, ctx.get_variable_types());
            writeln!(
                output,
                "{}{}.{}.decrement({} as u64);",
                indent_str, obj_str, field_name, amount_str
            ).unwrap();
        }

        // Phase 49b: Append to SharedSequence (RGA)
        Stmt::AppendToSequence { sequence, value } => {
            let seq_str = codegen_expr_with_async(sequence, interner, synced_vars, async_functions, ctx.get_variable_types());
            let val_str = codegen_expr_boxed_with_types(value, interner, synced_vars, boxed_fields, registry, async_functions, ctx.get_string_vars(), ctx.get_variable_types());
            writeln!(
                output,
                "{}{}.append({});",
                indent_str, seq_str, val_str
            ).unwrap();
        }

        // Phase 49b: Resolve MVRegister conflicts
        Stmt::ResolveConflict { object, field, value } => {
            let field_name = interner.resolve(*field);
            let val_str = codegen_expr_boxed_with_types(value, interner, synced_vars, boxed_fields, registry, async_functions, ctx.get_string_vars(), ctx.get_variable_types());
            let obj_str = codegen_expr_with_async(object, interner, synced_vars, async_functions, ctx.get_variable_types());
            writeln!(
                output,
                "{}{}.{}.resolve({});",
                indent_str, obj_str, field_name, val_str
            ).unwrap();
        }

        // Escape hatch: emit raw foreign code wrapped in braces for scope isolation
        Stmt::Escape { code, .. } => {
            let raw_code = interner.resolve(*code);
            write!(output, "{}{{\n", indent_str).unwrap();
            for line in raw_code.lines() {
                write!(output, "{}    {}\n", indent_str, line).unwrap();
            }
            write!(output, "{}}}\n", indent_str).unwrap();
        }

        // Dependencies are metadata; no Rust code emitted.
        Stmt::Require { .. } => {}

        // Phase 63: Theorems are verified at compile-time, no runtime code generated
        Stmt::Theorem(_) => {
            // Theorems don't generate runtime code - they're processed separately
            // by compile_theorem() at the meta-level
        }
    }

    output
}

/// OPT-5: Sentinel → break transformation.
///
/// Detects `If cond then: ...; Set counter to limit.` inside a `While counter < limit:` loop
/// and replaces the sentinel set with `break;`. This gives LLVM a clean early-exit edge
/// instead of an opaque counter assignment that forces one more condition check.
///
/// Returns the generated code if the pattern matches, or None.
fn try_emit_sentinel_break<'a>(
    stmt: &Stmt<'a>,
    counter_sym: Symbol,
    limit_expr: &Expr<'a>,
    interner: &Interner,
    indent: usize,
    mutable_vars: &HashSet<Symbol>,
    ctx: &mut RefinementContext<'a>,
    lww_fields: &HashSet<(String, String)>,
    mv_fields: &HashSet<(String, String)>,
    synced_vars: &mut HashSet<Symbol>,
    var_caps: &HashMap<Symbol, VariableCapabilities>,
    async_functions: &HashSet<Symbol>,
    pipe_vars: &HashSet<Symbol>,
    boxed_fields: &HashSet<(String, String, String)>,
    registry: &TypeRegistry,
    type_env: &crate::analysis::types::TypeEnv,
) -> Option<String> {
    // Match: If cond then: ...; Set counter to limit. (no else block)
    let (if_cond, then_block, else_block) = match stmt {
        Stmt::If { cond, then_block, else_block } => (cond, then_block, else_block),
        _ => return None,
    };

    if else_block.is_some() {
        return None;
    }

    if then_block.is_empty() {
        return None;
    }

    // Last statement in then_block must be `Set counter to limit`
    let last = &then_block[then_block.len() - 1];
    match last {
        Stmt::Set { target, value, .. } => {
            if *target != counter_sym || !exprs_equal(value, limit_expr) {
                return None;
            }
        }
        _ => return None,
    }

    // Pattern matched! Emit if block with break instead of sentinel set.
    let indent_str = "    ".repeat(indent);
    let var_types = ctx.get_variable_types();
    let cond_str = codegen_expr_with_async(if_cond, interner, synced_vars, async_functions, var_types);
    let mut output = String::new();
    writeln!(output, "{}if {} {{", indent_str, cond_str).unwrap();

    // Emit all then_block statements except the last (the sentinel set)
    for s in &then_block[..then_block.len() - 1] {
        output.push_str(&codegen_stmt(
            s, interner, indent + 1, mutable_vars, ctx,
            lww_fields, mv_fields, synced_vars, var_caps,
            async_functions, pipe_vars, boxed_fields, registry, type_env,
        ));
    }

    // Emit break instead of the sentinel set
    writeln!(output, "{}    break;", indent_str).unwrap();
    writeln!(output, "{}}}", indent_str).unwrap();

    Some(output)
}

/// Phase 52: Extract the root identifier from an expression.
/// For `x.field.subfield`, returns `x`.
pub(crate) fn get_root_identifier(expr: &Expr) -> Option<Symbol> {
    match expr {
        Expr::Identifier(sym) => Some(*sym),
        Expr::FieldAccess { object, .. } => get_root_identifier(object),
        _ => None,
    }
}

/// Extract all symbols from `Expr::Length { collection: Expr::Identifier(sym) }` nodes
/// in an expression tree. Used for loop bounds hoisting.
pub(crate) fn extract_length_expr_syms(expr: &Expr) -> Vec<Symbol> {
    let mut out = Vec::new();
    collect_length_syms_from_expr(expr, &mut out);
    out
}

fn collect_length_syms_from_expr(expr: &Expr, out: &mut Vec<Symbol>) {
    match expr {
        Expr::Length { collection } => {
            if let Expr::Identifier(sym) = collection {
                out.push(*sym);
            }
        }
        Expr::BinaryOp { left, right, .. } => {
            collect_length_syms_from_expr(left, out);
            collect_length_syms_from_expr(right, out);
        }
        Expr::Not { operand } => collect_length_syms_from_expr(operand, out),
        Expr::Index { collection, index } => {
            collect_length_syms_from_expr(collection, out);
            collect_length_syms_from_expr(index, out);
        }
        Expr::Call { args, .. } => {
            for arg in args.iter() {
                collect_length_syms_from_expr(arg, out);
            }
        }
        _ => {}
    }
}

/// Collect all `Expr::Length { Identifier(sym) }` symbols from a statement list (recursively).
pub(crate) fn collect_length_syms_from_stmts(stmts: &[Stmt], out: &mut Vec<Symbol>) {
    for stmt in stmts {
        collect_length_syms_from_stmt(stmt, out);
    }
}

fn collect_length_syms_from_stmt(stmt: &Stmt, out: &mut Vec<Symbol>) {
    match stmt {
        Stmt::Let { value, .. } => collect_length_syms_from_expr(value, out),
        Stmt::Set { value, .. } => collect_length_syms_from_expr(value, out),
        Stmt::Show { object, .. } => collect_length_syms_from_expr(object, out),
        Stmt::Push { value, collection } => {
            collect_length_syms_from_expr(value, out);
            collect_length_syms_from_expr(collection, out);
        }
        Stmt::SetIndex { collection, index, value } => {
            collect_length_syms_from_expr(collection, out);
            collect_length_syms_from_expr(index, out);
            collect_length_syms_from_expr(value, out);
        }
        Stmt::If { cond, then_block, else_block } => {
            collect_length_syms_from_expr(cond, out);
            collect_length_syms_from_stmts(then_block, out);
            if let Some(else_stmts) = else_block {
                collect_length_syms_from_stmts(else_stmts, out);
            }
        }
        Stmt::While { cond, body, .. } => {
            collect_length_syms_from_expr(cond, out);
            collect_length_syms_from_stmts(body, out);
        }
        Stmt::Repeat { body, .. } => {
            collect_length_syms_from_stmts(body, out);
        }
        Stmt::Return { value } => {
            if let Some(v) = value {
                collect_length_syms_from_expr(v, out);
            }
        }
        Stmt::Call { args, .. } => {
            for arg in args.iter() {
                collect_length_syms_from_expr(arg, out);
            }
        }
        _ => {}
    }
}

/// Check if a type string represents a Copy type (no .clone() needed).
/// Delegates to `LogosType::is_copy()` — single source of truth.
pub(crate) fn is_copy_type(ty: &str) -> bool {
    crate::analysis::types::LogosType::from_rust_type_str(ty).is_copy()
}

/// Check if a Vec<T> type has a Copy element type.
/// Delegates to `LogosType::element_type().is_copy()` — single source of truth.
pub(crate) fn has_copy_element_type(vec_type: &str) -> bool {
    crate::analysis::types::LogosType::from_rust_type_str(vec_type)
        .element_type()
        .map_or(false, |e| e.is_copy())
}

/// Check if a HashMap<K, V> type has a Copy value type.
/// Delegates to `LogosType::value_type().is_copy()` — single source of truth.
pub(crate) fn has_copy_value_type(map_type: &str) -> bool {
    crate::analysis::types::LogosType::from_rust_type_str(map_type)
        .value_type()
        .map_or(false, |v| v.is_copy())
}

/// Detect commutative reduction patterns in Repeat loops and emit par_iter() code.
///
/// Pattern: `Repeat for x in coll: Set acc = acc + expr(x)`
/// Emits:
/// ```text
/// if coll.len() >= 10000 {
///     acc += coll.par_iter().copied().map(|x| expr).sum::<i64>();
/// } else {
///     for x in coll.iter().copied() { acc = acc + expr; }
/// }
/// ```
fn try_emit_parallel_reduction<'a>(
    var_sym: Symbol,
    pattern_str: &str,
    iter_str: &str,
    iterable: &'a Expr<'a>,
    body: &'a [Stmt<'a>],
    interner: &Interner,
    indent: usize,
    ctx: &RefinementContext<'a>,
    synced_vars: &HashSet<Symbol>,
    async_functions: &HashSet<Symbol>,
) -> Option<String> {
    // Body must be exactly 1 statement: Set acc = acc OP expr
    if body.len() != 1 { return None; }

    let (acc_sym, op, increment_expr) = match &body[0] {
        Stmt::Set { target, value } => {
            if let Expr::BinaryOp { op, left, right } = value {
                match op {
                    BinaryOpKind::Add => {
                        // acc = acc + expr  OR  acc = expr + acc
                        if let Expr::Identifier(lhs) = left {
                            if *lhs == *target {
                                Some((*target, BinaryOpKind::Add, *right))
                            } else {
                                None
                            }
                        } else if let Expr::Identifier(rhs) = right {
                            if *rhs == *target {
                                Some((*target, BinaryOpKind::Add, *left))
                            } else {
                                None
                            }
                        } else {
                            None
                        }
                    }
                    _ => None,
                }
            } else {
                None
            }
        }
        _ => None,
    }?;

    // The increment expression must only involve the loop variable and literals
    if !expr_is_pure_of(increment_expr, var_sym) {
        return None;
    }

    // The collection must be a typed Vec (for .par_iter().copied())
    let is_vec_i64 = if let Expr::Identifier(coll_sym) = iterable {
        ctx.get_variable_types().get(coll_sym)
            .map(|t| {
                let t = t.split("|__hl:").next().unwrap_or(t.as_str());
                (t.starts_with("LogosSeq<") || t.starts_with("Vec<") || t.starts_with("&[")) && has_copy_element_type(t)
            })
            .unwrap_or(false)
    } else {
        false
    };

    if !is_vec_i64 { return None; }

    let indent_str = "    ".repeat(indent);
    let acc_name = interner.resolve(acc_sym);

    // Generate the increment expression as Rust code
    let incr_code = codegen_expr_with_async(
        increment_expr, interner, synced_vars, async_functions,
        ctx.get_variable_types(),
    );

    // Determine if we need a .map() or can use .sum() directly
    let needs_map = !matches!(increment_expr, Expr::Identifier(s) if *s == var_sym);

    let mut out = String::new();

    // Emit parallel reduction with runtime threshold
    // LogosSeq needs .borrow() to access the inner Vec for .par_iter()/.iter()
    // &[T] and Vec<T> can be used directly without .borrow()
    let (borrow_expr, len_expr) = if let Expr::Identifier(coll_sym) = iterable {
        let ty = ctx.get_variable_types().get(coll_sym).map(|s| s.split("|__hl:").next().unwrap_or(s.as_str()));
        if matches!(ty, Some(t) if t.starts_with("LogosSeq")) {
            (format!("{}.borrow()", iter_str), format!("{}.len()", iter_str))
        } else {
            (iter_str.to_string(), format!("{}.len()", iter_str))
        }
    } else {
        (format!("{}.borrow()", iter_str), format!("{}.len()", iter_str))
    };
    writeln!(out, "{}if {} >= 10000 {{", indent_str, len_expr).unwrap();
    writeln!(out, "{}    use rayon::prelude::*;", indent_str).unwrap();
    writeln!(out, "{}    let __par_ref = {};", indent_str, borrow_expr).unwrap();
    if needs_map {
        writeln!(out, "{}    {} += __par_ref.par_iter().copied().map(|{}| {}).sum::<i64>();",
            indent_str, acc_name, pattern_str, incr_code).unwrap();
    } else {
        writeln!(out, "{}    {} += __par_ref.par_iter().copied().sum::<i64>();",
            indent_str, acc_name).unwrap();
    }
    writeln!(out, "{}}} else {{", indent_str).unwrap();
    writeln!(out, "{}    for {} in {}.to_vec() {{", indent_str, pattern_str, iter_str).unwrap();

    match op {
        BinaryOpKind::Add => {
            writeln!(out, "{}        {} += {};", indent_str, acc_name, incr_code).unwrap();
        }
        _ => {
            writeln!(out, "{}        {} = {} {:?} {};", indent_str, acc_name, acc_name, op, incr_code).unwrap();
        }
    }
    writeln!(out, "{}    }}", indent_str).unwrap();
    writeln!(out, "{}}}", indent_str).unwrap();

    Some(out)
}

/// Check if an expression only involves the given symbol and literals (no side effects).
fn expr_is_pure_of(expr: &Expr, allowed_sym: Symbol) -> bool {
    match expr {
        Expr::Identifier(s) => *s == allowed_sym,
        Expr::Literal(_) => true,
        Expr::BinaryOp { left, right, .. } => {
            expr_is_pure_of(left, allowed_sym) && expr_is_pure_of(right, allowed_sym)
        }
        Expr::Not { operand } => expr_is_pure_of(operand, allowed_sym),
        _ => false,
    }
}

