Skip to content

Marker interfaces should be partial to support user extensions #647

@tompipe

Description

@tompipe

Problem

When --generate-marker-interfaces is enabled, generated nested interfaces are not marked as partial, preventing users from manually extending them with custom implementations.

Simple Example

C++ input:

struct IFoo
{
    virtual void Method1() = 0;
    virtual void Method2() = 0;
};

Generated with --generate-marker-interfaces:

public unsafe partial struct IFoo : IFoo.Interface
{
    public interface Interface  // NOT partial - users cannot extend
    {
        void Method1();
        void Method2();
    }
}

User tries to manually add a custom helper method:

// User's manually-written code in a separate file
public partial struct IFoo
{
    public partial interface Interface  // ✗ Error: no partial declaration exists
    {
        void CallBoth();  // User wants to add this to the interface contract
    }
    
    // User's manual implementation
    public void CallBoth() 
    {
        Method1();
        Method2();
    }
}

Generic constraint breaks:

void Process<T>(T foo) where T : unmanaged, IFoo.Interface
{
    foo.CallBoth();  // ✗ Error: Interface doesn't contain CallBoth
}

Solution

Change CSharpOutputBuilder.VisitDecl.cs:829:

WriteIndented("public partial interface Interface");

This allows users to manually extend the interface with custom methods while maintaining backward compatibility (adding partial is non-breaking).

I have a fix ready in my fork.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions