Skip to content

Commit bc0ff2f

Browse files
marek-safarjoncham
authored andcommitted
[mcs] Support implicit user conversion from nullable type without unwrapping. Fixes #60900 (case 970493)
1 parent 3d4bb39 commit bc0ff2f

File tree

5 files changed

+63
-3
lines changed

5 files changed

+63
-3
lines changed

mcs/errors/cs0151-4.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// CS0151: A switch expression of type `S1?' cannot be converted to an integral type, bool, char, string, enum or nullable type
2-
// Line: 24
2+
// Line: 25
3+
// Compiler options: -langversion:5
34

45
using System;
56

mcs/errors/known-issues-net_4_x

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
# Parser problems
1515
cs0080.cs
1616

17+
# Undocumented switch governing rules
18+
cs0151-4.cs NO ERROR
19+
1720
# Operators
1821
cs0457-2.cs
1922
cs0457.cs

mcs/mcs/convert.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,13 @@ public static Expression UserDefinedConversion (ResolveContext rc, Expression so
12321232
FindApplicableUserDefinedConversionOperators (rc, operators, source_type_expr, target_type, restr, ref candidates);
12331233
}
12341234

1235+
if (source_type_expr == source && source_type.IsNullableType) {
1236+
operators = MemberCache.GetUserOperator (source_type.TypeArguments [0], Operator.OpType.Implicit, declared_only);
1237+
if (operators != null) {
1238+
FindApplicableUserDefinedConversionOperators (rc, operators, source_type_expr, target_type, restr, ref candidates);
1239+
}
1240+
}
1241+
12351242
if (!implicitOnly) {
12361243
operators = MemberCache.GetUserOperator (source_type, Operator.OpType.Explicit, declared_only);
12371244
if (operators != null) {

mcs/tests/gtest-647.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System;
2+
3+
public class Program
4+
{
5+
public static int Main ()
6+
{
7+
int B = default (MyStruct?);
8+
if (MyStruct.counter != 1)
9+
return 1;
10+
11+
switch (default (MyStruct?)) {
12+
case 0:
13+
break;
14+
default:
15+
return 2;
16+
}
17+
18+
if (MyStruct.counter != 2)
19+
return 4;
20+
21+
return 0;
22+
}
23+
24+
public struct MyStruct
25+
{
26+
public static int counter;
27+
28+
public static implicit operator int (MyStruct? s)
29+
{
30+
++counter;
31+
return 0;
32+
}
33+
}
34+
}

mcs/tests/ver-il-net_4_x.xml

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11064,7 +11064,7 @@
1106411064
</type>
1106511065
<type name="X">
1106611066
<method name="Int32 Beer(System.Nullable`1[IrishPub])" attrs="145">
11067-
<size>72</size>
11067+
<size>60</size>
1106811068
</method>
1106911069
<method name="Int32 Test(System.Nullable`1[System.Int32])" attrs="145">
1107011070
<size>62</size>
@@ -19505,7 +19505,7 @@
1950519505
</type>
1950619506
<type name="C">
1950719507
<method name="Int32 Main()" attrs="150">
19508-
<size>267</size>
19508+
<size>255</size>
1950919509
</method>
1951019510
<method name="Void .ctor()" attrs="6278">
1951119511
<size>7</size>
@@ -20144,6 +20144,21 @@
2014420144
</method>
2014520145
</type>
2014620146
</test>
20147+
<test name="gtest-647.cs">
20148+
<type name="Program">
20149+
<method name="Int32 Main()" attrs="150">
20150+
<size>99</size>
20151+
</method>
20152+
<method name="Void .ctor()" attrs="6278">
20153+
<size>7</size>
20154+
</method>
20155+
</type>
20156+
<type name="Program+MyStruct">
20157+
<method name="Int32 op_Implicit(System.Nullable`1[Program+MyStruct])" attrs="2198">
20158+
<size>22</size>
20159+
</method>
20160+
</type>
20161+
</test>
2014720162
<test name="gtest-anontype-01.cs">
2014820163
<type name="Test">
2014920164
<method name="Int32 Main()" attrs="150">

0 commit comments

Comments
 (0)