Repository navigation
MacroCompiler: AEval()/AEvalA() with a codeblock literal (implicit reference conversion to interfaces) - #2114
Merged
RobertvanderHulst merged 2 commits intoOct 23, 2026
Conversation
Calling AEval()/AEvalA() with a codeblock literal from a macro or script always failed with "error XM0205: No suitable overload". The literal has type XSharp.Codeblock and the parameter is ICodeblock, but the reference conversion check used Type.IsSubclassOf(), which only looks at base classes and never at implemented interfaces. Use IsAssignableFrom() for the implicit (and the reverse explicit) reference conversion instead. Added AEval/AEvalA tests to the script tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Problem
AEval()andAEvalA()can't be called from a macro or script with a codeblock literal:This also fails with the optional start/count arguments, and for a plain macro
aeval({1,2}, {|x| x}). Passing a USUAL that holds a codeblock works, and so doesAScan(), because its parameter is a USUAL.Cause
The codeblock literal has the type
XSharp.Codeblock, and the parameter has the typeICodeblock. InBinder.Conversion(), the reference conversion check usesType.IsSubclassOf(). That method only looks at base classes and never at implemented interfaces. So no conversion was found, and every non-generic overload was rejected. The genericAEval<T>overloads are rejected anyway by the open-generic check.Change
Binder.Conversion.cs: useIsAssignableFrom()instead ofIsSubclassOf():For class to class conversions this gives the same result as before. The identity case is handled earlier by
TypesMatch().Tests
ScriptTests.prg: four new tests:aevalthroughCompileand throughCompileCodeblockaevalwith start/countaevalaCompileandCompileCodeblock. All cases failed with XM0205 before the change and pass after it.DbCreatein the UDC tests in both runs, so the tests after that point did not run.GetScriptCompiler()+CompileCodeblock(), together with MacroCompiler: nested codeblocks can use LOCALs of the enclosing script/codeblock #2113.Relation to #2113
This fixes the
AEval()side note in #2113. The two PRs are independent. Together, a script can useaeval(a, {|x| nSum += x})with a LOCALnSum. Both PRs add tests at the same place inScriptTests.prg, so whichever one is merged second will have a trivial conflict there: keep both test blocks.🤖 Generated with Claude Code