Skip to content

Commit 248377d

Browse files
yevhenclaude
andcommitted
Harden expression evaluation with fallbacks and sentinels
Fixes InvalidProgramException when runtime emits incorrect JIT-code 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 6c48d54 commit 248377d

12 files changed

Lines changed: 1091 additions & 28 deletions

File tree

CLAUDE.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,3 +415,11 @@ async\method: Suffix with `Async` =\> `GetDataAsync()`
415415
- **CRITICAL**: Explain the "why" not just the "what"
416416
- **CRITICAL**: Always write XML doc comments from the user's perspective, not implementation details
417417
- Cover common pitfalls and best practices
418+
419+
- Expression compilation can emit invalid IL on some runtimes; fall back to `Compile(preferInterpretation: true)` when evaluating expressions to avoid CI-only `InvalidProgramException`.
420+
- Byref-like expression trees (e.g., `Span<T>`, `ReadOnlySpan<T>`) cannot be boxed; convert them to arrays before evaluation to avoid interpreter type load errors.
421+
- Reflection helpers should tolerate missing overloads (e.g., `MemoryExtensions.ToArray`) to prevent type initializer failures on runtimes where a method shape differs.
422+
- Compilation can fail with `TypeLoadException`/`ArgumentException` in addition to `InvalidProgramException`; catch broadly and fall back to interpreted compilation or a safe null-returning delegate.
423+
- Prefer `Compile(preferInterpretation: true)` for expression value extraction to avoid invalid IL, and only drop to null when both interpreted compilation and span normalization fail.
424+
- If evaluation still fails, return a sentinel (e.g., `EvaluationUnavailable`) and render `<unavailable: reason>` so diagnostics stay honest instead of showing nulls or bogus counts.
425+
- `NUnit.Assert.ThrowsAsync<T>()` returns the exception instance (not a `Task`), so async tests should await a real async assertion (e.g., `action.Should().ThrowAsync<T>()`) to avoid CS1998 warnings.

0 commit comments

Comments
 (0)