Skip to content

CMTK0005 misses an array created by Array.CreateInstance, CreateInstanceFromArrayType or ArrayPool<T>.Rent #228

Closed

Description

@CaffeinatedCoder

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 default

Change

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

  1. added this to the 2.3.1 milestone on Oct 31, 2026
  2. added
    bugSomething isn't working
    silentCompiles or answers and does less than it appears to
    severity/lowCosmetic, message or documentation-level difference
    package/analyzersAffects CodoMetis.TypeKit.Analyzers
    area/value-objectsValue-object contracts and what the aspects generate for them
    on Oct 31, 2026
  3. CaffeinatedCoder commented on Oct 31, 2026

    @CaffeinatedCoder
    OwnerAuthor

    Fixed in #235, stacked on #233 (same file). As proposed: Array.CreateInstance (every overload with a length, params long[] and lower bounds included) and CreateInstanceFromArrayType when a typeof names the element, Rent on ArrayPool<T> or an override; a Type variable, GetType() and typeof(Plain?) stay silent, and a constant zero in any dimension stays silent (#227). Rent's T and the typeof element run across TypeArgumentKinds (79 kinds), each reporting exactly where GC.AllocateArray<K> does.

  4. CaffeinatedCoder commented on Oct 31, 2026

    @CaffeinatedCoder
    OwnerAuthor

    Fixed by #235, merged into release/2.3.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/value-objectsValue-object contracts and what the aspects generate for thembugSomething isn't workingpackage/analyzersAffects CodoMetis.TypeKit.Analyzersseverity/lowCosmetic, message or documentation-level differencesilentCompiles or answers and does less than it appears to

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions