Fix ICE on named-arg indexer setter (#16034)#19851
Conversation
Co-authored-by: Copilot <[email protected]>
When a named argument matches one of the indexer arguments of a property setter, the remaining unnamed called args may number fewer than 2. The ParamArray detection used nUnnamedCalledArgs-2 unconditionally for indexer setters, leading to a negative index and FS0193. Gate the setter-shape indexing on nUnnamedCalledArgs >= 2 and fall back to the regular path otherwise. Also skip the unnamed-arg-prefix deprecation check for indexer setters, since the trailing 'value' arg breaks the strict (i,j) position match when an indexer arg is supplied by name. Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
❗ Release notes requiredYou can open this PR in browser to add release notes: open in github.dev
|
- Moved release note entry from 9.0.300.md to 11.0.100.md (correct version) - Replaced 4-line prose comment with a single-line code example Co-authored-by: Copilot <[email protected]>
T-Gro
left a comment
There was a problem hiding this comment.
Review of PR #19851 — Fix ICE on named-arg indexer setter (#16034)
Overall: This is a clean, well-targeted fix for a genuine ICE (internal compiler error). The core logic is correct and the tests are comprehensive. Approving with minor observations.
✅ What works well
-
MethodCalls.fs guard — The
useIndexerSetterShapevariable cleanly separates the concern: only use the setter-specific ParamArray path when there are actually ≥2 unnamed called args. This prevents the negative-index crash without changing behavior for the common case. -
Tests — Good coverage of the exact repro (single-index named arg), multi-index scenarios, extension properties, getter verification, and multiple call shapes via
[<Theory>]. -
Minimal surface area — The new
IsIndexerSettermember is a simple delegation of existing state, well-placed next toIsIndexParamArraySetter.
📝 Observations (non-blocking)
-
PR description mentions ConstraintSolver.fs — The body states "Fix a minor issue in ConstraintSolver.fs where a property-setter indexer arg count was off-by-one" but no such change appears in the diff. This should be removed from the description to avoid confusion for future readers.
-
Deprecation check suppression breadth (CheckExpressions.fs:10575) — The new
not finalCalledMeth.IsIndexerSetterguard suppresses thetcUnnamedArgumentsDoNotFormPrefixwarning for all indexer setters, not only those with named args. This is safe in practice — without named args the unnamed positions will match(i, j)anyway and the check passes — but a comment explaining why the blanket suppression is harmless would help future readers:// Indexer setters: when index args are named, the remaining unnamed args' // Position values won't form a prefix (the 'value' arg has a non-zero j). // Without named args the check passes naturally, so blanket skip is safe.
-
Missing doc comment on
IsIndexerSetter(MethodCalls.fsi:274) — A one-line XML doc like/// True when this method call is for a property indexer setter (set_Item or named indexer set)would align with the surrounding style.
Summary
The fix correctly guards the ParamArray detection against the case where named arguments reduce the unnamed-arg count below the expected minimum for indexer setters, and correctly suppresses a false-positive deprecation warning. No functional issues found.
- Add XML doc comment on IsIndexerSetter in MethodCalls.fsi - Add comment explaining why blanket indexer setter suppression is safe - PR description updated to remove incorrect ConstraintSolver.fs mention Co-authored-by: Copilot <[email protected]>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
The merge with main inadvertently dropped the NoWarn;MSB3277 entries from fsc.targets and fsi.targets. These suppress a build-time conflict between System.ValueTuple 4.0.2.0 (.NET Framework 4.7.2 facade) and 4.0.5.0 (pulled transitively by System.Text.Json/System.Formats.Nrbf). Binding redirects handle this at runtime; the warning is harmless. Co-authored-by: Copilot <[email protected]>
Branch was behind main again. Auto-merge resolved IlxGen.fs, Optimizer.fs, TypedTreeOps.ExprConstruction.fs, and one baseline cleanly. Verified post-merge: SEQ=PAR FCS.dll byte-identical, sin/abs quotation passes. (#19928) Co-authored-by: Copilot <[email protected]>
Summary
Fixes #16034 — calling an indexed property setter with a named argument (e.g.
.indexed1(a1="ok") <- 1) caused an internal compiler error (FS0193 / ArgumentException: The input must be non-negative).Root Cause
When a named argument matches one of the indexer arguments of a property setter, the remaining unnamed called args may number fewer than 2. The ParamArray detection in MethodCalls.fs used
UnnamedCalledArgs - 2unconditionally for indexer setters, leading to a negative index into calledArgs.Fix
UnnamedCalledArgs >= 2and fall back to the regular path otherwise.Tests
Added IndexedSetterNamedArgTests.fs covering:
All variants compile and typecheck without error.