Skip to content

fix: invoke static interface mapping methods on the interface type - #2464

Open
trejjam wants to merge 4 commits into
riok:mainfrom
trejjam:fix/static-interface-mapping-receiver
Open

trejjam wants to merge 4 commits into
riok:mainfrom
trejjam:fix/static-interface-mapping-receiver

Conversation

@trejjam

@trejjam trejjam commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

fix: invoke static interface mapping methods on the interface type

Description

When a mapper (or an external mapper used via [UseMapper] / [UseStaticMapper]) implements an interface that declares a static method, Mapperly picks the method up as a user-implemented mapping. It then calls it through a cast instance, which does not compile:

public interface IMapperBase { public static string MapValue(string value) => value.ToUpper(); }
[Mapper] public partial class Mapper : IMapperBase { public partial B Map(A source); }
// before
target.Value = ((global::IMapperBase)this).MapValue(source.Value); // CS0176
// after
target.Value = global::IMapperBase.MapValue(source.Value);

The same cast was emitted for existing-target (void) mappings, non-inlinable queryable projections, static partial mapping methods (CS0026, this in a static method), [UseMapper] members (CS0176) and [UseStaticMapper] types (CS0119, ((global::IOther)global::Other)).

Four commits:

  1. fix: invoke static interface mapping methods on the interface type: UserImplementedMethodMapping and UserImplementedExistingTargetMethodMapping call static interface methods on the fully qualified interface type instead of casting the receiver. Output for all other mappings is unchanged.
  2. fix: ignore static abstract and static virtual interface mapping methods: these members can only be accessed through a type parameter (CS8926), so global::IBaseMapper<global::Mapper>.BaseMapping(...) does not compile either. UserMethodMappingExtractor now treats them as invalid user mappings: ignored, or RMG001 when marked with [UserMapping] (unless Ignore = true). An implicit implementation in the mapper (public static D BaseMapping(C source)) is still discovered and used as before.
  3. fix: honor ignored user mappings before reporting unsupported signatures: a method marked with [UserMapping(Ignore = true)] is skipped before its signature is validated, so an ignored static abstract member (or any other ignored method with an unsupported signature) no longer reports RMG001.
  4. docs: document user-implemented mapping methods in base classes and interfaces: adds a short section to the user-implemented methods docs.

The change is covered by unit tests that assert the generated code. No integration tests were added.

Checklist

  • I did not use AI tools to generate this PR, or I have manually verified that the code is correct, optimal, and follows the project guidelines and architecture
  • I understand that low-quality, AI-generated PRs will be closed immediately without further explanation
  • The existing code style is followed
  • The commit message follows our guidelines
  • Performed a self-review of my code
  • Hard-to-understand areas of my code are commented
  • The documentation is updated (as applicable)
  • Unit tests are added/updated
  • Integration tests are added/updated (as applicable, especially if feature/bug depends on roslyn or framework version in use)

Static interface methods discovered as user-implemented mappings were invoked through a cast instance, e.g. ((global::IMapperBase)this).MapValue(x), which does not compile (CS0176, CS0026 in static mapping methods, CS0119 for static external mappers). Invoke them on the interface type instead: global::IMapperBase.MapValue(x).
Static abstract and static virtual interface members can only be accessed through a type parameter (CS8926), so they cannot be used as user-implemented mappings. Ignore them, reporting RMG001 if they are marked with UserMappingAttribute.
A method marked with [UserMapping(Ignore = true)] is now skipped even if its signature is unsupported, e.g. a static abstract interface member, instead of reporting RMG001.
@trejjam

trejjam commented Oct 17, 2026

Copy link
Copy Markdown
Contributor Author

This is a niche issue. I didn't find it in my code. An agent did while I was working on the #2240 . I did not find it super important; if you do not want to spend time on it, just close it.

I reviewed the code, and it seems correct.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant