Repository navigation
Description
Found by a hand check of release/2.3.1 @ dbdd44e (unchanged at d573eef), measured in a scratch consumer that references the analyzer as Generators.Probes does.
Package
CodoMetis.TypeKit.Analyzers
Version
2.3.0 (the same code in v2.3.0), and release/2.3.1 @ dbdd44e
How does it fail?
Silently. An array of default value objects is created with no warning
Problem
DefaultFilledCollectionAnalyzer.AnalyzeInvocation (src/CodoMetis.TypeKit.Analyzers/DefaultFilledCollectionAnalyzer.cs:79) looks only at a generic call with one type argument, and of those only at GC.AllocateArray, GC.AllocateUninitializedArray (:38) and Array.Resize. The README defines CMTK0005 as "An array or span of a value object ... created with a length, so every slot starts as default", which these calls are too.
Scenario
public readonly partial record struct Plain : IValue<int>;
new Plain[3]; // CMTK0005
Array.Resize(ref a, 3); // CMTK0005
Array.CreateInstance(typeof(Plain), 3); // nothing
Array.CreateInstance(typeof(Plain), 2, 2); // nothing
Array.CreateInstanceFromArrayType(typeof(Plain[]), 3); // nothing
ArrayPool<Plain>.Shared.Rent(3); // nothing; a fresh array from the pool is all defaultChange
Report Array.CreateInstance and Array.CreateInstanceFromArrayType when the element type is a constant typeof of such a type (the element of typeof(T[]) for the second), and ArrayPool<T>.Rent like the generic allocators. A constant length of zero in any dimension stays unreported (#227). A Warning reporting more needs no exception to decision 34.
Test
CMTK0005 rows for each call above, a zero-length control for each, a typeof that is not constant (a Type variable) unreported, and ArrayPool<T>.Create().Rent; reverted per verify-the-guard. Input class (AIS): an expression that creates an array of a value object, by the API that creates it, across TypeArgumentKinds for Rent's T.
Environment
.NET SDK 10.0.4xx; any consumer.
Activity
CaffeinatedCoder commentedon Oct 31, 2026
Fixed in #235, stacked on #233 (same file). As proposed:
Array.CreateInstance(every overload with a length,params long[]and lower bounds included) andCreateInstanceFromArrayTypewhen atypeofnames the element,RentonArrayPool<T>or an override; aTypevariable,GetType()andtypeof(Plain?)stay silent, and a constant zero in any dimension stays silent (#227).Rent'sTand thetypeofelement run acrossTypeArgumentKinds(79 kinds), each reporting exactly whereGC.AllocateArray<K>does.CaffeinatedCoder commentedon Oct 31, 2026
Fixed by #235, merged into
release/2.3.1.