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
Interface default-method bodies are lost in Go and C and missing from JavaScript implementers (Go output fails with "missing method") #177
A method with a body declared on an interface (a default method) is handled correctly by three targets:
C++ writes it as a non-pure virtual.
Rust writes it as a trait default.
Python gets it through multiple inheritance.
Three other targets lose it:
Go. Inside an interface, GenerateFunction writes only the signature and returns (GoGenerator.cs L895-L900). The body is silently dropped, but the method stays in the interface's method set. A struct that lists the interface gets var _ Greeter = (*En)(nil), which then fails to compile.
C. An interface becomes a struct of function pointers. GenerateFunctionPointer writes only the pointer, and an interface has no function list, so the body appears nowhere in the file, not even as a note.
JavaScript. An implemented interface is written only as // implements Greeter (JavaScriptGenerator.cs ~L376-L381). The implementing class never gets the default, so calling it throws.
Repro
varg=newClassDeclaration("Greeter"){Kind=TypeDeclarationKind.Interface};g.Members.Add(newFunctionDeclaration("Name"){ReturnType="str",IsAbstract=true,IsReadOnly=true});varhello=newFunctionDeclaration("Hello"){ReturnType="int",IsReadOnly=true};hello.Body.Add(newReturnStatement(newLiteralExpression<int>(42)));g.Members.Add(hello);varen=newClassDeclaration("En"){Kind=TypeDeclarationKind.Struct};en.Interfaces.Add("Greeter");// En implements Name only
Go (go vet): cannot use (*En)(nil) ... *En does not implement Greeter (missing method Hello)
JS (node): new En().Hello() throws TypeError: (intermediate value).Hello is not a function
C: the output contains int (*Hello)(const void* self);, and return 42 appears nowhere.
Suggested fix
C: write the body as a free function after the struct, int Greeter_Hello(const void* self) { return 42; }, so an implementation can point its slot at it.
Go: write the default as a function over the interface, func GreeterHello(self Greeter) int. Then pick one of:
(a) on each struct in the document that lists the interface without defining the method, synthesise a forwarder such as func (self En) Hello() int { return GreeterHello(self) };
(b) leave the method out of the interface's method set and write a note.
Either way, the output must compile and nothing may be dropped silently.
JS: give an implementing class that doesn't define the method a forwarding method, or copy the default into it.
Priority: High. When an interface has a default method, Go output doesn't compile and C drops the body silently. JavaScript implementers throw at runtime. Nothing in the generated output tells the user the code was lost.
Area:Coder/Languages: interface member lowering in GoGenerator, CGenerator and JavaScriptGenerator
Duplicates / in progress: Not a duplicate, and no open PR covers it.
Next step: Start with Go, because its output fails to build. Emit the default as a free function over the interface, plus a forwarder on each implementer that lacks the method. Then add the C free function and the JS forwarder, with compile and run tests for each target.
Activity
matt-edmondson commentedon Oct 6, 2026
Triage
Coder/Languages: interface member lowering inGoGenerator,CGeneratorandJavaScriptGeneratorGenerated by Claude Code