Repository navigation
A Ruby string prefers System::String over System::Boolean in overload resolution - #5
Merged
Merged
Conversation
… resolution
Any argument converts to Boolean on narrowing level 2, the level of MutableString's
explicit conversions, so a Ruby string tied String and Boolean overloads:
System::IO::BinaryWriter#Write("abc") raised AmbiguousMatchException (Boolean, Byte[],
Char, String; Write has no Object overload). The String-over-Byte[] rule in
SelectBestConversionFor now covers Boolean too, and PreferConvert already orders
String over Char. nil, symbols and other non-string arguments resolve as before.
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.
Follow-up to #4, which added the String-over-Byte[] rule.
Problem
MutableString has explicit conversions to String, Byte[] and Char, and
Converter.CanConvertFromlets any argument convert to Boolean. All four are on narrowing level 2, andWritehas no Object overload to catch the argument earlier. #4 settles String vs Byte[] andPreferConvertalready settles String vs Char, but String vs Boolean still ends upAmbiguousin the DLR'sGetPreferredParameter.Change
RubyOverloadResolver.SelectBestConversionFornow prefers String over Boolean as well as over Byte[] for a MutableString argument. Neitherboolnorbyte[]has a default protocol conversion, so for a Ruby string a Boolean parameter is only reachable at level 2. The rule therefore only changes comparisons that used to be ambiguous.These still resolve as before, because the rule only applies to a MutableString argument:
nilis still ambiguous (it goes through the separate nil branch).Inst.BoolinClrConversions1has a single overload, so it never gets here.Tests
ClrOverloadSelection4(new, registered inRubyTests.cs):F(String)/F(Boolean)with strings,true/false,1,Object.new,niland:foo, andBinaryWriter#Writewith a string, a CLR string, a Boolean, a Byte[], a Char andnil.OverloadResolution_Numeric1: newProws (String/Boolean) andQrows (the fourWriteoverloads a Ruby string reaches).This was not built locally (no .NET SDK on that machine), so this CI run is the first build and test run. The 4.0.0-preview1 release reproduces the bug. Every line of the new
BinaryWritertest that doesn't depend on the fix already matches that release's output exactly.Known edge case
For overloads like
F(String, Double)/F(Boolean, Int32)called as("s", 1), the second argument used to decide, and the string was silently passed astrue. That call is now ambiguous. The Byte[] rule from #4 has the same effect.Not covered here: a Ruby subclass of String (
class S < String) still makesWritewritetrue. The DLR doesn't find MutableString's conversion operators for the subclass's CLR type, so only Boolean applies at level 2. That's a conversion bug, not a tie, and is left for a separate change.