diff options
author | Marek Safar <marek.safar@gmail.com> | 2017-12-22 02:49:48 +0300 |
---|---|---|
committer | Bernhard Urban <bernhard.urban@xamarin.com> | 2017-12-22 17:31:45 +0300 |
commit | 6e885dec43b2e275822e9372412a7077287fd484 (patch) | |
tree | 8d7e7917ca6a65dc6d674d40d320aba8a51344e8 /mcs | |
parent | 492f66c60f7ca3bb7b88b231e2d8f42f8347f1ee (diff) |
[mcs] Support implicit user conversion from nullable type without unwrapping. Fixes #60900
Diffstat (limited to 'mcs')
-rw-r--r-- | mcs/errors/cs0151-4.cs | 3 | ||||
-rw-r--r-- | mcs/errors/known-issues-net_4_x | 3 | ||||
-rw-r--r-- | mcs/mcs/convert.cs | 7 | ||||
-rw-r--r-- | mcs/tests/gtest-647.cs | 34 | ||||
-rw-r--r-- | mcs/tests/ver-il-net_4_x.xml | 19 |
5 files changed, 63 insertions, 3 deletions
diff --git a/mcs/errors/cs0151-4.cs b/mcs/errors/cs0151-4.cs index 0e45b1a9049..c9e05589e4d 100644 --- a/mcs/errors/cs0151-4.cs +++ b/mcs/errors/cs0151-4.cs @@ -1,5 +1,6 @@ // CS0151: A switch expression of type `S1?' cannot be converted to an integral type, bool, char, string, enum or nullable type -// Line: 24 +// Line: 25 +// Compiler options: -langversion:5 using System; diff --git a/mcs/errors/known-issues-net_4_x b/mcs/errors/known-issues-net_4_x index c9ed9317350..54902e03e7b 100644 --- a/mcs/errors/known-issues-net_4_x +++ b/mcs/errors/known-issues-net_4_x @@ -14,6 +14,9 @@ # Parser problems cs0080.cs +# Undocumented switch governing rules +cs0151-4.cs NO ERROR + # Operators cs0457-2.cs cs0457.cs diff --git a/mcs/mcs/convert.cs b/mcs/mcs/convert.cs index f4012fbd222..2fd5bcc5585 100644 --- a/mcs/mcs/convert.cs +++ b/mcs/mcs/convert.cs @@ -1232,6 +1232,13 @@ namespace Mono.CSharp { FindApplicableUserDefinedConversionOperators (rc, operators, source_type_expr, target_type, restr, ref candidates); } + if (source_type_expr == source && source_type.IsNullableType) { + operators = MemberCache.GetUserOperator (source_type.TypeArguments [0], Operator.OpType.Implicit, declared_only); + if (operators != null) { + FindApplicableUserDefinedConversionOperators (rc, operators, source_type_expr, target_type, restr, ref candidates); + } + } + if (!implicitOnly) { operators = MemberCache.GetUserOperator (source_type, Operator.OpType.Explicit, declared_only); if (operators != null) { diff --git a/mcs/tests/gtest-647.cs b/mcs/tests/gtest-647.cs new file mode 100644 index 00000000000..4aae641f85f --- /dev/null +++ b/mcs/tests/gtest-647.cs @@ -0,0 +1,34 @@ +using System; + +public class Program +{ + public static int Main () + { + int B = default (MyStruct?); + if (MyStruct.counter != 1) + return 1; + + switch (default (MyStruct?)) { + case 0: + break; + default: + return 2; + } + + if (MyStruct.counter != 2) + return 4; + + return 0; + } + + public struct MyStruct + { + public static int counter; + + public static implicit operator int (MyStruct? s) + { + ++counter; + return 0; + } + } +}
\ No newline at end of file diff --git a/mcs/tests/ver-il-net_4_x.xml b/mcs/tests/ver-il-net_4_x.xml index e4156fbdb05..d57416d8e0b 100644 --- a/mcs/tests/ver-il-net_4_x.xml +++ b/mcs/tests/ver-il-net_4_x.xml @@ -11064,7 +11064,7 @@ </type> <type name="X"> <method name="Int32 Beer(System.Nullable`1[IrishPub])" attrs="145"> - <size>72</size> + <size>60</size> </method> <method name="Int32 Test(System.Nullable`1[System.Int32])" attrs="145"> <size>62</size> @@ -19508,7 +19508,7 @@ </type> <type name="C"> <method name="Int32 Main()" attrs="150"> - <size>267</size> + <size>255</size> </method> <method name="Void .ctor()" attrs="6278"> <size>7</size> @@ -20147,6 +20147,21 @@ </method> </type> </test> + <test name="gtest-647.cs"> + <type name="Program"> + <method name="Int32 Main()" attrs="150"> + <size>99</size> + </method> + <method name="Void .ctor()" attrs="6278"> + <size>7</size> + </method> + </type> + <type name="Program+MyStruct"> + <method name="Int32 op_Implicit(System.Nullable`1[Program+MyStruct])" attrs="2198"> + <size>22</size> + </method> + </type> + </test> <test name="gtest-anontype-01.cs"> <type name="Test"> <method name="Int32 Main()" attrs="150"> |