gsc: keep named-tuple-bearing generic arguments symbolic at every projection gate (ADR-0172) - #3632
Merged
Merged
Conversation
…jection gate (ADR-0172) The 2026-08-29 nightly (run 33260247720, post-#3631) still failed 32/52 vs floor 33: migrated Cs2Gs.Translator hit GS0158/GS0159/GS0116 at CSharpToGSharpTranslator.Constructors.gs:1537-38 — `candidate[0].Symbol` and `reach[head].Contains(...)` over `List[List[(syntax LocalFunctionStatementSyntax, symbol IMethodSymbol)]]` — and the errors cascaded into 11 downstream apps. Root cause: a named tuple nested INSIDE a generic type argument shares its CLR backing with the unnamed shape, so every keep-symbolic decision that consults only RequiresSymbolicProjection (or a direct `is TupleTypeSymbol`) collapsed the constructed type to its erased CLR form and the element names vanished; member access by name then failed. The #3622 projection-gate family covered direct named-tuple arguments (`List[(a, b)]` one level deep) but not `List[List[(a, b)]]`, `List[[](a, b)]`, or `Dictionary[K, (a, b)]` reached through construction, indexing, or iteration. Widened six gates with TypeSymbol.ContainsNamedTupleElements (which already recurses through every constructor shape): - ExpressionBinder.Calls.cs TryResolveClrConstructionTypeArgs — the generic ctor call kept no symbolic view, erasing at the root. - ExpressionBinder.Access.Accessor.cs constructed-generic receiver — same for the `Type[args]` receiver form. - ExpressionBinder.Access.MemberLookup.cs MapErasedIndexerElementType — indexer elements skipped substitution when HasSubstitutableTypeArgument saw no direct named tuple; also the #2365 recursive projection filter. - MemberLookup.cs generic-return construction (anyParam) and the indexer property projection. - ConversionClassifier.cs parameter substitution. - Binder.cs ProjectGenericArgument (type-clause path). New NestedNamedTupleProjectionTests pin all four shapes end to end, including the exact selfmig iteration+index+member chain. Full Core.Tests green (8218), local selfmig proof shows the three real Translator compile errors gone. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Nng28yiBdPVdeML7mSZphs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the remaining systemic failure in the second 2026-08-29 selfmig nightly (run 33260247720, which already included #3630/#3631): 32/52 green against floor 33, with migrated Cs2Gs.Translator failing
GS0158 Cannot find member Symbol/GS0159 Cannot find function Contains/GS0116 not indexableatCSharpToGSharpTranslator.Constructors.gs:1537-38—candidate[0].Symbolandreach[head].Contains(symbol)overList[List[(syntax …, symbol …)]]— cascading into 11 downstream apps.Root cause
A named tuple nested inside a generic type argument shares its CLR backing with the unnamed shape (
ValueTuple<…>), so any keep-symbolic gate that consults onlyRequiresSymbolicProjection(or a directis TupleTypeSymbol) collapses the constructed type to its erased CLR form — and the element names vanish, so member access by name fails. The #3622 projection-gate family covered direct named-tuple arguments (List[(a, b)], one level), but notList[List[(a, b)]],List[[](a, b)], orDictionary[K, (a, b)]reached through construction, indexing, or iteration. Minimal repro (failed before, runs now):Fix
Widened six keep-symbolic gates with
TypeSymbol.ContainsNamedTupleElements(already recursive through every constructor shape): the generic ctor-call type-argument resolution (the erasure at the root), the constructed-generic receiver form, the indexer element substitution + its #2365 recursive projection filter, the generic-return construction and indexer property projection in MemberLookup, the conversion-classifier parameter substitution, and the type-clauseProjectGenericArgument. Deliberately did not widenImportedTypeSymbol.HasSubstitutableTypeArgumentitself — it feeds conversion/lowering decisions with broader meaning, and widening it regressed working cases during investigation.Verification
NestedNamedTupleProjectionTests(4 end-to-end oracle tests) pin all shapes, including the exact selfmig iteration+index+member chain with an imported interface element type.GSharpRoundTrip.gsreferencing GSharp.Core, which the subtree run excludes from migration; the nightly migrates it).With this plus #3630/#3631, the next nightly should clear the
b7a89d8f22f8/0a665d0d062c/ebe7e1f2f6f8fingerprint family. The!!ceiling breach (17516 vs 17400) is a separate ratchet question.🤖 Generated with Claude Code
https://claude.ai/code/session_01Nng28yiBdPVdeML7mSZphs