~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/nrefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExplicitConversionsTest.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
ļ»æ// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
 
2
// 
 
3
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
 
4
// software and associated documentation files (the "Software"), to deal in the Software
 
5
// without restriction, including without limitation the rights to use, copy, modify, merge,
 
6
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
 
7
// to whom the Software is furnished to do so, subject to the following conditions:
 
8
// 
 
9
// The above copyright notice and this permission notice shall be included in all copies or
 
10
// substantial portions of the Software.
 
11
// 
 
12
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 
13
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 
14
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 
15
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 
16
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
17
// DEALINGS IN THE SOFTWARE.
 
18
 
 
19
using System;
 
20
using System.Collections.Generic;
 
21
using System.Linq;
 
22
using NUnit.Framework;
 
23
using ICSharpCode.NRefactory.TypeSystem;
 
24
using ICSharpCode.NRefactory.Semantics;
 
25
 
 
26
namespace ICSharpCode.NRefactory.CSharp.Resolver
 
27
{
 
28
        using dynamic = ICSharpCode.NRefactory.TypeSystem.ReflectionHelper.Dynamic;
 
29
        using C = Conversion;
 
30
        
 
31
        [TestFixture]
 
32
        public class ExplicitConversionsTest : ResolverTestBase
 
33
        {
 
34
                CSharpConversions conversions;
 
35
                
 
36
                public override void SetUp()
 
37
                {
 
38
                        base.SetUp();
 
39
                        conversions = new CSharpConversions(compilation);
 
40
                }
 
41
                
 
42
                Conversion ExplicitConversion(Type from, Type to)
 
43
                {
 
44
                        IType from2 = compilation.FindType(from);
 
45
                        IType to2 = compilation.FindType(to);
 
46
                        return conversions.ExplicitConversion(from2, to2);
 
47
                }
 
48
                
 
49
                [Test]
 
50
                public void PointerConversion()
 
51
                {
 
52
                        Assert.AreEqual(C.ExplicitPointerConversion, ExplicitConversion(typeof(int*), typeof(short)));
 
53
                        Assert.AreEqual(C.ExplicitPointerConversion, ExplicitConversion(typeof(short), typeof(void*)));
 
54
                        
 
55
                        Assert.AreEqual(C.ExplicitPointerConversion, ExplicitConversion(typeof(void*), typeof(int*)));
 
56
                        Assert.AreEqual(C.ExplicitPointerConversion, ExplicitConversion(typeof(long*), typeof(byte*)));
 
57
                }
 
58
                
 
59
                [Test]
 
60
                public void ConversionFromDynamic()
 
61
                {
 
62
                        // Explicit dynamic conversion is for resolve results only;
 
63
                        // otherwise it's an explicit reference / unboxing conversion
 
64
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(dynamic), typeof(string)));
 
65
                        Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(dynamic), typeof(int)));
 
66
                        
 
67
                        var dynamicRR = new ResolveResult(SpecialType.Dynamic);
 
68
                        Assert.AreEqual(C.ExplicitDynamicConversion, conversions.ExplicitConversion(dynamicRR, compilation.FindType(typeof(string))));
 
69
                        Assert.AreEqual(C.ExplicitDynamicConversion, conversions.ExplicitConversion(dynamicRR, compilation.FindType(typeof(int))));
 
70
                }
 
71
                
 
72
                [Test]
 
73
                public void NumericConversions()
 
74
                {
 
75
                        Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(sbyte), typeof(uint)));
 
76
                        Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(sbyte), typeof(char)));
 
77
                        Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(byte), typeof(char)));
 
78
                        Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(byte), typeof(sbyte)));
 
79
                        // if an implicit conversion exists, ExplicitConversion() should return that
 
80
                        Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(byte), typeof(int)));
 
81
                        Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(double), typeof(float)));
 
82
                        Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(double), typeof(decimal)));
 
83
                        Assert.AreEqual(C.ExplicitNumericConversion, ExplicitConversion(typeof(decimal), typeof(double)));
 
84
                        Assert.AreEqual(C.ImplicitNumericConversion, ExplicitConversion(typeof(int), typeof(decimal)));
 
85
                        
 
86
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(bool), typeof(int)));
 
87
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(int), typeof(bool)));
 
88
                }
 
89
                
 
90
                [Test]
 
91
                public void EnumerationConversions()
 
92
                {
 
93
                        var explicitEnumerationConversion = C.EnumerationConversion(false, false);
 
94
                        Assert.AreEqual(explicitEnumerationConversion, ExplicitConversion(typeof(sbyte), typeof(StringComparison)));
 
95
                        Assert.AreEqual(explicitEnumerationConversion, ExplicitConversion(typeof(char), typeof(StringComparison)));
 
96
                        Assert.AreEqual(explicitEnumerationConversion, ExplicitConversion(typeof(int), typeof(StringComparison)));
 
97
                        Assert.AreEqual(explicitEnumerationConversion, ExplicitConversion(typeof(decimal), typeof(StringComparison)));
 
98
                        Assert.AreEqual(explicitEnumerationConversion, ExplicitConversion(typeof(StringComparison), typeof(char)));
 
99
                        Assert.AreEqual(explicitEnumerationConversion, ExplicitConversion(typeof(StringComparison), typeof(int)));
 
100
                        Assert.AreEqual(explicitEnumerationConversion, ExplicitConversion(typeof(StringComparison), typeof(decimal)));
 
101
                        Assert.AreEqual(explicitEnumerationConversion, ExplicitConversion(typeof(StringComparison), typeof(StringSplitOptions)));
 
102
                }
 
103
                
 
104
                [Test]
 
105
                public void NullableConversion_BasedOnIdentityConversion()
 
106
                {
 
107
                        Assert.AreEqual(C.IdentityConversion, ExplicitConversion(typeof(ArraySegment<dynamic>?), typeof(ArraySegment<object>?)));
 
108
                        Assert.AreEqual(C.ImplicitNullableConversion, ExplicitConversion(typeof(ArraySegment<dynamic>), typeof(ArraySegment<object>?)));
 
109
                        Assert.AreEqual(C.ExplicitNullableConversion, ExplicitConversion(typeof(ArraySegment<dynamic>?), typeof(ArraySegment<object>)));
 
110
                }
 
111
                
 
112
                [Test]
 
113
                public void NullableConversion_BasedOnImplicitNumericConversion()
 
114
                {
 
115
                        Assert.AreEqual(C.ImplicitLiftedNumericConversion, ExplicitConversion(typeof(int?), typeof(long?)));
 
116
                        Assert.AreEqual(C.ImplicitLiftedNumericConversion, ExplicitConversion(typeof(int), typeof(long?)));
 
117
                        Assert.AreEqual(C.ExplicitLiftedNumericConversion, ExplicitConversion(typeof(int?), typeof(long)));
 
118
                }
 
119
                
 
120
                [Test]
 
121
                public void NullableConversion_BasedOnImplicitEnumerationConversion()
 
122
                {
 
123
                        ResolveResult zero = new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), 0);
 
124
                        ResolveResult one = new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), 1);
 
125
                        Assert.AreEqual(C.EnumerationConversion(true, true), conversions.ExplicitConversion(zero, compilation.FindType(typeof(StringComparison?))));
 
126
                        Assert.AreEqual(C.EnumerationConversion(false, true), conversions.ExplicitConversion(one, compilation.FindType(typeof(StringComparison?))));
 
127
                }
 
128
                
 
129
                [Test]
 
130
                public void NullableConversion_BasedOnExplicitNumericConversion()
 
131
                {
 
132
                        Assert.AreEqual(C.ExplicitLiftedNumericConversion, ExplicitConversion(typeof(int?), typeof(short?)));
 
133
                        Assert.AreEqual(C.ExplicitLiftedNumericConversion, ExplicitConversion(typeof(int), typeof(short?)));
 
134
                        Assert.AreEqual(C.ExplicitLiftedNumericConversion, ExplicitConversion(typeof(int?), typeof(short)));
 
135
                }
 
136
                
 
137
                [Test]
 
138
                public void NullableConversion_BasedOnExplicitEnumerationConversion()
 
139
                {
 
140
                        C c = C.EnumerationConversion(false, true); // c = explicit lifted enumeration conversion
 
141
                        Assert.AreEqual(c, ExplicitConversion(typeof(int?), typeof(StringComparison?)));
 
142
                        Assert.AreEqual(c, ExplicitConversion(typeof(int), typeof(StringComparison?)));
 
143
                        Assert.AreEqual(c, ExplicitConversion(typeof(int?), typeof(StringComparison)));
 
144
                        
 
145
                        Assert.AreEqual(c, ExplicitConversion(typeof(StringComparison?), typeof(int?)));
 
146
                        Assert.AreEqual(c, ExplicitConversion(typeof(StringComparison), typeof(int?)));
 
147
                        Assert.AreEqual(c, ExplicitConversion(typeof(StringComparison?), typeof(int)));
 
148
                        
 
149
                        Assert.AreEqual(c, ExplicitConversion(typeof(StringComparison?), typeof(StringSplitOptions?)));
 
150
                        Assert.AreEqual(c, ExplicitConversion(typeof(StringComparison), typeof(StringSplitOptions?)));
 
151
                        Assert.AreEqual(c, ExplicitConversion(typeof(StringComparison?), typeof(StringSplitOptions)));
 
152
                }
 
153
                
 
154
                [Test]
 
155
                public void ExplicitReferenceConversion_SealedClass()
 
156
                {
 
157
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(object), typeof(string)));
 
158
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable<char>), typeof(string)));
 
159
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(IEnumerable<int>), typeof(string)));
 
160
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(IEnumerable<object>), typeof(string)));
 
161
                        Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(string), typeof(IEnumerable<char>)));
 
162
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(string), typeof(IEnumerable<int>)));
 
163
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(string), typeof(IEnumerable<object>)));
 
164
                }
 
165
                
 
166
                [Test]
 
167
                public void ExplicitReferenceConversion_NonSealedClass()
 
168
                {
 
169
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(object), typeof(List<string>)));
 
170
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable<object>), typeof(List<string>)));
 
171
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable<string>), typeof(List<string>)));
 
172
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable<int>), typeof(List<string>)));
 
173
                        
 
174
                        Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(List<string>), typeof(IEnumerable<object>)));
 
175
                        Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(List<string>), typeof(IEnumerable<string>)));
 
176
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(List<string>), typeof(IEnumerable<int>)));
 
177
                        
 
178
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(List<string>), typeof(List<object>)));
 
179
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(List<string>), typeof(List<int>)));
 
180
                }
 
181
                
 
182
                [Test]
 
183
                public void ExplicitReferenceConversion_Interfaces()
 
184
                {
 
185
                        Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable<string>), typeof(IEnumerable<object>)));
 
186
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable<int>), typeof(IEnumerable<object>)));
 
187
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable<object>), typeof(IEnumerable<string>)));
 
188
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable<object>), typeof(IEnumerable<int>)));
 
189
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable<object>), typeof(IConvertible)));
 
190
                }
 
191
                
 
192
                [Test]
 
193
                public void ExplicitReferenceConversion_Arrays()
 
194
                {
 
195
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(object[]), typeof(string[])));
 
196
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(dynamic[]), typeof(string[])));
 
197
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(object[]), typeof(object[,])));
 
198
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(object[]), typeof(int[])));
 
199
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(short[]), typeof(int[])));
 
200
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(Array), typeof(int[])));
 
201
                }
 
202
                
 
203
                [Test]
 
204
                public void ExplicitReferenceConversion_InterfaceToArray()
 
205
                {
 
206
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(ICloneable), typeof(int[])));
 
207
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable<string>), typeof(string[])));
 
208
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable<object>), typeof(string[])));
 
209
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable<string>), typeof(object[])));
 
210
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable<string>), typeof(dynamic[])));
 
211
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(IEnumerable<int>), typeof(int[])));
 
212
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(IEnumerable<string>), typeof(object[,])));
 
213
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(IEnumerable<short>), typeof(object[])));
 
214
                }
 
215
                
 
216
                [Test]
 
217
                public void ExplicitReferenceConversion_ArrayToInterface()
 
218
                {
 
219
                        Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(int[]), typeof(ICloneable)));
 
220
                        Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(string[]), typeof(IEnumerable<string>)));
 
221
                        Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(string[]), typeof(IEnumerable<object>)));
 
222
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(object[]), typeof(IEnumerable<string>)));
 
223
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(dynamic[]), typeof(IEnumerable<string>)));
 
224
                        Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(int[]), typeof(IEnumerable<int>)));
 
225
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(object[,]), typeof(IEnumerable<string>)));
 
226
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(object[]), typeof(IEnumerable<short>)));
 
227
                }
 
228
                
 
229
                [Test]
 
230
                public void ExplicitReferenceConversion_Delegates()
 
231
                {
 
232
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(MulticastDelegate), typeof(Action)));
 
233
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(Delegate), typeof(Action)));
 
234
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(ICloneable), typeof(Action)));
 
235
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(System.Threading.ThreadStart), typeof(Action)));
 
236
                }
 
237
                
 
238
                [Test]
 
239
                public void ExplicitReferenceConversion_GenericDelegates()
 
240
                {
 
241
                        Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(Action<object>), typeof(Action<string>)));
 
242
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(Action<string>), typeof(Action<object>)));
 
243
                        
 
244
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(Func<object>), typeof(Func<string>)));
 
245
                        Assert.AreEqual(C.ImplicitReferenceConversion, ExplicitConversion(typeof(Func<string>), typeof(Func<object>)));
 
246
                        
 
247
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(Action<IFormattable>), typeof(Action<IConvertible>)));
 
248
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(Action<IFormattable>), typeof(Action<int>)));
 
249
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(Action<string>), typeof(Action<IEnumerable<int>>)));
 
250
                        
 
251
                        Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(Func<IFormattable>), typeof(Func<IConvertible>)));
 
252
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(Func<IFormattable>), typeof(Func<int>)));
 
253
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(Func<string>), typeof(Func<IEnumerable<int>>)));
 
254
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(Func<string>), typeof(Func<IEnumerable<int>>)));
 
255
                }
 
256
                
 
257
                [Test]
 
258
                public void UnboxingConversion()
 
259
                {
 
260
                        Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(object), typeof(int)));
 
261
                        Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(object), typeof(decimal)));
 
262
                        Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(ValueType), typeof(int)));
 
263
                        Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(IFormattable), typeof(int)));
 
264
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(IEnumerable<object>), typeof(int)));
 
265
                        Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(Enum), typeof(StringComparison)));
 
266
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(Enum), typeof(int)));
 
267
                }
 
268
                
 
269
                [Test]
 
270
                public void LiftedUnboxingConversion()
 
271
                {
 
272
                        Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(object), typeof(int?)));
 
273
                        Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(object), typeof(decimal?)));
 
274
                        Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(ValueType), typeof(int?)));
 
275
                        Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(IFormattable), typeof(int?)));
 
276
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(IEnumerable<object>), typeof(int?)));
 
277
                        Assert.AreEqual(C.UnboxingConversion, ExplicitConversion(typeof(Enum), typeof(StringComparison?)));
 
278
                        Assert.AreEqual(C.None, ExplicitConversion(typeof(Enum), typeof(int?)));
 
279
                }
 
280
                Conversion ResolveCast(string program)
 
281
                {
 
282
                        return Resolve<ConversionResolveResult>(program).Conversion;
 
283
                }
 
284
                
 
285
                [Test]
 
286
                public void ObjectToTypeParameter()
 
287
                {
 
288
                        string program = @"using System;
 
289
class Test {
 
290
        public void M<T>(object o) {
 
291
                T t = $(T)o$;
 
292
        }
 
293
}";
 
294
                        Assert.AreEqual(C.UnboxingConversion, ResolveCast(program));
 
295
                }
 
296
                
 
297
                [Test]
 
298
                public void UnrelatedClassToTypeParameter()
 
299
                {
 
300
                        string program = @"using System;
 
301
class Test {
 
302
        public void M<T>(string o) {
 
303
                T t = $(T)o$;
 
304
        }
 
305
}";
 
306
                        Assert.AreEqual(C.None, ResolveCast(program));
 
307
                }
 
308
                
 
309
                [Test]
 
310
                public void IntefaceToTypeParameter()
 
311
                {
 
312
                        string program = @"using System;
 
313
class Test {
 
314
        public void M<T>(IDisposable o) {
 
315
                T t = $(T)o$;
 
316
        }
 
317
}";
 
318
                        Assert.AreEqual(C.UnboxingConversion, ResolveCast(program));
 
319
                }
 
320
                
 
321
                [Test]
 
322
                public void TypeParameterToInterface()
 
323
                {
 
324
                        string program = @"using System;
 
325
class Test {
 
326
        public void M<T>(T t) {
 
327
                IDisposable d = $(IDisposable)t$;
 
328
        }
 
329
}";
 
330
                        Assert.AreEqual(C.BoxingConversion, ResolveCast(program));
 
331
                }
 
332
                
 
333
                [Test]
 
334
                public void ValueTypeToTypeParameter()
 
335
                {
 
336
                        string program = @"using System;
 
337
class Test {
 
338
        public void M<T>(ValueType o) where T : struct {
 
339
                T t = $(T)o$;
 
340
        }
 
341
}";
 
342
                        Assert.AreEqual(C.UnboxingConversion, ResolveCast(program));
 
343
                }
 
344
                
 
345
                [Test]
 
346
                public void InvalidTypeParameterConversion()
 
347
                {
 
348
                        string program = @"using System;
 
349
class Test {
 
350
        public void M<T, U>(T t) {
 
351
                U u = $(U)t$;
 
352
        }
 
353
}";
 
354
                        Assert.AreEqual(C.None, ResolveCast(program));
 
355
                }
 
356
                
 
357
                [Test]
 
358
                public void TypeParameterConversion1()
 
359
                {
 
360
                        string program = @"using System;
 
361
class Test {
 
362
        public void M<T, U>(T t) where T : U {
 
363
                U u = $(U)t$;
 
364
        }
 
365
}";
 
366
                        Assert.AreEqual(C.BoxingConversion, ResolveCast(program));
 
367
                }
 
368
                
 
369
                [Test]
 
370
                public void TypeParameterConversion1Array()
 
371
                {
 
372
                        string program = @"using System;
 
373
class Test {
 
374
        public void M<T, U>(T[] t) where T : U {
 
375
                U[] u = $(U[])t$;
 
376
        }
 
377
}";
 
378
                        Assert.AreEqual(C.None, ResolveCast(program));
 
379
                }
 
380
                
 
381
                [Test]
 
382
                public void TypeParameterConversion2()
 
383
                {
 
384
                        string program = @"using System;
 
385
class Test {
 
386
        public void M<T, U>(T t) where U : T {
 
387
                U u = $(U)t$;
 
388
        }
 
389
}";
 
390
                        Assert.AreEqual(C.UnboxingConversion, ResolveCast(program));
 
391
                }
 
392
                
 
393
                [Test]
 
394
                public void TypeParameterConversion2Array()
 
395
                {
 
396
                        string program = @"using System;
 
397
class Test {
 
398
        public void M<T, U>(T[] t) where U : T {
 
399
                U[] u = $(U[])t$;
 
400
        }
 
401
}";
 
402
                        Assert.AreEqual(C.None, ResolveCast(program));
 
403
                }
 
404
                
 
405
                [Test]
 
406
                public void ImplicitTypeParameterConversionWithClassConstraint()
 
407
                {
 
408
                        string program = @"using System;
 
409
class Test {
 
410
        public void M<T, U>(T t) where T : class where U : class, T {
 
411
                U u = $(U)t$;
 
412
        }
 
413
}";
 
414
                        Assert.AreEqual(C.ExplicitReferenceConversion, ResolveCast(program));
 
415
                }
 
416
                
 
417
                [Test]
 
418
                public void ImplicitTypeParameterArrayConversionWithClassConstraint()
 
419
                {
 
420
                        string program = @"using System;
 
421
class Test {
 
422
        public void M<T, U>(T[] t) where T : class where U : class, T {
 
423
                U[] u = $(U[])t$;
 
424
        }
 
425
}";
 
426
                        Assert.AreEqual(C.ExplicitReferenceConversion, ResolveCast(program));
 
427
                }
 
428
                
 
429
                [Test]
 
430
                public void ImplicitTypeParameterConversionWithClassConstraintOnlyOnT()
 
431
                {
 
432
                        string program = @"using System;
 
433
class Test {
 
434
        public void M<T, U>(T t) where U : class, T {
 
435
                U u = $(U)t$;
 
436
        }
 
437
}";
 
438
                        Assert.AreEqual(C.ExplicitReferenceConversion, ResolveCast(program));
 
439
                }
 
440
                
 
441
                [Test]
 
442
                public void ImplicitTypeParameterArrayConversionWithClassConstraintOnlyOnT()
 
443
                {
 
444
                        string program = @"using System;
 
445
class Test {
 
446
        public void M<T, U>(T[] t) where U : class, T {
 
447
                U[] u = $(U[])t$;
 
448
        }
 
449
}";
 
450
                        Assert.AreEqual(C.ExplicitReferenceConversion, ResolveCast(program));
 
451
                }
 
452
                
 
453
                [Test]
 
454
                public void SimpleUserDefinedConversion()
 
455
                {
 
456
                        var rr = Resolve<ConversionResolveResult>(@"
 
457
class C1 {}
 
458
class C2 {
 
459
        public static explicit operator C1(C2 c2) {
 
460
                return null;
 
461
        }
 
462
}
 
463
class C {
 
464
        public void M() {
 
465
                var c2 = new C2();
 
466
                C1 c1 = $(C1)c2$;
 
467
        }
 
468
}");
 
469
                        Assert.IsTrue(rr.Conversion.IsValid);
 
470
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
471
                        Assert.AreEqual("op_Explicit", rr.Conversion.Method.Name);
 
472
                }
 
473
                
 
474
                [Test]
 
475
                public void ExplicitReferenceConversionFollowedByUserDefinedConversion()
 
476
                {
 
477
                        var rr = Resolve<ConversionResolveResult>(@"
 
478
                class B {}
 
479
                class S : B {}
 
480
                class T {
 
481
                        public static explicit operator T(S s) { return null; }
 
482
                }
 
483
                class Test {
 
484
                        void Run(B b) {
 
485
                                T t = $(T)b$;
 
486
                        }
 
487
                }");
 
488
                        Assert.IsTrue(rr.Conversion.IsValid);
 
489
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
490
                        Assert.AreEqual("B", rr.Input.Type.Name);
 
491
                }
 
492
                
 
493
                [Test]
 
494
                public void ImplicitUserDefinedConversionFollowedByExplicitNumericConversion()
 
495
                {
 
496
                        var rr = Resolve<ConversionResolveResult>(@"
 
497
                struct T {
 
498
                        public static implicit operator float(T t) { return 0; }
 
499
                }
 
500
                class Test {
 
501
                        void Run(T t) {
 
502
                                int x = $(int)t$;
 
503
                        }
 
504
                }");
 
505
                        Assert.IsTrue(rr.Conversion.IsValid);
 
506
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
507
                        // even though the user-defined conversion is implicit, the combined conversion is explicit
 
508
                        Assert.IsTrue(rr.Conversion.IsExplicit);
 
509
                }
 
510
                
 
511
                [Test]
 
512
                public void BothDirectConversionAndBaseClassConversionAvailable()
 
513
                {
 
514
                        var rr = Resolve<ConversionResolveResult>(@"
 
515
                class B {}
 
516
                class S : B {}
 
517
                class T {
 
518
                        public static explicit operator T(S s) { return null; }
 
519
                        public static explicit operator T(B b) { return null; }
 
520
                }
 
521
                class Test {
 
522
                        void Run(B b) {
 
523
                                T t = $(T)b$;
 
524
                        }
 
525
                }");
 
526
                        Assert.IsTrue(rr.Conversion.IsValid);
 
527
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
528
                        Assert.AreEqual("b", rr.Conversion.Method.Parameters.Single().Name);
 
529
                }
 
530
 
 
531
                [Test]
 
532
                public void UserDefinedExplicitConversion_PicksExactSourceTypeIfPossible() {
 
533
                        string program = @"using System;
 
534
class Convertible {
 
535
        public static explicit operator Convertible(int i) {return new Convertible(); }
 
536
        public static explicit operator Convertible(short s) {return new Convertible(); }
 
537
}
 
538
class Test {
 
539
        public void M() {
 
540
                var a = $(Convertible)33$;
 
541
        }
 
542
}";
 
543
                        var rr = Resolve<ConversionResolveResult>(program);
 
544
                        Assert.IsTrue(rr.Conversion.IsValid);
 
545
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
546
                        Assert.AreEqual("i", rr.Conversion.Method.Parameters[0].Name);
 
547
                }
 
548
 
 
549
                [Test]
 
550
                public void UserDefinedExplicitConversion_PicksMostEncompassedSourceTypeIfPossible() {
 
551
                        string program = @"using System;
 
552
class Convertible {
 
553
        public static explicit operator Convertible(long l) {return new Convertible(); }
 
554
        public static explicit operator Convertible(uint ui) {return new Convertible(); }
 
555
}
 
556
class Test {
 
557
        public void M() {
 
558
                var a = $(Convertible)(ushort)33$;
 
559
        }
 
560
}";
 
561
                        var rr = Resolve<ConversionResolveResult>(program);
 
562
                        Assert.IsTrue(rr.Conversion.IsValid);
 
563
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
564
                        Assert.AreEqual("ui", rr.Conversion.Method.Parameters[0].Name);
 
565
                }
 
566
 
 
567
                [Test]
 
568
                public void UserDefinedExplicitConversion_PicksMostEncompassingSourceType() {
 
569
                        string program = @"using System;
 
570
class Convertible {
 
571
        public static explicit operator Convertible(int i) {return new Convertible(); }
 
572
        public static explicit operator Convertible(ushort us) {return new Convertible(); }
 
573
}
 
574
class Test {
 
575
        public void M() {
 
576
                var a = $(Convertible)(long)33$;
 
577
        }
 
578
}";
 
579
                        var rr = Resolve<ConversionResolveResult>(program);
 
580
                        Assert.IsTrue(rr.Conversion.IsValid);
 
581
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
582
                        Assert.AreEqual("i", rr.Conversion.Method.Parameters[0].Name);
 
583
                }
 
584
 
 
585
                [Test]
 
586
                public void UserDefinedExplicitConversion_NoMostEncompassingSourceTypeIsInvalid() {
 
587
                        string program = @"using System;
 
588
class Convertible {
 
589
        public static explicit operator Convertible(uint i) {return new Convertible(); }
 
590
        public static explicit operator Convertible(short us) {return new Convertible(); }
 
591
}
 
592
class Test {
 
593
        public void M() {
 
594
                var a = $(Convertible)(long)33$;
 
595
        }
 
596
}";
 
597
                        var rr = Resolve<ConversionResolveResult>(program);
 
598
                        Assert.IsFalse(rr.Conversion.IsValid);
 
599
                }
 
600
 
 
601
                [Test]
 
602
                public void UserDefinedExplicitConversion_PicksExactTargetTypeIfPossible() {
 
603
                        string program = @"using System;
 
604
class Convertible {
 
605
        public static explicit operator int(Convertible i) {return 0; }
 
606
        public static explicit operator short(Convertible s) {return 0; }
 
607
}
 
608
class Test {
 
609
        public void M() {
 
610
                var a = $(int)new Convertible()$;
 
611
        }
 
612
}";
 
613
                        var rr = Resolve<ConversionResolveResult>(program);
 
614
                        Assert.IsTrue(rr.Conversion.IsValid);
 
615
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
616
                        Assert.AreEqual("i", rr.Conversion.Method.Parameters[0].Name);
 
617
                }
 
618
 
 
619
                [Test]
 
620
                public void UserDefinedExplicitConversion_PicksMostEncompassingTargetTypeIfPossible() {
 
621
                        string program = @"using System;
 
622
class Convertible {
 
623
        public static explicit operator int(Convertible i) {return 0; }
 
624
        public static explicit operator ushort(Convertible us) {return 0; }
 
625
}
 
626
class Test {
 
627
        public void M() {
 
628
                var a = $(ulong)new Convertible()$;
 
629
        }
 
630
}";
 
631
                        var rr = Resolve<ConversionResolveResult>(program);
 
632
                        Assert.IsTrue(rr.Conversion.IsValid);
 
633
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
634
                        Assert.AreEqual("us", rr.Conversion.Method.Parameters[0].Name);
 
635
                }
 
636
 
 
637
                [Test]
 
638
                public void UserDefinedExplicitConversion_PicksMostEncompassedTargetType() {
 
639
                        string program = @"using System;
 
640
class Convertible {
 
641
        public static explicit operator long(Convertible l) { return 0; }
 
642
        public static explicit operator uint(Convertible ui) { return 0; }
 
643
}
 
644
class Test {
 
645
        public void M() {
 
646
                var a = $(ushort)new Convertible()$;
 
647
        }
 
648
}";
 
649
                        var rr = Resolve<ConversionResolveResult>(program);
 
650
                        Assert.IsTrue(rr.Conversion.IsValid);
 
651
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
652
                        Assert.AreEqual("ui", rr.Conversion.Method.Parameters[0].Name);
 
653
                }
 
654
 
 
655
                [Test]
 
656
                public void UserDefinedExplicitConversion_NoMostEncompassedTargetTypeIsInvalid() {
 
657
                        string program = @"using System;
 
658
class Convertible {
 
659
        public static explicit operator ulong(Convertible l) { return 0; }
 
660
        public static explicit operator int(Convertible ui) { return 0; }
 
661
}
 
662
class Test {
 
663
        public void M() {
 
664
                var a = $(ushort)new Convertible()$;
 
665
        }
 
666
}";
 
667
                        var rr = Resolve<ConversionResolveResult>(program);
 
668
                        Assert.IsFalse(rr.Conversion.IsValid);
 
669
                }
 
670
 
 
671
                [Test]
 
672
                public void UserDefinedExplicitConversion_AmbiguousIsInvalid() {
 
673
                        string program = @"using System;
 
674
class Convertible1 {
 
675
        public static explicit operator Convertible2(Convertible1 c) {return 0; }
 
676
}
 
677
class Convertible2 {
 
678
        public static explicit operator Convertible2(Convertible1 c) {return 0; }
 
679
}
 
680
class Test {
 
681
        public void M() {
 
682
                var a = $(Convertible2)new Convertible1()$;
 
683
        }
 
684
}";
 
685
                        var rr = Resolve<ConversionResolveResult>(program);
 
686
                        Assert.IsFalse(rr.Conversion.IsValid);
 
687
                }
 
688
 
 
689
                [Test]
 
690
                public void UserDefinedExplicitConversion_Lifted() {
 
691
                        string program = @"using System;
 
692
struct Convertible {
 
693
        public static explicit operator Convertible(int i) {return new Convertible(); }
 
694
}
 
695
class Test {
 
696
        public void M(int? i) {
 
697
                 a = $(Convertible?)i$;
 
698
        }
 
699
}";
 
700
                        var rr = Resolve<ConversionResolveResult>(program);
 
701
                        Assert.IsTrue(rr.Conversion.IsValid);
 
702
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
703
                        Assert.IsTrue(rr.Conversion.IsLifted);
 
704
                }
 
705
                
 
706
                [Test]
 
707
                public void UserDefinedExplicitConversionFollowedByImplicitNullableConversion() {
 
708
                        string program = @"using System;
 
709
struct Convertible {
 
710
        public static explicit operator Convertible(int i) {return new Convertible(); }
 
711
}
 
712
class Test {
 
713
        public void M(int i) {
 
714
                 a = $(Convertible?)i$;
 
715
        }
 
716
}";
 
717
                        var rr = Resolve<ConversionResolveResult>(program);
 
718
                        Assert.IsTrue(rr.Conversion.IsValid);
 
719
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
720
                        Assert.IsFalse(rr.Conversion.IsLifted);
 
721
                }
 
722
                
 
723
                [Test]
 
724
                public void UserDefinedExplicitConversion_ExplicitNullable_ThenUserDefined() {
 
725
                        string program = @"using System;
 
726
struct Convertible {
 
727
        public static explicit operator Convertible(int i) {return new Convertible(); }
 
728
        public static explicit operator Convertible?(int? ni) {return new Convertible(); }
 
729
}
 
730
class Test {
 
731
        public void M(int? i) {
 
732
                 a = $(Convertible)i$;
 
733
        }
 
734
}";
 
735
                        var rr = Resolve<ConversionResolveResult>(program);
 
736
                        Assert.IsTrue(rr.Conversion.IsValid);
 
737
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
738
                        Assert.IsFalse(rr.Conversion.IsLifted);
 
739
                        Assert.AreEqual("i", rr.Conversion.Method.Parameters[0].Name);
 
740
                }
 
741
                
 
742
                [Test]
 
743
                public void UserDefinedExplicitConversion_DefinedNullableTakesPrecedenceOverLifted() {
 
744
                        string program = @"using System;
 
745
struct Convertible {
 
746
        public static explicit operator Convertible(int i) {return new Convertible(); }
 
747
        public static explicit operator Convertible?(int? ni) {return new Convertible(); }
 
748
}
 
749
class Test {
 
750
        public void M() {
 
751
                 a = $(Convertible?)(int?)33$;
 
752
        }
 
753
}";
 
754
                        var rr = Resolve<ConversionResolveResult>(program);
 
755
                        Assert.IsTrue(rr.Conversion.IsValid);
 
756
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
757
                        Assert.IsFalse(rr.Conversion.IsLifted);
 
758
                        Assert.AreEqual("ni", rr.Conversion.Method.Parameters[0].Name);
 
759
                }
 
760
 
 
761
                [Test]
 
762
                public void UserDefinedExplicitConversion_UIntConstant() {
 
763
                        string program = @"using System;
 
764
class Convertible {
 
765
        public static explicit operator Convertible(long l) {return new Convertible(); }
 
766
        public static explicit operator Convertible(uint ui) {return new Convertible(); }
 
767
}
 
768
class Test {
 
769
        public void M() {
 
770
                var a = $(Convertible)33$;
 
771
        }
 
772
}";
 
773
                        var rr = Resolve<ConversionResolveResult>(program);
 
774
                        Assert.IsTrue(rr.Conversion.IsValid);
 
775
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
776
                        Assert.AreEqual("ui", rr.Conversion.Method.Parameters[0].Name);
 
777
                }
 
778
 
 
779
                [Test]
 
780
                public void UserDefinedExplicitConversion_NullableUIntConstant() {
 
781
                        string program = @"using System;
 
782
class Convertible {
 
783
        public static explicit operator Convertible(long? l) {return new Convertible(); }
 
784
        public static explicit operator Convertible(uint? ui) {return new Convertible(); }
 
785
}
 
786
class Test {
 
787
        public void M() {
 
788
                Convertible a = $(Convertible)33$;
 
789
        }
 
790
}";
 
791
                        var rr = Resolve<ConversionResolveResult>(program);
 
792
                        Assert.IsTrue(rr.Conversion.IsValid);
 
793
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
794
                        Assert.AreEqual("ui", rr.Conversion.Method.Parameters[0].Name);
 
795
                }
 
796
 
 
797
                [Test]
 
798
                public void UseDefinedExplicitConversion_Lifted() {
 
799
                        string program = @"
 
800
struct Convertible {
 
801
    public static explicit operator Convertible(int i) { return new Convertible(); }
 
802
}
 
803
class Test {
 
804
    public void M(int? i) {
 
805
         a = $(Convertible?)i$;
 
806
    }
 
807
}";
 
808
                        var rr = Resolve<ConversionResolveResult>(program);
 
809
                        Assert.IsTrue(rr.Conversion.IsValid);
 
810
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
811
                        Assert.IsTrue(rr.Conversion.IsLifted);
 
812
                        Assert.IsTrue(rr.Input is LocalResolveResult);
 
813
                }
 
814
 
 
815
                [Test]
 
816
                public void UserDefinedExplicitConversion_Short_Or_NullableByte_Target()
 
817
                {
 
818
                        string program = @"using System;
 
819
class Test {
 
820
        public static explicit operator short(Test s) { return 0; }
 
821
        public static explicit operator byte?(Test b) { return 0; }
 
822
}
 
823
class Program {
 
824
        public static void Main(string[] args)
 
825
        {
 
826
                int? x = $(int?)new Test()$;
 
827
        }
 
828
}";
 
829
                        var rr = Resolve<ConversionResolveResult>(program);
 
830
                        Assert.IsTrue(rr.Conversion.IsValid);
 
831
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
832
                        Assert.AreEqual("System.Int16", rr.Conversion.Method.ReturnType.FullName);
 
833
                }
 
834
                
 
835
                [Test]
 
836
                public void UserDefinedExplicitConversion_Byte_Or_NullableShort_Target()
 
837
                {
 
838
                        string program = @"using System;
 
839
class Test {
 
840
        public static explicit operator byte(Test b) { return 0; }
 
841
        public static explicit operator short?(Test s) { return 0; }
 
842
}
 
843
class Program {
 
844
        public static void Main(string[] args)
 
845
        {
 
846
                int? x = $(int?)new Test()$;
 
847
        }
 
848
}";
 
849
                        var rr = Resolve<ConversionResolveResult>(program);
 
850
                        Assert.IsTrue(rr.Conversion.IsValid);
 
851
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
852
                        Assert.AreEqual("s", rr.Conversion.Method.Parameters[0].Name);
 
853
                }
 
854
 
 
855
                [Test]
 
856
                public void ExplicitConversionOperatorsCanOverrideApplicableImplicitOnes()
 
857
                {
 
858
                        string program = @"
 
859
struct Convertible {
 
860
    public static explicit operator int(Convertible ci) {return 0; }
 
861
    public static implicit operator short(Convertible cs) {return 0; }
 
862
}
 
863
class Test {
 
864
    static void Main() {
 
865
        int i = $(int)new Convertible()$; // csc uses the explicit conversion operator
 
866
    }
 
867
}";
 
868
                        var rr = Resolve<ConversionResolveResult>(program);
 
869
                        Assert.IsTrue(rr.Conversion.IsValid);
 
870
                        Assert.IsTrue(rr.Conversion.IsUserDefined);
 
871
                        Assert.AreEqual("ci", rr.Conversion.Method.Parameters[0].Name);
 
872
                }
 
873
 
 
874
                [Test]
 
875
                public void UserDefinedExplicitConversion_ConversionBeforeUserDefinedOperatorIsCorrect() {
 
876
                        string program = @"using System;
 
877
class Convertible {
 
878
        public static implicit operator Convertible(int l) {return new Convertible(); }
 
879
}
 
880
class Test {
 
881
        public void M() {
 
882
                long i = 33;
 
883
                Convertible a = $(Convertible)i$;
 
884
        }
 
885
}";
 
886
                        var rr = Resolve<ConversionResolveResult>(program);
 
887
                        Assert.IsTrue(rr.Conversion.IsValid);
 
888
                        Assert.IsTrue(rr.Conversion.ConversionBeforeUserDefinedOperator.IsValid);
 
889
                        Assert.IsTrue(rr.Conversion.ConversionBeforeUserDefinedOperator.IsExplicit);
 
890
                        Assert.IsTrue(rr.Conversion.ConversionBeforeUserDefinedOperator.IsNumericConversion);
 
891
                        Assert.IsTrue(rr.Conversion.ConversionAfterUserDefinedOperator.IsIdentityConversion);
 
892
                }
 
893
 
 
894
                [Test]
 
895
                public void UserDefinedExplicitConversion_ConversionAfterUserDefinedOperatorIsCorrect() {
 
896
                        string program = @"using System;
 
897
class Convertible {
 
898
        public static implicit operator long(Convertible i) {return 0; }
 
899
}
 
900
class Test {
 
901
        public void M() {
 
902
                int a = $(int)new Convertible()$;
 
903
        }
 
904
}";
 
905
                        var rr = Resolve<ConversionResolveResult>(program);
 
906
                        Assert.IsTrue(rr.Conversion.IsValid);
 
907
                        Assert.IsTrue(rr.Conversion.ConversionBeforeUserDefinedOperator.IsIdentityConversion);
 
908
                        Assert.IsTrue(rr.Conversion.ConversionAfterUserDefinedOperator.IsValid);
 
909
                        Assert.IsTrue(rr.Conversion.ConversionAfterUserDefinedOperator.IsExplicit);
 
910
                        Assert.IsTrue(rr.Conversion.ConversionAfterUserDefinedOperator.IsNumericConversion);
 
911
                }
 
912
        }
 
913
}