You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
No EntryPoint placement builds in every target: C# rejects it at file/namespace scope, C++/Rust lose main inside a namespace, and Rust/Go drop it silently inside a class #128
EntryPoint exists so that "the name, the parameter spelling and the wiring that runs it are the generator's business" (Coder/Ast/EntryPoint.cs). In practice each generator writes it exactly where it sits in the AST, and no placement produces a runnable program in every target:
Where the EntryPoint is
C#
C++
C
Rust
Go
SourceFile member
public static int Main() at top level: CS0106
ok
ok
ok
ok
NamespaceDeclaration("App") member
CS0116 (a namespace can't contain a method)
App::main: undefined reference to main at link
ok
pub mod App { fn main() }: E0601 main function not found
ok
ClassDeclaration("Program") member
ok
member Program::main: undefined reference to main
function body inside a typedef struct: syntax error
dropped silently (pub struct Program {})
dropped silently (type Program struct{})
C# writes a bare public static … Main in every position (CSharpGenerator.GenerateEntryPoint, Coder/Languages/CSharpGenerator.cs:926-943). EntryPointTests.Schema_TakesAnEntryPointAsAMemberButNotAsAStatement accepts it as a class member on purpose, "which is where C# puts Main", but that is exactly the position C++, C, Rust and Go can't use.
Repro (confirmed with dotnet build / g++ / rustc)
EntryPointmain=new(){ReturnsExitCode=true};main.Body.Add(newReturnStatement(newLiteralExpression<int>(0)));SourceFilefile=new("app");NamespaceDeclarationns=new("App");ns.Members.Add(main);file.Members.Add(ns);// C#: namespace App { public static int Main() { return 0; } } -> CS0116// C++: namespace App { int main() { return 0; } } -> ld: undefined reference to `main'// Rust: pub mod App { ... fn main() {...} } -> error[E0601]
Why it matters
A caller who wants one AST to produce a runnable program in every language has no placement that works. Two of the failures (Rust and Go inside a class) produce no error or note at all: the program just has no entry point.
Suggested fix / acceptance criteria
C#: an EntryPoint outside a type is wrapped in public static class Program { … }. Inside a type it stays as it is today.
C++ and Rust: an EntryPoint inside a namespace or module is written at file scope, where the toolchain looks for it. For Rust, a root fn main can call App::run.
C, C++, Rust and Go: an EntryPoint inside a class is written at file scope, or at least reported with WriteInexpressible, and never dropped silently.
At least one placement (e.g. inside a NamespaceDeclaration) is compiled and linked by every language's compile test.
Priority: Medium. No single AST placement gives a runnable program in every target, and Rust and Go drop the entry point silently when it sits inside a class. A caller who targets one language can still pick a placement that works for that language, so this is not High.
Area:EntryPoint lowering across CSharpGenerator, CppGenerator, CGenerator, RustGenerator and GoGenerator
Suggested assignment: Coder generators maintainer. This is a cross-language change, so one owner should decide the canonical placement.
Duplicates / in progress: none found; no open PR covers it
Note: The two silent drops (Rust and Go inside a class) are the most urgent part. A WriteInexpressible note is a small fix that could ship ahead of the full relocation work.
Activity
matt-edmondson commentedon Sep 29, 2026
Triage
EntryPointlowering acrossCSharpGenerator,CppGenerator,CGenerator,RustGeneratorandGoGenerator+silently becomes unary+and unary/conversion operators fail with CS1019 #126 and C#: modifiers are emitted where C# forbids them:readonlyon class/interface members (CS0106),public ~T()(CS0106), abstract member in a non-abstract class (CS0513) #127 are C# output correctness too. The C# compile test proposed in C#: member operators lose their implicit operand, so binary+silently becomes unary+and unary/conversion operators fail with CS1019 #126 would also cover the C# column here.WriteInexpressiblenote is a small fix that could ship ahead of the full relocation work.Generated by Claude Code