Skip to content

Fix COM interface classification across metadata assemblies - #1870

Draft
Jevan Saks (jevansaks) wants to merge 2 commits into
mainfrom
jevansaks-external-com-interfaces
Draft

Jevan Saks (jevansaks) wants to merge 2 commits into
mainfrom
jevansaks-external-com-interfaces

Conversation

@jevansaks

@jevansaks Jevan Saks (jevansaks) commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

Summary

Resolve interface references through the existing qualified metadata resolver, using the defining generator and reader for both interface classification and COM ancestry. This preserves native interface pointers when a field's COM interface moves to another input WinMD.

For example, DML_BUFFER_BINDING.Buffer must remain ID3D12Resource* with allowMarshaling: false when Direct3D 12 interfaces are supplied by SDK-owned metadata instead of Windows metadata. Previously the external reference was classified as a non-interface and projected by value, failing a pointer assignment with CS0029.

The reader-ownership correction also covers marshaled interface arrays, transitive external non-COM ancestry, and inherited method inspection for COM callable wrappers. It does not change public APIs or production metadata inputs.

Regression coverage

Two small authored IL/WinMD fixtures use reciprocal assembly references. They cover local and external COM fields, marshaled COM arrays, native double pointers, and transitive external non-COM ancestry.

All three modes are exercised: native pointers (allowMarshaling: false), runtime marshaling, and AOT-compatible COM source generation. GUID-bearing interfaces allow the tests to run the .NET SDK's actual COM source generators on the projected code, check generator diagnostics, and compile/emit the completed output. Source-generated binding fields accept the native IExternalCom_unmanaged* projection; runtime-marshaled fields accept the managed interface.

Validation

  • All 154 cases in COMTests and MultiMetadataTests pass, including six reciprocal-fixture cases across the three modes.
  • Both generator legs build without warnings.
  • The real minimal DML_BUFFER_BINDING consumer passes with baseline Windows metadata using CsWin32 0.3.367, and fails with CS0029 using the reciprocal Windows/D3D metadata pair.
  • The unchanged native consumer builds with zero warnings/errors against baseline Windows metadata and the real reciprocal pair using the rebuilt generator. The reciprocal pair also passes using the rebuilt Roslyn 4.11 leg.
  • The real reciprocal Windows/D3D consumer requesting DML_BUFFER_BINDING and DMLCreateDevice builds with zero warnings/errors in native, runtime-marshaled, and COM source-generated modes using the rebuilt build task. The source-generated case runs the SDK COM generator with IsAotCompatible and DisableRuntimeMarshalling enabled; Buffer accepts ID3D12Resource_unmanaged*.

This fixes a projection prerequisite for moving Direct3D 12 metadata ownership. Enabling Windows metadata removal still requires published fixed CsWin32 and WinmdGenerator releases and the coordinated SDK/package updates; this PR does not enable that removal.

Resolve interface definitions and COM ancestry with their owning generator and metadata reader. Add reciprocal metadata fixtures covering native pointers, marshaled arrays, and non-COM ancestry.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Run the SDK COM source generator on GUID-bearing reciprocal fixtures and compile its output. Fix inherited CCW property inspection to use the method-owning metadata reader.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

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