Skip to content

fix: CMTK0005 reports Array.CreateInstance, CreateInstanceFromArrayType and ArrayPool<T>.Rent - #235

Open
CaffeinatedCoder wants to merge 3 commits into
release/2.3.1from
fix/array-factories-reported-2-3-1
Open

CaffeinatedCoder wants to merge 3 commits into
release/2.3.1from
fix/array-factories-reported-2-3-1

Conversation

@CaffeinatedCoder

Copy link
Copy Markdown
Owner

Closes #228

Stacked on #233 (#227), which changes the same file: merge #233 first, then retarget this to release/2.3.1.

Problem

DefaultFilledCollectionAnalyzer.AnalyzeInvocation looked only at generic calls with one type argument (GC.AllocateArray, GC.AllocateUninitializedArray, Array.Resize). Array.CreateInstance(typeof(Plain), 3) (one to three dimensions, params int[], params long[], with lower bounds), Array.CreateInstanceFromArrayType(typeof(Plain[]), 3) and ArrayPool<Plain>.Shared.Rent(3) create the same default slots and got nothing.

Change

  • DefaultFilledCollectionAnalyzer.cs: the two factories are reported when a typeof names the element (for CreateInstanceFromArrayType, the element of the array type); a Type in a variable stays silent. Rent is recognised on ArrayPool<T> or an override of it, T the element. One Lengths reads every int/long length parameter and the elements of a params or written-out array of them, never lowerBounds, so CMTK0005 reports a multidimensional array with a zero dimension, such as new Plain[0, 2], which holds no element #227's rule holds for every form: a constant zero in any dimension stays silent.
  • Analyzers README: the CMTK0005 section names the new forms and says a Type variable isn't reported; claim K05-a-factory-given-a-typeof holds it.
  • CHANGELOG: a line under 2.3.1's Changed, since a warnings-as-errors build can now fail. A Warning that reports more needs no exception to decision 34.

Tests

  • The_array_factories_and_the_pool_report: every CreateInstance/CreateInstanceFromArrayType overload that takes a length, Rent on the shared pool, on ArrayPool<T>.Create() and on a derived pool, an Option<int> element and a typeof(T) of a constrained parameter.
  • The_array_factories_with_a_zero_length_or_an_unknown_type_stay_silent: a zero-length control for each form (in each dimension, in a params list, beside lower bounds, long), a Type variable, GetType(), typeof(Plain?), typeof(int), typeof(Plain[]), ArrayPool<int> and Activator.CreateInstance.
  • The_factories_judge_each_kind_as_the_generic_allocator_does: Rent's T and the typeof element across TypeArgumentKinds (79 kinds); each reports exactly where GC.AllocateArray<K> does, with a value-object struct as the positive control and a compile-error check so no row passes vacuously.
  • Reverting the source fails the forms row and the three reporting kinds. Seeds: dropping the zero check fails the three zero rows; reading the lower bounds as lengths fails the forms row; skipping an array of lengths fails the silent row.
  • Analyzers (3,772), Conventions (2,016), Samples (150) and Oracles (51) green locally through tools/BuildVerdict.

CollectionsMarshal.SetCount is #229 (2.4.0) and out of scope.

🤖 Generated with Claude Code

…pe and ArrayPool<T>.Rent

AnalyzeInvocation looked only at generic calls with one type argument,
GC.AllocateArray, GC.AllocateUninitializedArray and Array.Resize. The
README defines CMTK0005 as an array of a value object created with a
length, which Array.CreateInstance(typeof(Plain), 3) in each overload,
CreateInstanceFromArrayType(typeof(Plain[]), 3) and
ArrayPool<Plain>.Shared.Rent(3) are too; none was reported.

The two factories are reported when a typeof names the element (the
element of the array type for the second); a Type in a variable could be
anything and stays silent. Rent is recognised on ArrayPool<T> or an
override of it, its T the element. The lengths are read from every int
or long parameter and the elements of a params or written-out array of
them, never the lower bounds, so #227's rule holds: a constant zero in
any dimension stays silent.

Input class (AIS): an expression that creates an array of a no-default
struct, by the API that creates it. Every Array.CreateInstance and
CreateInstanceFromArrayType overload that takes a length, Rent on the
shared pool, on ArrayPool<T>.Create() and on a derived pool, each with
a zero-length control; a Type variable, GetType(), typeof(Plain?) and
an array of another element silent. Rent's T and the typeof element run
across TypeArgumentKinds (79 kinds; dynamic and string? take Rent
alone, typeof refusing them): each reports exactly where
GC.AllocateArray<K> does. No sibling beyond #229's
CollectionsMarshal.SetCount, which 2.4.0 takes.

Reverting the source fails the forms row and the three kinds that
report. Seeding the zero check away fails the three zero rows, reading
the lower bounds as lengths fails the forms row, and skipping an array
of lengths fails the silent row.

Closes #228

Defect-Class: AIS
Found-By: RS
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@CaffeinatedCoder CaffeinatedCoder added this to the 2.3.1 milestone Oct 31, 2026
@CaffeinatedCoder CaffeinatedCoder added bug Something isn't working silent Compiles or answers and does less than it appears to stacked Base is another open PR; merge in order, CI does not run until it targets a release severity/low Cosmetic, message or documentation-level difference package/analyzers Affects CodoMetis.TypeKit.Analyzers area/value-objects Value-object contracts and what the aspects generate for them labels Oct 31, 2026
Base automatically changed from fix/zero-dimension-array-silent-2-3-1 to release/2.3.1 October 31, 2026 07:48
@CaffeinatedCoder CaffeinatedCoder removed the stacked Base is another open PR; merge in order, CI does not run until it targets a release label Oct 31, 2026

This branch has not been deployed

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

Labels

area/value-objects Value-object contracts and what the aspects generate for them bug Something isn't working package/analyzers Affects CodoMetis.TypeKit.Analyzers severity/low Cosmetic, message or documentation-level difference silent Compiles or answers and does less than it appears to

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant