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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions