Skip to content

Interop sweep: the generic-annotation probe accepts a DIFFERENT type than the member it enumerated (7 List`1 rows) #1829

Description

@antonsynd

Found while draining the #1625 rows from src/Sharpy.Compiler.Tests/Conformance/interop-allowlist.txt (P4 remediation R4, branch v5/clr-resolution).

The instrument

InteropConformanceTests renders a closed construction for a generic discovered type (List[int], Deque[int]) and guards it with a probe:

// Core-internal generic types (List, Set, iterators, views) are not annotatable under their
// discovered CamelCase names — the user-facing spelling is `list`/`set`/…, so `List[int]`
// yields SPY0202. Probe the closed annotation once and skip the whole type when it doesn't resolve.

The probe asks only "does this compile", not "did the name bind the type whose members I am about to probe". Since #1625 the CLR fallback answers List with System.Collections.Generic.List<T> (the collision rule: a short name that also names a non-Sharpy type prefers the .NET one). So the probe now passes, the type is no longer skipped, and Sharpy.List<T>'s Python-style member names are probed against the .NET List<int>:

builtins::property::List`1.length::property             SPY0203: Type 'List[int32]' has no member 'length'
builtins::method::List`1.delete_at::method              SPY0203: ... no member 'delete_at'
builtins::method::List`1.get_item_unchecked::method     SPY0203: ... no member 'get_item_unchecked'
builtins::method::List`1.get::method                    SPY0203: ... no member 'get'
builtins::method::List`1.pop::method                    SPY0203: 'pop' is a Python collection method with no CLR equivalent on 'List[int32]'
builtins::method::List`1.extend::method                 SPY0203: ... 'extend' ...
builtins::method::List`1.copy::method                   SPY0203: ... 'copy' ...

2cc6e0667 recorded these as "genuine API-surface gaps, not resolution bugs" and kept them allowlisted against the issue it was closing. They are neither: the sweep is measuring the wrong receiver. Sharpy.List<T> does have pop, extend, copy — under the spelling list[int].

Fix

Make the probe an identity check, not a compile check: a Sharpy-namespace type whose discovered short name also names a type in the fallback's namespace list cannot be annotated by that name at all, so it must be RecordNotAttempted (reason: the name resolves to the .NET type — #1625) or rendered under its user-facing Sharpy spelling (list, set, frozenset, the dict views) and probed there.

State

The 7 rows are re-added to interop-allowlist.txt citing this issue (the other 47 #1625 rows, all Sharpy-namespace non-collision types, drained when the resolution fix landed: the sweep reads 2576 pass / 7 fail / 0 crash / 0 stale @ v5/clr-resolution). Delete them when this lands.

Activity

  1. antonsynd commented on Sep 12, 2026

    @antonsynd
    OwnerAuthor

    Placement (2026-09-11 batching): chore, one commit (drains the 7 interop-allowlist.txt rows). Instrument rule added to docs/design/gap-discovery-contracts.md: a sweep probe asserts it bound the type it enumerated, never merely that the probe compiled. Collision types render under their Sharpy spelling or record NotAttempted citing #1625's collision rule.

  2. antonsynd commented on Sep 20, 2026

    @antonsynd
    OwnerAuthor

    Close criterion met: Conformance/interop-allowlist.txt has 0 rows (grep -c 1829 = 0). SharpyWrapperSpellings + BindsTheEnumeratedType + totality guard SharpyWrapperSpellings_CoverEveryBclCollidingSharpyGeneric in InteropConformanceTests.cs; EditorBrowsable(Never) on the six internal List members and delete_at/get_item_unchecked gone from docs/stdlib/. InteropSweep_AllPublicStdlibMembers_CompileClean passes in the gate. (28fa008, unpushed, additionally anchors the totality guard to the literal collider List`1.)

    — /verify-implementation 2026-09-20 (six-plan round, base 41dd19d). Evidence is on origin/dev @ 322fbd2; whole-solution gate 31390/0/3 @ 322fbd2 (measured, a2) and 31835/1/3 @ 8182253 (measured; the 1 red a test-roster row, cured @ c1bb9f7).

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions