Repository navigation
Description
Found by a sweep of release/2.3.1 @ dbdd44e (lens: sibling-parity, analyzers) for the defect class of #191-#197; reproduced in a scratch analyzer test.
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. Two rules say nothing where their siblings report the same type
Problem
TypeKitSymbols.IsNoDefaultStruct (src/CodoMetis.TypeKit.Analyzers/TypeKitSymbols.cs:299-300), which CMTK0005 (DefaultFilledCollectionAnalyzer.cs:119) and CMTK0006 (UnassignedNoDefaultMemberAnalyzer.cs:163,171) call, admits a type parameter only with a struct constraint. DefaultRestriction, which CMTK0001 and CMTK0009 call, also admits ITypeParameterSymbol { HasConstructorConstraint: true, IsReferenceType: false }, since a generated class has no public parameterless constructor and such a T is a struct value object. The README defines CMTK0005 and CMTK0006 over "such a type", CMTK0001's list, which includes a type parameter whose constraints make it one.
Scenario
public interface IEntityId<TSelf> : IValue<int> where TSelf : IEntityId<TSelf> { }
public static T One<T>() where T : IEntityId<T>, new() => new T(); // CMTK0001
public static T[] Many<T>() where T : IEntityId<T>, new() => new T[3]; // nothing; with `struct, IEntityId<T>`: CMTK0005
public sealed class Holder<T> where T : IEntityId<T>, new()
{
public T Id { get; set; } // nothing; expected CMTK0006
}Measured @ dbdd44e: the CMTK0005 and CMTK0006 rows report no diagnostic; the struct control and CMTK0001 on the same T report.
Change
IsNoDefaultStruct returns DefaultRestriction(type) is not null, which already admits only value types and new() type parameters that are not reference types. Both rules are Warnings, so reporting more needs no exception to decision 34.
Test
CMTK0005 and CMTK0006 rows for T : IEntityId<T>, new() and T : IValue<int>, new(), across TypeArgumentKinds (struct, new(), through a user interface, through another type parameter); reverted per verify-the-guard.
Environment
.NET SDK 10.0.4xx; any consumer.
Fixed in #216 (a3f72f5)
IsNoDefaultStruct is now DefaultRestriction(type) is not null, CMTK0001's predicate. NoDefaultKindTests holds CMTK0001, CMTK0005 and CMTK0006 to one oracle over all 80 kinds of TypeArgumentKinds (the reported new() shape through a derived interface added); the two new() kinds were the only disagreement, and no other rule called the narrow predicate.
Activity
CaffeinatedCoder commentedon Oct 31, 2026
Fixed by #216, merged into
release/2.3.1(c855caa); ships in 2.3.1.