Generate CCW metadata for IReadOnlyDictionary and dictionary key/value collections - #2538
Open
Sergio Pedri (Sergio0694) wants to merge 1 commit into
Open
Conversation
…e collections
The AOT source generator special cased IDictionary<K, V> when gathering the
adapter types a dictionary CCW hands out, but had no branch for
IReadOnlyDictionary<K, V>. Since it is projected as IMapView<K, V>, whose Split
method hands out ConstantSplittableMap<K, V> instances and whose iteration hands
out KeyValuePair<K, V> values, a type implementing only the read only interface
was missing both entries.
Additionally, a dictionary hands out its Keys and Values through concrete
collection types (eg. Dictionary<K, V>.ValueCollection) that never appear by
name in user code, so nothing discovered them. Binding to them (eg.
"{x:Bind ViewModel.Dictionary.Values}") then crashed under NativeAOT because the
marshaled collection had no CCW vtable. Those collection types and their
enumerator adapters are now registered through the dictionary itself.
Fixes #2537
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: aa4f63a9-8c06-4dbb-9eae-a788a38c6262
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Sergio Pedri (Sergio0694)
requested a review
from Manodasan Wignarajah (manodasanW)
August 27, 2026 12:43
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.
Fixes #2537
Problem
Binding to the values of a dictionary crashes under NativeAOT:
There were two gaps in
AddVtableAdapterTypeForKnownInterfacein the AOT source generator:IReadOnlyDictionary<K, V>was never handled. The method special casedIDictionary<K, V>(registeringReadOnlyDictionary<K, V>,KeyValuePair<K, V>andConstantSplittableMap<K, V>), but had no branch forIReadOnlyDictionary<K, V>. That interface is projected asIMapView<K, V>, whoseSplitmethod hands outConstantSplittableMap<K, V>instances and whose iteration hands outKeyValuePair<K, V>values, so a type implementing only the read only interface was missing both CCW entries.KeysandValueswere never discovered. A dictionary hands those out through concrete collection types (e.g.Dictionary<K, V>.ValueCollection) which never appear by name in user code, so nothing in the generator ever gathered them. Marshaling one to XAML then found no vtable in the CCW lookup table, so the resulting CCW had noIBindableIterableand the bind crashed. This is what the repro in the issue hits:Dictionary<int, string>itself was registered, butDictionary<int, string>.ValueCollectionwas not.Fix
IReadOnlyDictionary<K, V>branch registeringKeyValuePair<K, V>andConstantSplittableMap<K, V>.Keys/Valuesproperties and register a vtable for the concrete collection type behind them, along with theToAbiEnumeratorAdapter<T>needed to enumerate it. Interface typedKeys/Valuesare skipped, since there is no concrete type to discover in that case.The lookup table is keyed by string, so this adds table entries only — no new type references in generated code.
Testing
AotOptimizerTests.cs, each verified to fail without the generator change and pass with it. Full suite: 74/74 passing.CollectionsAOT functional test that assignsdictionary.Keys/dictionary.ValuestoClass.BindableIterableProperty(typedMicrosoft.UI.Xaml.Interop.IBindableIterable), which fails to marshal unless the collection CCW exposesIBindableIterable.