@@ -1584,6 +1584,131 @@ func TranspileStatement(out *strings.Builder, stmt ast.Stmt, fnType *ast.FuncTyp
15841584 // Restore previous capture renames
15851585 currentCaptureRenames = oldCaptureRenames
15861586
1587+ case * ast.GoStmt :
1588+ // Track that we need thread import
1589+ TrackImport ("thread" )
1590+
1591+ // Check if the go statement contains a closure that captures variables
1592+ captured := findCapturedInCall (s .Call )
1593+
1594+ // Generate clones for captured variables
1595+ // Sort variable names for deterministic output
1596+ var capturedVars []string
1597+ for varName := range captured {
1598+ capturedVars = append (capturedVars , varName )
1599+ }
1600+ slices .Sort (capturedVars )
1601+
1602+ for _ , varName := range capturedVars {
1603+ out .WriteString ("let " )
1604+ out .WriteString (varName )
1605+ out .WriteString ("_thread = " )
1606+ out .WriteString (varName )
1607+ out .WriteString (".clone(); " )
1608+ }
1609+
1610+ // Store current capture renames for nested transpilation
1611+ captureRenames := make (map [string ]string )
1612+ for _ , varName := range capturedVars {
1613+ captureRenames [varName ] = varName + "_thread"
1614+ }
1615+ oldCaptureRenames := currentCaptureRenames
1616+ currentCaptureRenames = captureRenames
1617+
1618+ // Generate the thread::spawn call
1619+ out .WriteString ("std::thread::spawn(move || {\n " )
1620+ out .WriteString (" " )
1621+
1622+ // Check if it's an immediately invoked function literal
1623+ if funcLit , ok := s .Call .Fun .(* ast.FuncLit ); ok {
1624+ // Generate the closure body inline
1625+ if len (s .Call .Args ) > 0 {
1626+ // Has arguments - need to create parameter bindings
1627+ out .WriteString ("let __closure = move |" )
1628+ // Parameters
1629+ if funcLit .Type .Params != nil {
1630+ var params []string
1631+ for _ , field := range funcLit .Type .Params .List {
1632+ paramType := GoTypeToRust (field .Type )
1633+ for _ , name := range field .Names {
1634+ params = append (params , name .Name + ": " + paramType )
1635+ }
1636+ }
1637+ out .WriteString (strings .Join (params , ", " ))
1638+ }
1639+ out .WriteString ("| {\n " )
1640+
1641+ // Body
1642+ for i , stmt := range funcLit .Body .List {
1643+ if i > 0 {
1644+ out .WriteString ("\n " )
1645+ }
1646+ TranspileStatementSimple (out , stmt , funcLit .Type , fileSet )
1647+ out .WriteString (";" )
1648+ }
1649+
1650+ out .WriteString ("\n };\n " )
1651+ out .WriteString (" __closure(" )
1652+
1653+ // Arguments
1654+ for i , arg := range s .Call .Args {
1655+ if i > 0 {
1656+ out .WriteString (", " )
1657+ }
1658+ // Wrap arguments appropriately
1659+ if ident , ok := arg .(* ast.Ident ); ok && ident .Name != "nil" && ident .Name != "_" {
1660+ // Check if this is a variable (not a constant)
1661+ if _ , isRangeVar := rangeLoopVars [ident .Name ]; ! isRangeVar {
1662+ if _ , isLocalConst := localConstants [ident .Name ]; ! isLocalConst {
1663+ // It's a variable, clone it
1664+ if captureRenames [ident .Name ] != "" {
1665+ out .WriteString (captureRenames [ident .Name ])
1666+ } else {
1667+ out .WriteString (ident .Name )
1668+ out .WriteString (".clone()" )
1669+ }
1670+ } else {
1671+ // It's a constant, wrap it
1672+ out .WriteString ("Arc::new(Mutex::new(Some(" )
1673+ TranspileExpression (out , arg )
1674+ out .WriteString (")))" )
1675+ }
1676+ } else {
1677+ // Range variable, wrap it
1678+ out .WriteString ("Arc::new(Mutex::new(Some(" )
1679+ TranspileExpression (out , arg )
1680+ out .WriteString (")))" )
1681+ }
1682+ } else {
1683+ // Complex expression or literal, wrap it
1684+ out .WriteString ("Arc::new(Mutex::new(Some(" )
1685+ TranspileExpression (out , arg )
1686+ out .WriteString (")))" )
1687+ }
1688+ }
1689+ out .WriteString (")" )
1690+ } else {
1691+ // No arguments - just inline the body
1692+ for i , stmt := range funcLit .Body .List {
1693+ if i > 0 {
1694+ out .WriteString ("\n " )
1695+ }
1696+ TranspileStatementSimple (out , stmt , funcLit .Type , fileSet )
1697+ out .WriteString (";" )
1698+ }
1699+ }
1700+ } else {
1701+ // Regular function call
1702+ TranspileCall (out , s .Call )
1703+ }
1704+
1705+ out .WriteString (";\n " )
1706+ out .WriteString (" })" )
1707+ out .WriteString (";" )
1708+
1709+ // Restore previous capture renames
1710+ currentCaptureRenames = oldCaptureRenames
1711+
15871712 default :
15881713 out .WriteString ("// TODO: Unhandled statement type: " + strings .TrimPrefix (fmt .Sprintf ("%T" , s ), "*ast." ))
15891714 }
0 commit comments