Skip to content

gsc: awaited imported Task[(named)] keeps element names (ADR-0172, #3501) - #3625

Merged
DavidObando merged 1 commit into
mainfrom
fix/await-named-tuple-element
Aug 29, 2026
Merged

DavidObando merged 1 commit into
mainfrom
fix/await-named-tuple-element

Conversation

@DavidObando

Copy link
Copy Markdown
Owner

Summary

Follow-up to #3622: the code-exploder gate's GS0158: Cannot find member AnalysisId family. An imported awaitable whose signature carries reference-nullability metadata arrives wrapped in NullabilityAnnotatedTypeSymbol, hiding the symbolic constructed Task from TryGetTaskElementType's #2195 fast path — the CLR fallback rebuilt the element from the closed ValueTuple and erased its names, so (await store.RetryAsync(id)).AnalysisId failed to bind. Fix: unwrap to the symbolic base exactly when a type argument carries named-tuple content (ContainsNamedTupleElements gate, matching the #3622 projection-gate family); the base's arguments already carry their element nullability.

Verified on the pinned code-exploder Task<(Guid AnalysisId, string? GitRef)?> shape reduced to a minimal cross-assembly repro (compiles + runs), plus a new round-trip test covering await element access and an if-let unwrap of an awaited nullable named tuple. Async/await suites green (Compiler.Tests 326, Core.Tests 453).

Known follow-up (pre-existing, reproduced without this change): an async-function if let over a non-awaited imported call returning Nullable<ValueTuple<…>>-with-names emits invalid IL — ILVerify StackUnexpected: found Nullobjref, expected Nullable<ValueTuple<int32,string>> in MoveNext — filing separately.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Nng28yiBdPVdeML7mSZphs

)

An imported awaitable whose signature carries reference-nullability
metadata arrives wrapped in a NullabilityAnnotatedTypeSymbol, hiding
the symbolic constructed Task from TryGetTaskElementType's #2195 fast
path — the CLR fallback then rebuilt the element from the closed
ValueTuple and erased its names, so `(await Store.RetryAsync(id)).X`
died with GS0158 (the code-exploder gate's `Cannot find member
AnalysisId` family). Unwrap to the symbolic base exactly when a type
argument carries named-tuple content; the base's arguments already
carry their element nullability.

Regression test: cross-assembly async round trip covering both a plain
`await` element access and an if-let unwrap of an awaited nullable
named tuple.

Known follow-up (pre-existing, reproduced without this change): an
async-function `if let` over a NON-awaited imported call returning
`Nullable<ValueTuple<…>>` with names emits invalid IL — ILVerify
StackUnexpected `found Nullobjref, expected Nullable<ValueTuple<int32,
string>>` in MoveNext — filed separately.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nng28yiBdPVdeML7mSZphs
@DavidObando
DavidObando enabled auto-merge (squash) August 29, 2026 02:43
@DavidObando
DavidObando merged commit 735ec0e into main Aug 29, 2026
36 checks passed
@DavidObando
DavidObando deleted the fix/await-named-tuple-element branch August 29, 2026 03:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant