Fix #4332: string[].Contains parse failure under C# 14 + nullable + method init#4333
Merged
jeremydmiller merged 1 commit intomasterfrom May 6, 2026
Merged
Conversation
C# 14 with <Nullable>enable</Nullable> wraps captured-closure string[]
locals that were initialised from a method-typed return with an extra
Convert() before the implicit string[] -> ReadOnlySpan<string>:
s => op_Implicit(Convert(closureField, String[])).Contains(s.Name)
UnwrapConversions only peeled op_Implicit, so the receiver failed to
reduce to a constant, parsing fell through to ParseWhereForContains,
and CompileFast'ing the whole Where lambda threw
InvalidOperationException about the lambda parameter not being in
scope. Strip Convert/ConvertChecked unaries (and op_Explicit) in a
loop alongside op_Implicit so any stacked wrapper combination
canonicalises to the captured field.
Closes #4332.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 7, 2026
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.
Summary
Fixes #4332.
C# 14 with
<Nullable>enable</Nullable>wraps captured-closurestring[]locals that were initialised from a method-typed return (var v = MakeStrings();) with an extraConvert()before the implicitstring[] -> ReadOnlySpan<string>conversion:MemoryExtensionsContains.UnwrapConversionsonly peeled the outerop_ImplicitMethodCallExpression, leaving the innerConvertUnaryExpressionin place. The receiver then failedTryToParseConstant, parsing fell through toValueCollectionMember.ParseWhereForContains, andCompileFast'ing the wholeWherelambda threwInvalidOperationException: variable 's' ... referenced from scope '', but it is not definedat parse time.The fix strips
Convert/ConvertCheckedUnaryExpressions (andop_Explicit) in a loop alongsideop_Implicit, so any stacked wrapper combination canonicalises to the captured field and reduces cleanly to a constant. The query then takes the fastIsOneOfFilterpath that the literal-init /.ToList()workaround was already hitting.Test plan
Bug_4332_string_array_contains_under_nullable_method_initwith two facts:can_query_when_string_array_local_is_method_initialised— natural-pattern repro using#nullable enable+var values = MakeNames(...);(triggers under net10.0 / C# 14)can_query_when_collection_expression_has_convert_wrapper— builds the failingConvert(closureField, string[])expression by hand so the bug reproduces deterministically on every TFMmasterwith the exactInvalidOperationExceptionfrom the issue and pass with the fix applied.LinqTestssuite green on net10.0: 1260 passed / 1 skipped (pre-existing) / 0 failed.🤖 Generated with Claude Code