use super::classify::branches_share_mutable_state;
use crate::ast::stmt::Stmt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SendDiagnostic {
pub message: String,
}
pub fn check_send_escape(stmts: &[Stmt]) -> Vec<SendDiagnostic> {
let mut diags = Vec::new();
check_block(stmts, &mut diags);
diags
}
fn check_block(stmts: &[Stmt], diags: &mut Vec<SendDiagnostic>) {
for stmt in stmts {
match stmt {
Stmt::Parallel { tasks } | Stmt::Concurrent { tasks } => {
if branches_share_mutable_state(tasks) {
diags.push(SendDiagnostic {
message: "concurrent branches share mutable state across tasks — \
pass it through a Pipe or make it a CRDT"
.to_string(),
});
}
check_block(tasks, diags);
}
Stmt::If { then_block, else_block, .. } => {
check_block(then_block, diags);
if let Some(eb) = else_block {
check_block(eb, diags);
}
}
Stmt::While { body, .. }
| Stmt::Repeat { body, .. }
| Stmt::Zone { body, .. }
| Stmt::FunctionDef { body, .. } => check_block(body, diags),
Stmt::Inspect { arms, .. } => {
for arm in arms.iter() {
check_block(arm.body, diags);
}
}
_ => {}
}
}
}