Context
Follow-up to #12159.
The trimmable typemap currently uses ValueTypeFactory.SupportedValueTypeFactories as a fixed allowlist that statically roots the exact NativeAOT shapes needed for:
- managed value-type arrays;
JavaList<T> and JavaCollection<T>;
- mixed reference/value
JavaDictionary<TKey,TValue> shapes;
- the full supported value/value dictionary cross-product.
#12159 extends the list with DateTime, DateTimeOffset, and TimeSpan (plus nullable forms), but arbitrary value types still cannot safely fall back to MakeGenericType() under NativeAOT.
Problem
Growing a framework-owned allowlist does not scale:
- every supported type adds more statically rooted list, collection, and array shapes;
- value/value dictionaries currently root a Cartesian product, so cost grows quadratically;
- applications cannot opt in enums or their own structs;
- other common BCL candidates remain (
decimal, Guid, DateOnly, TimeOnly, Half, unsigned/native-sized integers, Int128/UInt128, and enums);
- being AOT-rootable is distinct from having built-in JNI primitive marshaling semantics.
Investigate
- Generate roots from the closed generic container shapes actually used by the application.
- Provide an opt-in registration or source-generation mechanism for additional value types.
- Root only used dictionary key/value pairs instead of the full allowlist cross-product.
- Define behavior for nullable types, enums, and user-defined structs.
- Keep diagnostics explicit when a value-type shape was not rooted.
- Measure NativeAOT build-time and binary-size impact against the fixed allowlist.
Completion criteria
Produce and validate a design that supports app-specific value types without runtime reflection and without requiring an indefinitely growing, quadratic framework allowlist.
Context
Follow-up to #12159.
The trimmable typemap currently uses
ValueTypeFactory.SupportedValueTypeFactoriesas a fixed allowlist that statically roots the exact NativeAOT shapes needed for:JavaList<T>andJavaCollection<T>;JavaDictionary<TKey,TValue>shapes;#12159 extends the list with
DateTime,DateTimeOffset, andTimeSpan(plus nullable forms), but arbitrary value types still cannot safely fall back toMakeGenericType()under NativeAOT.Problem
Growing a framework-owned allowlist does not scale:
decimal,Guid,DateOnly,TimeOnly,Half, unsigned/native-sized integers,Int128/UInt128, and enums);Investigate
Completion criteria
Produce and validate a design that supports app-specific value types without runtime reflection and without requiring an indefinitely growing, quadratic framework allowlist.