Repository navigation
Share interop discovery member reservations across a module - #2641
Merged
Manodasan Wignarajah (manodasanW) merged 6 commits intoNov 5, 2026
Merged
Manodasan Wignarajah (manodasanW) merged 6 commits into
Manodasan Wignarajah (manodasanW) merged 6 commits into
Conversation
Replace the lexical-family rule for sharing the active member scan reservation with a module-scoped rule. Ordinary member transitions at an unchanged, fully closed substitution within the same resolved module no longer consume additional reservations, which avoids exhausting the 1024 reservation budget when generic helpers in the same module (e.g. mocking libraries) expand across unrelated types. Members are still scanned, and visited-key deduplication, depth, complexity and the reservation budget are unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Rename the lexical family tests to member reservation tests, cover sharing across unrelated types within a module and rejection across modules, and update the static dispatch limit expectation to reflect the shared reservation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Update the interop generator skill to describe the module-scoped reservation sharing policy. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sergio Pedri (Sergio0694)
requested a review
from Manodasan Wignarajah (manodasanW)
November 3, 2026 22:18
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Cap the transitions that share an active module scan's reservation at 4096 per enumeration. Once exhausted, further candidates are charged against the normal transitive budget, so a pathologically wide module still reaches CSWINRTINTEROPGEN0106. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sergio Pedri (Sergio0694)
enabled auto-merge (squash)
November 4, 2026 22:07
Manodasan Wignarajah (manodasanW)
approved these changes
Nov 5, 2026
Manodasan Wignarajah (manodasanW)
disabled auto-merge
November 5, 2026 03:12
Manodasan Wignarajah (manodasanW)
merged commit Nov 5, 2026
eb2518b
into
staging/3.0
20 checks passed
Manodasan Wignarajah (manodasanW)
deleted the
user/sergiopedri/interop-discovery-limits
branch
November 5, 2026 03:13
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.
Summary
Share the active member scan's reservation across a whole module (instead of a lexical family) in the interop generator's generic discovery, so that large test projects no longer hit
CSWINRTINTEROPGEN0106while the existing recursion guards remain in place.Motivation
Replaying the Store test-project debug repros (Desktop, BusinessLogic, Purchase) produced
CSWINRTINTEROPGEN0106warnings (Desktop: 2, BusinessLogic: 2, Purchase: 0). Debug logs showed the 1024 reservation budget being consumed by generic helper expansion spread across many unrelated types in the same module (mocking libraries such as Moq). The existing lexical-family rule from #2619 only applied to a type and its nested definitions, so it did not cover these transitions even though they stay within a single, finite module at an unchanged closed substitution.With this change, ordinary member transitions at an unchanged, fully closed substitution within the same resolved module share the active scan's reservation. This is an accounting rule only: members are still scanned and considered for marshalling. Changing arguments or crossing into another module still costs a reservation, and the visited-key deduplication, FIFO ordering, depth limit (32), signature complexity limit (256) and the 1024 reservation budget are all unchanged, so genuine recursion is still bounded. The 1024 limit is not increased.
Shared transitions are not charged, so they get their own allowance of 4096 per enumeration. Once it is exhausted, further candidates are charged against the normal 1024 budget, so a pathologically wide module still reaches
CSWINRTINTEROPGEN0106. The highest shared count measured on the Store repros was about 1600.Validation on the three repros: all
0106warnings disappear and the generatedWinRT.Interop.dllis byte-identical to the baseline (re-verified with the cap). End-to-end benchmarking over 264 accepted runs (baseline, this change, an increased-limit variant, and a baseline-copy control) showed no measurable performance impact beyond run-to-run noise, with memory within ±2% in 17 of 18 cells.Changes
src/WinRT.Interop.Generator/Discovery/TypeSignatureDiscovery.MemberScanContext.cs: removeGetLexicalFamilyand the family identity;MemberScanContextnow carries the declaringModuleDefinitionand compares module identity when deciding whether a transition can share the reservation. Sharing consumes a separate allowance (MaxSharedReservations, 4096) and falls back to normal charging once it is exhausted.src/WinRT.Interop.Generator/Discovery/TypeSignatureDiscovery.Members.csandsrc/WinRT.Interop.Generator/Discovery/TypeSignatureDiscovery.Worklist.cs: create the member scan context from, and pass toCanShareMemberReservation, the declaring module instead of the declaring type, and update the related comments.src/WinRT.Interop.Generator/Discovery/TypeSignatureDiscovery.cs: addMaxSharedReservationsand its counter, and update theMaxTransitiveTypesdoc comment.src/Tests/ProjectionWriterTest/Test_InteropGenericDiscovery.MemberReservations.cs(renamed from...LexicalFamilies.cs): tests now cover sharing across unrelated types within a module, rejection across modules, changed-argument limits, open-context behavior and the shared allowance bound.src/Tests/ProjectionWriterTest/Test_InteropGenericDiscovery.StaticDispatchLimits.cs: update the expectedNodecount (1022 to 1023), sinceRequired<string>now shares the instance default's reservation..github/skills/interop-generator/SKILL.md: document the module-scoped sharing policy and the shared allowance.