Qualify special string typedefs (PCWSTR) to Windows.Win32.Foundation for non-Win32 metadata - #1786
Merged
Jevan Saks (jevansaks) merged 1 commit intoAug 14, 2026
Conversation
in
Jevan Saks (jevansaks)
force-pushed
the
user/jevansa/pcwstr-array-friendly-overload
branch
from
August 13, 2026 21:53
8b2cbfd to
1276962
Compare
Jevan Saks (jevansaks)
marked this pull request as ready for review
August 13, 2026 22:46
Jevan Saks (jevansaks)
force-pushed
the
user/jevansa/pcwstr-array-friendly-overload
branch
from
August 13, 2026 23:07
1276962 to
1df91d2
Compare
Manodasan Wignarajah (manodasanW)
approved these changes
Aug 13, 2026
…for non-Win32 metadata When CsWin32 projects a non-Windows.Win32 metadata assembly with a single Generator (no SuperGenerator, with the Windows.Win32 projection provided as a referenced assembly -- the OSClient build configuration), references to the special string typedefs (PCWSTR, PCSTR, ...) were qualified under the consuming assembly's own root namespace (e.g. OSClient.Foundation.PCWSTR), which does not exist and fails to compile with CS0234. Two places produced the mis-qualification for a `[Const] PWSTR*` parameter (projected as PCWSTR*): 1. RequestSpecialTypeDefStruct built the fully-qualified name from this.Namespace (the consuming assembly's common namespace). For non-Win32 metadata the type lives in Windows.Win32.Foundation (provided by a delegated generator or a referenced assembly), so qualify it there. This covers the no-count case (in PCWSTR), the fixed block, and the extern/interface method signature. 2. The ReadOnlySpan<string> friendly overload generated for a counted array ([Const, NativeArrayInfo] PWSTR*) hard-coded the ArrayPool<PCWSTR> element type to the winmdroot alias. Qualify it with Win32NamespacePrefix to match how the parameter type is qualified. Both changes are no-ops for the Windows.Win32 SDK itself (byte-identical output). Adds SelfContained.winmd, a single-generator P/Invoke fixture reproducing the OSClient configuration, with a theory covering both the no-count (Foo) and counted (Bar) projections. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Jevan Saks (jevansaks)
force-pushed
the
user/jevansa/pcwstr-array-friendly-overload
branch
from
August 14, 2026 00:25
1df91d2 to
b68f2df
Compare
Jevan Saks (jevansaks)
marked this pull request as draft
August 14, 2026 00:26
Jevan Saks (jevansaks)
marked this pull request as ready for review
August 14, 2026 17:41
Jevan Saks (jevansaks)
enabled auto-merge (squash)
August 14, 2026 17:41
Manodasan Wignarajah (manodasanW)
approved these changes
Aug 14, 2026
Jevan Saks (jevansaks)
deleted the
user/jevansa/pcwstr-array-friendly-overload
branch
August 14, 2026 17:58
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When generating C# from a non-
Windows.Win32metadata assembly (e.g. a winmd built from a UDK header, common namespaceOSClient), a parameter typed_In_reads_opt_(count) LPCWSTR*/[Const] PWSTR*(projected asPCWSTR*) fails to compile:CsWin32 qualified the special string typedef
PCWSTRunder the consuming assembly's own root namespace —OSClient.Foundation.PCWSTR— which does not exist. It should referenceglobal::Windows.Win32.Foundation.PCWSTR, where the type actually lives.Root cause
This reproduces only in the configuration OSClient uses: a single
Generator(noSuperGenerator), with theWindows.Win32projection supplied as a referenced assembly rather than a sibling generator. In that setup there is noWindows.Win32generator to delegate special-typedef emission to, so the special typedefs must be referenced underWindows.Win32.Foundation.Two places built the wrong qualification for the projected
PCWSTR*:Generator.RequestSpecialTypeDefStructcomputed the fully-qualified name fromthis.Namespace(the consuming assembly's common namespace →OSClient). The delegation that fixes this up only runs when aSuperGeneratoris present, so in the single-generator case the name stayedOSClient.Foundation.PCWSTR. This is the element type used by the extern/interface signature, thein PCWSTRfriendly overload, and thefixedblock. This is the primary CS0234.Generator.FriendlyOverloads.PCWSTRTypeSyntax(used only by theReadOnlySpan<string>friendly overload generated for a counted array,[Const, NativeArrayInfo] PWSTR*) hard-coded theArrayPool<PCWSTR>element type to thewinmdrootalias, which for non-Win32 metadata points at the wrong assembly.Fix
RequestSpecialTypeDefStructnow qualifies special typedefs underWindows.Win32.Foundationfor non-Win32 metadata (rootNamespace = IsWin32Sdk ? this.Namespace : "Windows.Win32").PCWSTRTypeSyntaxis now an instance member usingWin32NamespacePrefix, matching how the parameter type itself is qualified.Both changes are no-ops for the
Windows.Win32SDK itself (byte-identical output — verified byEverything_NoFriendlyOverloads).Tests
Adds
SelfContained.winmd, a single-generator P/Invoke fixture that faithfully reproduces the OSClient configuration, and a theorySingleGeneratorQualifiesSpecialTypeDefToWin32Namespacecovering both projections:Foo—[Const] PWSTR*with no count →in PCWSTR(exercises fix Add unit tests for code generation #1).Bar—[Const, NativeArrayInfo] PWSTR*→ReadOnlySpan<string>+ArrayPool<PCWSTR>(exercises fix Add unit tests for code generation #1 and Consume metadata as dll #2).Both fail with
CS0234on the pre-fix generator and compile cleanly with the fix.Fixes the CsWin32 sanity-check failure in OSClient PR 16236433.