reflect — validation proof

Go’s own reflect test suite, converted to C# by go2cs, built against the converted standard library, run under the Go-semantics test host, and compared verdict for verdict against a clean go test -json baseline of the same sources. This page is generated by the converter from that comparison — it is the evidence behind the reflect row in Validated Test Packages.

Validated 2026-09-28 · converter 9a21c0848

396 matched · 22 disclosed — Go 1.24.13, windows/amd64, converted package src/core/reflect.

Measured at Release (tiered JIT off), oracle go version go1.24.13 windows/amd64.

Both runtimes skip 2 of the matched tests identically.

Verdicts

Test go test go2cs
TestAddr pass pass
TestAlias pass pass
TestAliasNames pass pass
TestAlignment pass fail (disclosed)
TestAll pass pass
TestAllocations skip skip
TestAllocsInterfaceBig pass pass
TestAllocsInterfaceSmall pass pass
TestAnonymousFields pass pass
TestAppend pass pass
TestArrayElemSet pass pass
TestArrayOf pass pass
TestArrayOfAlg pass pass
TestArrayOfDirectIface pass pass
TestArrayOfGC pass pass
TestArrayOfGenericAlg pass pass
TestArrayOfPanicOnNegativeLength pass pass
TestAssignableTo pass pass
TestBigStruct pass pass
TestBigUnnamedStruct pass pass
TestBigZero pass pass
TestBool pass pass
TestBytes pass pass
TestCallArgLive pass pass
TestCallConvert pass pass
TestCallGC pass pass
TestCallMethodJump pass pass
TestCallPanic pass pass
TestCallReturnsEmpty pass fail (disclosed)
TestCallWithStruct pass pass
TestCanIntUintFloatComplex pass pass
TestCanSetField pass pass
TestCanSetField/#00 pass pass
TestCanSetField/#01 pass pass
TestCanSetField/#02 pass pass
TestCanSetField/#03 pass pass
TestChan pass pass
TestChanAlloc pass fail (disclosed)
TestChanOf pass pass
TestChanOfDir pass pass
TestChanOfGC pass pass
TestClear pass pass
TestClear/map pass pass
TestClear/non-map/slice pass pass
TestClear/slice_has_pointer pass pass
TestClear/slice_no_pointer pass pass
TestComparable pass pass
TestConvert pass pass
TestConvertNaNs pass pass
TestConvertPanic pass pass
TestConvertSlice2Array pass pass
TestConvertibleTo pass pass
TestCopy pass pass
TestCopyArray pass pass
TestCopyString pass pass
TestCopyString/Array pass pass
TestCopyString/Slice pass pass
TestDeepEqual pass pass
TestDeepEqual/0 pass pass
TestDeepEqual/1 pass pass
TestDeepEqual/10 pass pass
TestDeepEqual/11 pass pass
TestDeepEqual/12 pass pass
TestDeepEqual/13 pass pass
TestDeepEqual/14 pass pass
TestDeepEqual/15 pass pass
TestDeepEqual/16 pass pass
TestDeepEqual/17 pass pass
TestDeepEqual/18 pass pass
TestDeepEqual/19 pass pass
TestDeepEqual/2 pass pass
TestDeepEqual/20 pass pass
TestDeepEqual/21 pass pass
TestDeepEqual/22 pass pass
TestDeepEqual/23 pass pass
TestDeepEqual/24 pass pass
TestDeepEqual/25 pass pass
TestDeepEqual/26 pass pass
TestDeepEqual/27 pass pass
TestDeepEqual/28 pass pass
TestDeepEqual/29 pass pass
TestDeepEqual/3 pass pass
TestDeepEqual/30 pass pass
TestDeepEqual/31 pass pass
TestDeepEqual/32 pass pass
TestDeepEqual/33 pass pass
TestDeepEqual/34 pass pass
TestDeepEqual/35 pass pass
TestDeepEqual/36 pass pass
TestDeepEqual/37 pass pass
TestDeepEqual/38 pass pass
TestDeepEqual/39 pass pass
TestDeepEqual/4 pass pass
TestDeepEqual/40 pass pass
TestDeepEqual/41 pass pass
TestDeepEqual/42 pass pass
TestDeepEqual/43 pass pass
TestDeepEqual/44 pass pass
TestDeepEqual/45 pass pass
TestDeepEqual/46 pass pass
TestDeepEqual/47 pass pass
TestDeepEqual/48 pass pass
TestDeepEqual/49 pass pass
TestDeepEqual/5 pass pass
TestDeepEqual/50 pass pass
TestDeepEqual/51 pass pass
TestDeepEqual/52 pass pass
TestDeepEqual/53 pass pass
TestDeepEqual/54 pass pass
TestDeepEqual/55 pass pass
TestDeepEqual/56 pass pass
TestDeepEqual/57 pass pass
TestDeepEqual/58 pass pass
TestDeepEqual/59 pass pass
TestDeepEqual/6 pass pass
TestDeepEqual/60 pass pass
TestDeepEqual/61 pass pass
TestDeepEqual/62 pass pass
TestDeepEqual/7 pass pass
TestDeepEqual/8 pass pass
TestDeepEqual/9 pass pass
TestDeepEqualAllocs skip skip
TestDeepEqualComplexStruct pass pass
TestDeepEqualComplexStructInequality pass pass
TestDeepEqualRecursiveStruct pass pass
TestDeepEqualUnexportedMap pass pass
TestDirectIfaceMethod pass pass
TestEmbed pass pass
TestEmbeddedMethods pass pass
TestExported pass pass
TestFieldByIndex pass pass
TestFieldByIndexErr pass pass
TestFieldByIndexNil pass pass
TestFieldByName pass pass
TestFieldPkgPath pass pass
TestFields pass pass
TestFields/EmbeddedExportedStruct pass pass
TestFields/EmbeddedNotAPointer pass pass
TestFields/EmbeddedPointerStruct pass pass
TestFields/EmbeddedStructsWithSameFieldsAtDifferentDepths pass pass
TestFields/EmbeddedUnexportedStruct pass pass
TestFields/NonEmbeddedStructMember pass pass
TestFields/RecursiveEmbedding pass pass
TestFields/RecursiveEmbedding2 pass pass
TestFields/RecursiveEmbedding3 pass pass
TestFields/SimpleStruct pass pass
TestFields/TwoEmbeddedStructsWithCancelingMembers pass pass
TestFunc pass pass
TestFuncArg pass pass
TestFuncLayout pass pass
TestFuncLayout/*uint8.func(uintptr,_*int) pass pass
TestFuncLayout/func()_uintptr pass pass
TestFuncLayout/func(map[int]int,_uintptr,_interface_{}) pass pass
TestFuncLayout/func(reflect_test.S) pass pass
TestFuncLayout/func(string,_string)_string pass pass
TestFuncLayout/func(uint32,_uint32,_uint32,_*uint8,_uint16) pass pass
TestFuncLayout/func(uintptr) pass pass
TestFuncLayout/uintptr.func(uintptr) pass pass
TestFuncOf pass pass
TestFunctionValue pass pass
TestGCBits pass fail (disclosed)
TestGroupSizeZero pass pass
TestGrow pass pass
TestGrow/Append pass pass
TestGrow/Rate pass pass
TestGrow/ZeroCapacity pass pass
TestImplements pass pass
TestImplicitAppendConversion pass pass
TestImplicitCallConversion pass pass
TestImplicitMapConversion pass pass
TestImplicitSendConversion pass pass
TestImplicitSetConversion pass pass
TestImportPath pass pass
TestIndex pass pass
TestInitFuncTypes pass pass
TestInterfaceExtraction pass pass
TestInterfaceGet pass pass
TestInterfaceSet pass pass
TestInterfaceValue pass pass
TestInternalIsZero pass pass
TestInvalid pass pass
TestIsNil pass pass
TestIsRegularMemory pass pass
TestIsRegularMemory/[0]struct{__S} pass pass
TestIsRegularMemory/[4]chan_int pass pass
TestIsRegularMemory/map[int][int] pass pass
TestIsRegularMemory/struct_{__int32_} pass pass
TestIsRegularMemory/struct_{x_int32;_y_int16} pass pass
TestIsRegularMemory/struct{a_int16;_b_int32} pass pass
TestIsRegularMemory/struct{i_int;___S} pass pass
TestIsRegularMemory/struct{i_int;_s_S} pass pass
TestIsRegularMemory/struct{i_int} pass pass
TestIsRegularMemory/struct{} pass pass
TestIsZero pass pass
TestIssue22031 pass pass
TestIssue22073 pass pass
TestIssue50208 pass pass
TestKeepFuncLive pass pass
TestKeepMethodLive pass pass
TestLarge pass pass
TestMakeFunc pass pass
TestMakeFuncInterface pass pass
TestMakeFuncInvalidReturnAssignments pass pass
TestMakeFuncStackCopy pass pass
TestMakeFuncValidReturnAssignments pass pass
TestMakeFuncVariadic pass pass
TestMap pass pass
TestMapAlloc pass pass
TestMapIterDelete0 pass pass
TestMapIterDelete1 pass pass
TestMapIterNext pass pass
TestMapIterNilMap pass pass
TestMapIterNonEmptyMap pass pass
TestMapIterReset pass fail (disclosed)
TestMapIterSafety pass pass
TestMapIterSet pass fail (disclosed)
TestMapOf pass pass
TestMapOfGCBigKey pass pass
TestMapOfGCKeys pass pass
TestMapOfGCValues pass pass
TestMapOfKeyPanic pass pass
TestMapOfKeyUpdate pass pass
TestMapSetNil pass pass
TestMethod pass pass
TestMethod5 pass pass
TestMethodByNameUnExportedFirst pass pass
TestMethodCallValueCodePtr pass fail (disclosed)
TestMethodPkgPath pass pass
TestMethodValue pass pass
TestMethodValueCallABI pass pass
TestNames pass pass
TestNegativeKindString pass pass
TestNestedMethods pass pass
TestNilMap pass pass
TestNilPtrValueSub pass pass
TestNumMethodOnDDD pass pass
TestOffsetLock pass pass
TestPtrPointTo pass pass
TestPtrSetNil pass pass
TestPtrTo pass pass
TestPtrToGC pass fail (disclosed)
TestPtrToMethods pass pass
TestReflectCallABI pass pass
TestReflectCallABI/reflect_test.pass2Struct1 pass pass
TestReflectCallABI/reflect_test.passArray pass pass
TestReflectCallABI/reflect_test.passArray1 pass pass
TestReflectCallABI/reflect_test.passArray1Mix pass pass
TestReflectCallABI/reflect_test.passComplex128 pass pass
TestReflectCallABI/reflect_test.passComplex64 pass pass
TestReflectCallABI/reflect_test.passEmptyStruct pass pass
TestReflectCallABI/reflect_test.passFloat32 pass pass
TestReflectCallABI/reflect_test.passFloat64 pass pass
TestReflectCallABI/reflect_test.passInt pass pass
TestReflectCallABI/reflect_test.passInt16 pass pass
TestReflectCallABI/reflect_test.passInt32 pass pass
TestReflectCallABI/reflect_test.passInt64 pass pass
TestReflectCallABI/reflect_test.passInt8 pass pass
TestReflectCallABI/reflect_test.passManyFloat64 pass pass
TestReflectCallABI/reflect_test.passManyInt pass pass
TestReflectCallABI/reflect_test.passNone pass pass
TestReflectCallABI/reflect_test.passPointer pass pass
TestReflectCallABI/reflect_test.passSlice pass pass
TestReflectCallABI/reflect_test.passString pass pass
TestReflectCallABI/reflect_test.passStruct1 pass pass
TestReflectCallABI/reflect_test.passStruct10 pass pass
TestReflectCallABI/reflect_test.passStruct10AndSmall pass pass
TestReflectCallABI/reflect_test.passStruct11 pass pass
TestReflectCallABI/reflect_test.passStruct12 pass pass
TestReflectCallABI/reflect_test.passStruct13 pass pass
TestReflectCallABI/reflect_test.passStruct14 pass pass
TestReflectCallABI/reflect_test.passStruct15 pass pass
TestReflectCallABI/reflect_test.passStruct2 pass pass
TestReflectCallABI/reflect_test.passStruct3 pass pass
TestReflectCallABI/reflect_test.passStruct4 pass pass
TestReflectCallABI/reflect_test.passStruct5 pass pass
TestReflectCallABI/reflect_test.passStruct6 pass pass
TestReflectCallABI/reflect_test.passStruct7 pass pass
TestReflectCallABI/reflect_test.passStruct8 pass pass
TestReflectCallABI/reflect_test.passStruct9 pass pass
TestReflectCallABI/reflect_test.passUint pass pass
TestReflectCallABI/reflect_test.passUint16 pass pass
TestReflectCallABI/reflect_test.passUint32 pass pass
TestReflectCallABI/reflect_test.passUint64 pass pass
TestReflectCallABI/reflect_test.passUint8 pass pass
TestReflectFuncTraceback pass pass
TestReflectMakeFuncCallABI pass pass
TestReflectMakeFuncCallABI/OnlyPointerInRegisterGC pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgs2Struct1 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsArray pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsArray1 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsArray1Mix pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsComplex128 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsComplex64 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsEmptyStruct pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsFloat32 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsFloat64 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsInt pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsInt16 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsInt32 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsInt64 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsInt8 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsManyFloat64 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsManyInt pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsNone pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsPointer pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsSlice pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsString pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsStruct1 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsStruct10 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsStruct11 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsStruct12 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsStruct13 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsStruct14 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsStruct15 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsStruct2 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsStruct3 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsStruct4 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsStruct5 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsStruct6 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsStruct7 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsStruct8 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsStruct9 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsUint pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsUint16 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsUint32 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsUint64 pass pass
TestReflectMakeFuncCallABI/reflect_test.callArgsUint8 pass pass
TestReflectMethodTraceback pass pass
TestSelect pass pass
TestSelectMaxCases pass pass
TestSelectNop pass pass
TestSet pass pass
TestSetBytes pass pass
TestSetIter pass pass
TestSetLenCap pass pass
TestSetPanic pass pass
TestSetValue pass pass
TestSignalingNaNArgument pass pass
TestSignalingNaNReturn pass pass
TestSlice pass fail (disclosed)
TestSlice3 pass fail (disclosed)
TestSliceAt pass fail (disclosed)
TestSliceOf pass pass
TestSliceOfGC pass pass
TestSliceOverflow pass pass
TestSmallNegativeInt pass pass
TestSmallZero pass fail (disclosed)
TestStructArg pass pass
TestStructOf pass fail (disclosed)
TestStructOfAlg pass pass
TestStructOfAnonymous pass fail (disclosed)
TestStructOfDifferentPkgPath pass pass
TestStructOfDirectIface pass pass
TestStructOfEmbeddedIfaceMethodCall pass pass
TestStructOfExportRules pass pass
TestStructOfFieldName pass pass
TestStructOfGC pass pass
TestStructOfGenericAlg pass pass
TestStructOfTooLarge pass pass
TestStructOfTooManyFields pass pass
TestStructOfWithInterface pass pass
TestSwapper pass pass
TestTagGet pass pass
TestTypeFieldOutOfRangePanic pass pass
TestTypeFieldReadOnly pass fail (disclosed)
TestTypeFor pass pass
TestTypeOf pass pass
TestTypeOfTypeOf pass pass
TestTypeOverflow pass pass
TestTypeStrings pass pass
TestType_CanSeq pass pass
TestType_CanSeq/*[4]int pass pass
TestType_CanSeq/[]int pass pass
TestType_CanSeq/chan_int64 pass pass
TestType_CanSeq/func(func(int)) pass pass
TestType_CanSeq/func(func(int)_bool) pass pass
TestType_CanSeq/int64 pass pass
TestType_CanSeq/map[int]int pass pass
TestType_CanSeq/string pass pass
TestType_CanSeq/uint64 pass pass
TestType_CanSeq2 pass pass
TestType_CanSeq2/*[4]int pass pass
TestType_CanSeq2/[]int pass pass
TestType_CanSeq2/chan_int64 pass pass
TestType_CanSeq2/func(func(int,_int)) pass pass
TestType_CanSeq2/func(func(int,_int)_bool) pass pass
TestType_CanSeq2/int64 pass pass
TestType_CanSeq2/map[int]int pass pass
TestType_CanSeq2/string pass pass
TestType_CanSeq2/uint64 pass pass
TestTypelinksSorted pass pass
TestTypes pass pass
TestUnaddressableField pass pass
TestUnexported pass pass
TestUnexportedMethods pass pass
TestValueOverflow pass pass
TestValuePanic pass pass
TestValuePointerAndUnsafePointer pass fail (disclosed)
TestValuePointerAndUnsafePointer/channel pass fail (disclosed)
TestValuePointerAndUnsafePointer/function pass fail (disclosed)
TestValuePointerAndUnsafePointer/map pass fail (disclosed)
TestValuePointerAndUnsafePointer/pointer pass fail (disclosed)
TestValuePointerAndUnsafePointer/slice pass fail (disclosed)
TestValuePointerAndUnsafePointer/string pass fail (disclosed)
TestValuePointerAndUnsafePointer/unsafe.Pointer pass pass
TestValueSeq pass pass
TestValueSeq2 pass pass
TestValueString pass pass
TestValueToString pass pass
TestValue_Cap pass pass
TestValue_Comparable pass pass
TestValue_Equal pass pass
TestValue_EqualNonComparable pass pass
TestValue_Len pass pass
TestVariadic pass pass
TestVariadicMethodValue pass pass
TestVariadicType pass pass
TestZeroSet pass pass

Disclosed divergences

A disclosed divergence is a specific Go assertion the managed CLR provably cannot satisfy — not a skipped test and not a tolerance. Each one is pinned by exact failure signature in the package’s hand-owned go2cs_test_disclosures.json; a disclosed test that fails any other way is still a hard mismatch.

Test Class Pinned reason
TestAlignment runtime-capability runtime-capability: the assert computes field offsets by uintptr ARITHMETIC over the receiver’s own address and compares them against reflect’s answers. Managed memory exposes no stable byte offsets to arithmetic – the runtime is free to lay out and to move objects – so the test’s arithmetic yields 0 where Go’s yields a real offset, and the printed pair (8 0, then 16 0) is the test’s OWN number against the bridge’s. reflect’s own Offset is CORRECT here and is not what fails: the divergence is in the measuring instrument the test builds, not in the operation under test. Pinned on the stable prefix because the two occurrences print different offsets.
TestCallReturnsEmpty codegen-liveness codegen-liveness: Go’s liveness maps drop a local at its LAST USE. The test writes v := ValueOf(f).Call(nil)[0] and NEVER NAMES the intermediate []Value, so Go frees it before runtime.GC() and the finalizer on out[1] – the *[2]int64 the test waits for – runs inside the wait. The converted host keeps a caller frame slot rooted for that intermediate while it stays in scope, so out[1] survives the collection and the wait times out with Go’s own message. runtime.SetFinalizer is FULLY WIRED here (a ConditionalWeakTable keyed on the referent, with a sentinel that resurrects the box for the call), so a finalizer that does not run means retention rather than a missing feature. MEASURED as a one-axis pair, each arm also run under Go as its own oracle – (7a) the row’s line verbatim: Go COLLECTED / Release+TC0 RETAINED; (7b) the intermediate NAMED and CLEARED, the only axis varied: Go COLLECTED / Release+TC0 COLLECTED. 7a retains and 7b collects, so the pin is SOLELY the frame slot holding the intermediate. That same pair is the anti-laundering control, and it is why this is a disclosure and not a defect: Go issue 21717, which this test exists to catch, is about out[0] ALIASING out[1]’s storage – if that alias existed here, clearing the slice could not help, because v still holds out[0] and is kept alive across the collection, so 7b would have read RETAINED. It reads COLLECTED. Call does not alias its zero-sized return over the next one; the defect this test guards is measured ABSENT, and what remains is the host’s liveness model, a representational fact rather than an unbuilt feature. LIMIT, stated: 7a/7b were measured at Release+TC0 only, the configuration of record; the tier axis of the sibling unique/TestMakeClonesStrings entry predicts retention under tiering and in Debug, but that was not run for this row and is not reported as though it had been.
TestChanAlloc alloc-count-semantics at-most-one AllocsPerRun assert on a reflect channel Send plus Recv of a chan *int: Go counts exactly one allocation per round-trip (the Value reflect.recv returns, which the test’s own note calls a limitation of escape analysis) and requires 0.5 <= allocs <= 1.5 (all_test.go TestChanAlloc). The managed channel carries its element boxed, so a send allocates where Go copies into the ring buffer. [SUPERSEDED 2026-09-27: this entry previously called the assert want-zero; its want is ONE.] RELABEL 2026-09-27 (C1, on COORD’s seat of 2026-09-27 11:50, ledger 9760611653, under the H10 rulings of ledger 2026-09-23 03:37): alloc-profile -> alloc-count-semantics. The run’s own unit note is BYTES, golib’s counter charging none of it, so no object count exists to compare with Go’s one: the ladder’s incomparable-unit arm. Nothing to retire and no plan.
TestGCBits runtime-capability runtime-capability: the verifyGCBitsSlice path compares a slice’s HEAP-ALLOCATION GC bitmap. Go’s gcbits(*E) reads the heap object at the pointer and returns the element’s pointer bits REPEATED by the allocation’s size class – have [1] want [1 1], have [1] want [1 1 …x10000], have [0 1] want [0 1 0 1]. The managed gcbits answers from the POINTEE TYPE’s layout (GoReflect.GoGCMaskOf) – the element’s bits ONCE – because the managed model has no allocation size class to repeat by, and reflect.NewAt’s *E carries no cap it was never given. The non-slice verifyGCBits path (New(typ).Interface()) is unaffected. Same managed-model class as the alloc-count and pointer-identity disclosures (coordinator ruling 2026-09-02; C2’s gcbits authority, R mints the reflect manifest entry).
TestMapIterReset alloc-count-semantics want-zero AllocsPerRun assert on MapIter.Reset. Go reuses one hiter in place; the managed iterator must obtain a fresh enumerator from the map when it rebinds, because IEnumerator carries no reset-to-a-different-source operation. The allocation is the enumerator itself, charged outside golib (BCL internal), so the figure is reported in BYTES rather than as a count. RELABEL 2026-09-27 (C1, on COORD’s seat of 2026-09-27 11:50, ledger 9760611653, under the H10 rulings of ledger 2026-09-23 03:37): alloc-profile -> alloc-count-semantics. The run’s own unit note is BYTES – the enumerator this reason names is BCL-internal and uncounted – so no object count exists to compare with the want of zero: the ladder’s incomparable-unit arm. Nothing to retire and no plan.
TestMapIterSet structural want-zero AllocsPerRun assert over SetIterKey/SetIterValue across one MapRange of a 22-key map. RELABEL 2026-09-27 (COORD, on the i7 readings requested at ledger 2026-09-27 14:58): alloc-profile -> STRUCTURAL. WANT: 0 allocations per run. READING: 1 per run, unit COUNT – 10 go2cs-runtime object allocations (33,120 bytes) over 10 runs at 1aebd6a885, windows/amd64, Release with tiering off; Go reads 0 mallocs and 0 B on the same box. PROOF, with the object Go keeps off the heap NAMED: the one counted object is the *MapIter itself, a StandardBox (224 B) minted by the hand-owned MapRange and handed to every SetIterKey/SetIterValue call as a ж argument. Go keeps it off the heap only because MapRange is inlineable, so escape analysis stack-allocates the non-escaping iterator in the CALLER (the test's own comment says so). A managed implementation cannot do the same across the call boundary: C# cannot return a reference into a callee's stack frame, and a shared or pooled box would alias two live iterators, which Go forbids. The only route is inlining MapRange into its callers, and go2cs keeps Go's function boundaries one-for-one so the emitted code reads like the Go source. The CLR JIT does not remove the box at tiering off either (measured: 224 B and count 1 on every run). The reading equals that floor. NOTE, not part of the proof: the run also allocates 3,088 B of objects the counter does not see (the range iterator 72 B, the by-design range snapshot 24 + 24 x len, and 112 B per entry of KeyValuePair and key boxing through the non-generic IEnumerator.Current and PropertyInfo.GetValue). They are reducible, but reducing them retires nothing while the box exists, since a zero count with nonzero bytes moves this want-zero assert to the byte arm. The per-site table is in docs/phase4/briefs/reflect-alloc-readings-2026-09-27.md. The previous reason (one KeyValuePair box per step) omitted the counted object.
TestMethodCallValueCodePtr runtime-capability runtime-capability: reflect.methodValueCall is an ASSEMBLY function with no managed body in this corpus, so no honest program counter exists for it and FuncPCABI0 REFUSES BY NAME rather than minting a number that would be a lie (internal/abi/funcpc_impl.cs, the GoExternalStubAttribute arm; landed 1742450a1, in master via 684d2b00c). The row therefore panics before it reaches its comparison at all. The refusal text was written to serve as a disclosure signature and its own comment names this class, so the pin and the label are the mechanism author’s rather than an interpretation of them. STALE BY MECHANISM CHANGE, not by drift: the previous signature pinned a numeric code-pointer MISMATCH – the row used to reach the comparison and disagree – and the previous reason described that comparison. The underlying capability gap is unchanged and is now stated earlier and more truthfully; the entry is re-pinned rather than widened, and it absorbs nothing it did not absorb before.
TestPtrToGC runtime-capability runtime-capability: the test converts a **uintptr to a DEFINED pointer type. A defined pointer type emits as a go2cs-gen wrapper CLASS, so there is no aliasing view of the outer slot to hand out and the conversion cannot be performed at all – which is why increment E3 refused it BY NAME rather than approximating it. The refusal is the honest answer: an approximation would hand back a wrapper over a COPY, and this test’s whole point is that the collector must see the pointer through the conversion. reflect’s own Convert is correct for every shape where an aliasing view exists; this is the one where the object model does not admit one.
TestSlice runtime-capability runtime-capability: the assert compares a POINTER NUMERICALLY. go2cs pointers are stable identity TOKENS, not addresses – the same deliberate model the guintptr manual conversion rests on – so a managed host can report a consistent, comparable identity for a value but never the address Go prints. Go itself documents these as implementation details; the divergence is the architecture showing through, not a defect in the operation under test.
TestSlice3 runtime-capability runtime-capability: the assert compares a POINTER NUMERICALLY. go2cs pointers are stable identity TOKENS, not addresses – the same deliberate model the guintptr manual conversion rests on – so a managed host can report a consistent, comparable identity for a value but never the address Go prints. Go itself documents these as implementation details; the divergence is the architecture showing through, not a defect in the operation under test.
TestSliceAt runtime-capability runtime-capability: reflect.SliceAt builds a slice that aliases the pointer’s memory faithfully (len/cap/nil and the negative/nil-pointer/overflow panics all agree with Go), but its Value.Pointer() is a STORAGE-IDENTITY token – HashCode.Combine(backing, low), kept stable for encoding/json’s cycle detector and internal/fmtsort’s map ordering – while uintptr(unsafe.Pointer(&p[0])) is the pinned data address. The two are managed-model projections of one storage that coincide only for native memory; making them equal would pin managed storage on every Pointer() call and move the cycle-detector hot path off its cheap hash, so the identity is disclosed rather than unified (coordinator ruling 2026-09-02; token-unification refused).
TestSmallZero alloc-count-semantics want-zero AllocsPerRun assert on reflect.Zero for small values. Go returns a value whose data word fits inline and allocates nothing; the managed bridge must materialize a boxed zero for the same Value. RELABEL 2026-09-27 (C1, on COORD’s seat of 2026-09-27 11:50, ledger 9760611653, under the H10 rulings of ledger 2026-09-23 03:37): alloc-profile -> alloc-count-semantics. The run’s own unit note is BYTES, golib’s counter charging none of it, so no object count exists to compare with the want of zero: the ladder’s incomparable-unit arm. Nothing to retire and no plan.
TestStructOf runtime-capability runtime-capability: the assert compares a POINTER NUMERICALLY. go2cs pointers are stable identity TOKENS, not addresses – the same deliberate model the guintptr manual conversion rests on – so a managed host can report a consistent, comparable identity for a value but never the address Go prints. Go itself documents these as implementation details; the divergence is the architecture showing through, not a defect in the operation under test.
TestStructOfAnonymous runtime-capability runtime-capability: the assert compares a POINTER NUMERICALLY. go2cs pointers are stable identity TOKENS, not addresses – the same deliberate model the guintptr manual conversion rests on – so a managed host can report a consistent, comparable identity for a value but never the address Go prints. Go itself documents these as implementation details; the divergence is the architecture showing through, not a defect in the operation under test.
TestTypeFieldReadOnly runtime-capability runtime-capability: the test asserts that gc places StructField.Index’s backing array in READ-ONLY memory, so that the plain write f.Index[0] = 1 takes a hardware protection fault which debug.SetPanicOnFault(true) turns into a panic – an allocation saving the test’s own comment calls “otherwise not important”. The managed runtime has no write-protected managed memory, and golib’s slice indexer is ONE ref-returning accessor (slice.cs, public ref T this[int]) serving reads and writes alike, so a guard could not tell this write from a read without taxing every slice read in the corpus (a measured hot path). Backing Index with a native read-only page instead would turn the write into an AccessViolation that .NET cannot catch, killing the host rather than reporting a divergence. So the write succeeds and shouldPanic reports “did not panic”. Go itself skips this test where a write does not fault (GOOS=js and wasip1: “test does not fault”), which is the same capability gap. The operation under test – reflect.Type.Field – is correct; only the memory protection behind it is absent.
TestValuePointerAndUnsafePointer aggregate no failure text of its own — the roll-up of this test’s disclosed subtests
TestValuePointerAndUnsafePointer/channel runtime-capability runtime-capability: reflect’s pointer projection and a raw memory-word read are separate authorities in the managed model, and this assert compares them. Go has one mechanism for both because its pointers ARE addresses; go2cs cannot, and each side’s rule exists because the alternative was measured and hurt. The want comes from golib’s implicit operator uintptr(ж<T>) (EnsureStableAddress, then fixed (&value.Value)), which must hand back a REAL PINNED, DEREFERENCEABLE address – Go permits converting the scalar back and dereferencing it, which go/types’ check_test.go does, and the uintptr arm’s exact fidelity rests on it. The got comes from reflect’s own reflectPointerToken, which must hand back an OPAQUE STABLE PER-OBJECT IDENTITY: a map or slice value is a header struct freshly boxed on every read, so an address-based token differs per read and encoding/json’s cycle detector stops matching entries it stored itself (the recorded 0xc00000fd stack-exhaustion defect), while typeDescriptorOrderToken’s packed type names are what make fmt.Println(map[I]int{…}) print deterministically. Measured 2026-08-31: the six wants cluster at ~2.993e12 within a few hundred bytes (consecutively allocated boxes, real addresses) while the gots scatter over 2.7e7-2.1e9 (32-bit identity hashes) – the two sides already share the ManagedPointerTokens registry, so what differs is the MINT, not resolution. Unifying either direction sacrifices a banked behavior worth hundreds of verdicts for six rows. The operation under test is correct; the architecture is showing through.
TestValuePointerAndUnsafePointer/function runtime-capability runtime-capability: reflect’s pointer projection and a raw memory-word read are separate authorities in the managed model, and this assert compares them. Go has one mechanism for both because its pointers ARE addresses; go2cs cannot, and each side’s rule exists because the alternative was measured and hurt. The want comes from golib’s implicit operator uintptr(ж<T>) (EnsureStableAddress, then fixed (&value.Value)), which must hand back a REAL PINNED, DEREFERENCEABLE address – Go permits converting the scalar back and dereferencing it, which go/types’ check_test.go does, and the uintptr arm’s exact fidelity rests on it. The got comes from reflect’s own reflectPointerToken, which must hand back an OPAQUE STABLE PER-OBJECT IDENTITY: a map or slice value is a header struct freshly boxed on every read, so an address-based token differs per read and encoding/json’s cycle detector stops matching entries it stored itself (the recorded 0xc00000fd stack-exhaustion defect), while typeDescriptorOrderToken’s packed type names are what make fmt.Println(map[I]int{…}) print deterministically. Measured 2026-08-31: the six wants cluster at ~2.993e12 within a few hundred bytes (consecutively allocated boxes, real addresses) while the gots scatter over 2.7e7-2.1e9 (32-bit identity hashes) – the two sides already share the ManagedPointerTokens registry, so what differs is the MINT, not resolution. Unifying either direction sacrifices a banked behavior worth hundreds of verdicts for six rows. The operation under test is correct; the architecture is showing through.
TestValuePointerAndUnsafePointer/map runtime-capability runtime-capability: reflect’s pointer projection and a raw memory-word read are separate authorities in the managed model, and this assert compares them. Go has one mechanism for both because its pointers ARE addresses; go2cs cannot, and each side’s rule exists because the alternative was measured and hurt. The want comes from golib’s implicit operator uintptr(ж<T>) (EnsureStableAddress, then fixed (&value.Value)), which must hand back a REAL PINNED, DEREFERENCEABLE address – Go permits converting the scalar back and dereferencing it, which go/types’ check_test.go does, and the uintptr arm’s exact fidelity rests on it. The got comes from reflect’s own reflectPointerToken, which must hand back an OPAQUE STABLE PER-OBJECT IDENTITY: a map or slice value is a header struct freshly boxed on every read, so an address-based token differs per read and encoding/json’s cycle detector stops matching entries it stored itself (the recorded 0xc00000fd stack-exhaustion defect), while typeDescriptorOrderToken’s packed type names are what make fmt.Println(map[I]int{…}) print deterministically. Measured 2026-08-31: the six wants cluster at ~2.993e12 within a few hundred bytes (consecutively allocated boxes, real addresses) while the gots scatter over 2.7e7-2.1e9 (32-bit identity hashes) – the two sides already share the ManagedPointerTokens registry, so what differs is the MINT, not resolution. Unifying either direction sacrifices a banked behavior worth hundreds of verdicts for six rows. The operation under test is correct; the architecture is showing through.
TestValuePointerAndUnsafePointer/pointer runtime-capability runtime-capability: reflect’s pointer projection and a raw memory-word read are separate authorities in the managed model, and this assert compares them. Go has one mechanism for both because its pointers ARE addresses; go2cs cannot, and each side’s rule exists because the alternative was measured and hurt. The want comes from golib’s implicit operator uintptr(ж<T>) (EnsureStableAddress, then fixed (&value.Value)), which must hand back a REAL PINNED, DEREFERENCEABLE address – Go permits converting the scalar back and dereferencing it, which go/types’ check_test.go does, and the uintptr arm’s exact fidelity rests on it. The got comes from reflect’s own reflectPointerToken, which must hand back an OPAQUE STABLE PER-OBJECT IDENTITY: a map or slice value is a header struct freshly boxed on every read, so an address-based token differs per read and encoding/json’s cycle detector stops matching entries it stored itself (the recorded 0xc00000fd stack-exhaustion defect), while typeDescriptorOrderToken’s packed type names are what make fmt.Println(map[I]int{…}) print deterministically. Measured 2026-08-31: the six wants cluster at ~2.993e12 within a few hundred bytes (consecutively allocated boxes, real addresses) while the gots scatter over 2.7e7-2.1e9 (32-bit identity hashes) – the two sides already share the ManagedPointerTokens registry, so what differs is the MINT, not resolution. Unifying either direction sacrifices a banked behavior worth hundreds of verdicts for six rows. The operation under test is correct; the architecture is showing through.
TestValuePointerAndUnsafePointer/slice runtime-capability runtime-capability: reflect’s pointer projection and a raw memory-word read are separate authorities in the managed model, and this assert compares them. Go has one mechanism for both because its pointers ARE addresses; go2cs cannot, and each side’s rule exists because the alternative was measured and hurt. The want comes from golib’s implicit operator uintptr(ж<T>) (EnsureStableAddress, then fixed (&value.Value)), which must hand back a REAL PINNED, DEREFERENCEABLE address – Go permits converting the scalar back and dereferencing it, which go/types’ check_test.go does, and the uintptr arm’s exact fidelity rests on it. The got comes from reflect’s own reflectPointerToken, which must hand back an OPAQUE STABLE PER-OBJECT IDENTITY: a map or slice value is a header struct freshly boxed on every read, so an address-based token differs per read and encoding/json’s cycle detector stops matching entries it stored itself (the recorded 0xc00000fd stack-exhaustion defect), while typeDescriptorOrderToken’s packed type names are what make fmt.Println(map[I]int{…}) print deterministically. Measured 2026-08-31: the six wants cluster at ~2.993e12 within a few hundred bytes (consecutively allocated boxes, real addresses) while the gots scatter over 2.7e7-2.1e9 (32-bit identity hashes) – the two sides already share the ManagedPointerTokens registry, so what differs is the MINT, not resolution. Unifying either direction sacrifices a banked behavior worth hundreds of verdicts for six rows. The operation under test is correct; the architecture is showing through.
TestValuePointerAndUnsafePointer/string runtime-capability runtime-capability: reflect’s pointer projection and a raw memory-word read are separate authorities in the managed model, and this assert compares them. Go has one mechanism for both because its pointers ARE addresses; go2cs cannot, and each side’s rule exists because the alternative was measured and hurt. The want comes from golib’s implicit operator uintptr(ж<T>) (EnsureStableAddress, then fixed (&value.Value)), which must hand back a REAL PINNED, DEREFERENCEABLE address – Go permits converting the scalar back and dereferencing it, which go/types’ check_test.go does, and the uintptr arm’s exact fidelity rests on it. The got comes from reflect’s own reflectPointerToken, which must hand back an OPAQUE STABLE PER-OBJECT IDENTITY: a map or slice value is a header struct freshly boxed on every read, so an address-based token differs per read and encoding/json’s cycle detector stops matching entries it stored itself (the recorded 0xc00000fd stack-exhaustion defect), while typeDescriptorOrderToken’s packed type names are what make fmt.Println(map[I]int{…}) print deterministically. Measured 2026-08-31: the six wants cluster at ~2.993e12 within a few hundred bytes (consecutively allocated boxes, real addresses) while the gots scatter over 2.7e7-2.1e9 (32-bit identity hashes) – the two sides already share the ManagedPointerTokens registry, so what differs is the MINT, not resolution. Unifying either direction sacrifices a banked behavior worth hundreds of verdicts for six rows. The operation under test is correct; the architecture is showing through.

Excluded declarations

Declarations filtered from both sides of the comparison, and therefore not claimed above: Benchmark, Fuzz and Example declarations the converted host does not execute, plus any test requiring a capability the managed runtime does not provide — a testing member the host has not implemented, or a platform behavior it provably cannot reproduce. Each is named with the capability it needs.