/Src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenImplicitlyTypeArraysTests.cs
C# | 1042 lines | 889 code | 82 blank | 71 comment | 0 complexity | cad50d6e10fdab93d06216a7d8d7c3d4 MD5 | raw file
1// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
2
3using System.IO;
4using Microsoft.CodeAnalysis.CSharp.Symbols;
5using Microsoft.CodeAnalysis.CSharp.Syntax;
6using ProprietaryTestResources = Microsoft.CodeAnalysis.Test.Resources.Proprietary;
7using Microsoft.CodeAnalysis.Test.Utilities;
8using Microsoft.CodeAnalysis.Text;
9using Roslyn.Test.Utilities;
10using Xunit;
11
12namespace Microsoft.CodeAnalysis.CSharp.UnitTests.CodeGen
13{
14 public class CodeGenImplicitlyTypeArraysTests : CompilingTestBase
15 {
16 #region "Functionality tests"
17
18 [Fact]
19 public void Test_001_Simple()
20 {
21 var source = @"
22using System.Linq;
23
24namespace Test
25{
26 public class Program
27 {
28 public static void Main()
29 {
30 var a = new [] {1, 2, 3};
31
32 System.Console.Write(a.SequenceEqual(new int[]{1, 2, 3}));
33 }
34 }
35}
36";
37
38 CompileAndVerify(
39 source,
40 emitOptions: EmitOptions.CCI,
41 additionalRefs: new[] { LinqAssemblyRef },
42 expectedOutput: "True");
43 }
44
45 [Fact]
46 public void Test_002_IntTypeBest()
47 {
48 // Best type: int
49
50 var source = @"
51using System.Linq;
52
53namespace Test
54{
55 public class Program
56 {
57 public static void Main()
58 {
59 var a = new [] {1, (byte)2, (short)3};
60
61 System.Console.Write(a.SequenceEqual(new int[]{1, (byte)2, (short)3}));
62 }
63 }
64}
65";
66
67 CompileAndVerify(
68 source,
69 emitOptions: EmitOptions.CCI,
70 additionalRefs: new[] { LinqAssemblyRef },
71 expectedOutput: "True");
72 }
73
74 [Fact]
75 public void Test_003_DoubleTypeBest()
76 {
77 // Best type: double
78
79 var source = @"
80using System.Linq;
81
82namespace Test
83{
84 public class Program
85 {
86 public static void Main()
87 {
88 var a = new [] {(sbyte)1, (byte)2, (short)3, (ushort)4, 5, 6u, 7l, 8ul, (char)9, 10.0f, 11.0d};
89
90 System.Console.Write(a.SequenceEqual(new double[]{(sbyte)1, (byte)2, (short)3, (ushort)4, 5, 6u, 7l, 8ul, (char)9, 10.0f, 11.0d}));
91 }
92 }
93}
94";
95
96 CompileAndVerify(
97 source,
98 emitOptions: EmitOptions.CCI,
99 additionalRefs: new[] { LinqAssemblyRef },
100 expectedOutput: "True");
101 }
102
103 [Fact, WorkItem(895655, "DevDiv")]
104 public void Test_004_Enum()
105 {
106 // Enums conversions
107
108 var source = @"
109using System.Linq;
110
111namespace Test
112{
113 public class Program
114 {
115 enum E
116 {
117 START
118 };
119
120 public static void Main()
121 {
122 var a = new [] {E.START, 0, 0U, 0u, 0L, 0l, 0UL, 0Ul, 0uL, 0ul, 0LU, 0Lu, 0lU, 0lu};
123
124 System.Console.Write(a.SequenceEqual(new E[]{E.START, 0, 0U, 0u, 0L, 0l, 0UL, 0Ul, 0uL, 0ul, 0LU, 0Lu, 0lU, 0lu}));
125 }
126 }
127}
128";
129
130 var comp = CreateCompilationWithMscorlib(source, references: new[] { LinqAssemblyRef });
131 comp.VerifyDiagnostics(
132 // (15,54): warning CS0078: The 'l' suffix is easily confused with the digit '1' -- use 'L' for clarity
133 // var a = new [] {E.START, 0, 0U, 0u, 0L, 0l, 0UL, 0Ul, 0uL, 0ul, 0LU, 0Lu, 0lU, 0lu};
134 Diagnostic(ErrorCode.WRN_LowercaseEllSuffix, "l").WithLocation(15, 54),
135 // (15,88): warning CS0078: The 'l' suffix is easily confused with the digit '1' -- use 'L' for clarity
136 // var a = new [] {E.START, 0, 0U, 0u, 0L, 0l, 0UL, 0Ul, 0uL, 0ul, 0LU, 0Lu, 0lU, 0lu};
137 Diagnostic(ErrorCode.WRN_LowercaseEllSuffix, "l").WithLocation(15, 88),
138 // (15,93): warning CS0078: The 'l' suffix is easily confused with the digit '1' -- use 'L' for clarity
139 // var a = new [] {E.START, 0, 0U, 0u, 0L, 0l, 0UL, 0Ul, 0uL, 0ul, 0LU, 0Lu, 0lU, 0lu};
140 Diagnostic(ErrorCode.WRN_LowercaseEllSuffix, "l").WithLocation(15, 93),
141 // (17,84): warning CS0078: The 'l' suffix is easily confused with the digit '1' -- use 'L' for clarity
142 // System.Console.Write(a.SequenceEqual(new E[]{E.START, 0, 0U, 0u, 0L, 0l, 0UL, 0Ul, 0uL, 0ul, 0LU, 0Lu, 0lU, 0lu}));
143 Diagnostic(ErrorCode.WRN_LowercaseEllSuffix, "l").WithLocation(17, 84),
144 // (17,118): warning CS0078: The 'l' suffix is easily confused with the digit '1' -- use 'L' for clarity
145 // System.Console.Write(a.SequenceEqual(new E[]{E.START, 0, 0U, 0u, 0L, 0l, 0UL, 0Ul, 0uL, 0ul, 0LU, 0Lu, 0lU, 0lu}));
146 Diagnostic(ErrorCode.WRN_LowercaseEllSuffix, "l").WithLocation(17, 118),
147 // (17,123): warning CS0078: The 'l' suffix is easily confused with the digit '1' -- use 'L' for clarity
148 // System.Console.Write(a.SequenceEqual(new E[]{E.START, 0, 0U, 0u, 0L, 0l, 0UL, 0Ul, 0uL, 0ul, 0LU, 0Lu, 0lU, 0lu}));
149 Diagnostic(ErrorCode.WRN_LowercaseEllSuffix, "l").WithLocation(17, 123),
150 // (15,21): error CS0826: No best type found for implicitly-typed array
151 // var a = new [] {E.START, 0, 0U, 0u, 0L, 0l, 0UL, 0Ul, 0uL, 0ul, 0LU, 0Lu, 0lU, 0lu};
152 Diagnostic(ErrorCode.ERR_ImplicitlyTypedArrayNoBestType, "new [] {E.START, 0, 0U, 0u, 0L, 0l, 0UL, 0Ul, 0uL, 0ul, 0LU, 0Lu, 0lU, 0lu}").WithLocation(15, 21),
153 // (17,35): error CS1929: '?[]' does not contain a definition for 'SequenceEqual' and the best extension method overload 'System.Linq.Queryable.SequenceEqual<Test.Program.E>(System.Linq.IQueryable<Test.Program.E>, System.Collections.Generic.IEnumerable<Test.Program.E>)' requires a receiver of type 'System.Linq.IQueryable<Test.Program.E>'
154 // System.Console.Write(a.SequenceEqual(new E[]{E.START, 0, 0U, 0u, 0L, 0l, 0UL, 0Ul, 0uL, 0ul, 0LU, 0Lu, 0lU, 0lu}));
155 Diagnostic(ErrorCode.ERR_BadInstanceArgType, "a").WithArguments("?[]", "SequenceEqual", "System.Linq.Queryable.SequenceEqual<Test.Program.E>(System.Linq.IQueryable<Test.Program.E>, System.Collections.Generic.IEnumerable<Test.Program.E>)", "System.Linq.IQueryable<Test.Program.E>").WithLocation(17, 35)
156 );
157 }
158
159 [Fact]
160 public void Test_005_ObjectTypeBest()
161 {
162 // Implicit reference conversions -- From any reference-type to object.
163
164 var source = @"
165
166using System.Linq;
167
168namespace Test
169{
170 public class C { };
171 public interface I { };
172 public class C2 : I { };
173
174 public class Program
175 {
176 delegate void D();
177
178 public static void M() { }
179
180 public static void Main()
181 {
182 object o = new object();
183 C c = new C();
184 I i = new C2();
185 D d = new D(M);
186 int[] aa = new int[] {1};
187
188 var a = new [] {o, """", c, i, d, aa};
189
190 System.Console.Write(a.SequenceEqual(new object[]{o, """", c, i, d, aa}));
191 }
192 }
193}
194";
195
196 CompileAndVerify(
197 source,
198 emitOptions: EmitOptions.CCI,
199 additionalRefs: new[] { LinqAssemblyRef },
200 expectedOutput: "True");
201 }
202
203 [Fact]
204 public void Test_006_ArrayTypeBest()
205 {
206 // Implicit reference conversions -- From an array-type S with an element type SE to an array-type T with an element type TE,
207
208 var source = @"
209
210using System.Linq;
211
212namespace Test
213{
214 public class Program
215 {
216 public static void Main()
217 {
218 object[] oa = new object[] {null};
219 string[] sa = new string[] {null};
220
221 var a = new [] {oa, sa};
222
223 System.Console.Write(a.SequenceEqual(new object[][]{oa, sa}));
224 }
225 }
226}
227";
228
229 CompileAndVerify(
230 source,
231 emitOptions: EmitOptions.CCI,
232 additionalRefs: new[] { LinqAssemblyRef },
233 expectedOutput: "True");
234 }
235
236 [Fact]
237 public void Test_007A()
238 {
239 // Implicit reference conversions -- From a one-dimensional array-type S[] to System.Collections.Generic.IList<S>.
240
241 var testSrc = @"
242using System.Linq;
243using System.Collections.Generic;
244
245namespace Test
246{
247 public class Program
248 {
249 public static void Main()
250 {
251 int[] ia = new int[] {1, 2, 3};
252 IList<int> la = new List<int> {1, 2, 3};
253
254 var a = new [] {ia, la};
255
256 System.Console.Write(a.SequenceEqual(new IList<int>[]{ia, la}));
257 }
258 }
259}
260";
261 var compilation = CompileAndVerify(
262 testSrc,
263 emitOptions: EmitOptions.CCI,
264 additionalRefs: new[] { LinqAssemblyRef },
265 expectedOutput: "True");
266 }
267
268 [Fact]
269 public void Test_007B()
270 {
271 // Implicit reference conversions -- From a one-dimensional array-type S[] to System.Collections.Generic.IReadOnlyList<S>.
272
273 var testSrc = @"
274using System.Collections.Generic;
275
276namespace Test
277{
278 public class Program
279 {
280 public static void Main()
281 {
282 int[] array = new int[] {1, 2, 3};
283 object obj = array;
284 IEnumerable<int> ro1 = array;
285 IReadOnlyList<int> ro2 = (IReadOnlyList<int>)obj;
286 IReadOnlyList<int> ro3 = (IReadOnlyList<int>)array;
287 IReadOnlyList<int> ro4 = obj as IReadOnlyList<int>;
288 System.Console.WriteLine(ro4 != null ? 1 : 2);
289 }
290 }
291}
292";
293 // The version of mscorlib checked in to the test resources in v4_0_30316 does not have
294 // the IReadOnlyList<T> and IReadOnlyCollection<T> interfaces. Use the one in v4_0_30316_17626.
295
296 var mscorlib17626 = new MetadataImageReference(ProprietaryTestResources.NetFX.v4_0_30316_17626.mscorlib.AsImmutableOrNull(), display: "mscorlib");
297 CompileAndVerify(testSrc, new MetadataReference[] { mscorlib17626 }, expectedOutput: "1");
298 }
299
300 [Fact]
301 public void Test_008_DelegateType()
302 {
303 // Implicit reference conversions -- From any delegate-type to System.Delegate.
304
305 var source = @"
306using System;
307using System.Linq;
308
309namespace Test
310{
311 public class Program
312 {
313 delegate void D1();
314 public static void M1() {}
315
316 delegate int D2();
317 public static int M2() { return 0;}
318
319 delegate void D3(int i);
320 public static void M3(int i) {}
321
322 delegate void D4(params object[] o);
323 public static void M4(params object[] o) { }
324
325 public static void Main()
326 {
327 D1 d1 = new D1(M1);
328 D2 d2 = new D2(M2);
329 D3 d3 = new D3(M3);
330 D4 d4 = new D4(M4);
331 Delegate d = d1;
332
333 var a = new [] {d, d1, d2, d3, d4};
334
335 System.Console.Write(a.SequenceEqual(new Delegate[]{d, d1, d2, d3, d4}));
336 }
337 }
338}
339";
340
341 CompileAndVerify(
342 source,
343 emitOptions: EmitOptions.CCI,
344 additionalRefs: new[] { LinqAssemblyRef },
345 expectedOutput: "True");
346 }
347
348 [Fact]
349 public void Test_009_Null()
350 {
351 // Implicit reference conversions -- From the null type to any reference-type.
352
353 var source = @"
354using System.Linq;
355
356namespace Test
357{
358 public class Program
359 {
360 public static void Main()
361 {
362 var a = new [] {""aa"", ""bb"", null};
363
364 System.Console.Write(a.SequenceEqual(new string[]{""aa"", ""bb"", null}));
365 }
366 }
367}
368";
369
370 CompileAndVerify(
371 source,
372 emitOptions: EmitOptions.CCI,
373 additionalRefs: new[] { LinqAssemblyRef },
374 expectedOutput: "True");
375 }
376
377 [Fact]
378 public void Test_010_TypeParameter()
379 {
380 // Implicit reference conversions --
381 // For a type-parameter T that is known to be a reference type , the following
382 // implicit reference conversions exist:
383 // From T to its effective base class C, from T to any base class of C,
384 // and from T to any interface implemented by C.
385
386 var source = @"
387using System.Linq;
388
389namespace Test
390{
391 public interface I {}
392 public class B {}
393 public class C : B, I {}
394 public class D : C {}
395
396 public class Program
397 {
398 public static void M<T>() where T : C, new()
399 {
400 T t = new T();
401 I i = t;
402
403 var a = new [] {i, t};
404 System.Console.Write(a.SequenceEqual(new I[]{i, t}));
405 }
406
407 public static void Main()
408 {
409 M<D>();
410 }
411 }
412}
413";
414
415 CompileAndVerify(
416 source,
417 emitOptions: EmitOptions.CCI,
418 additionalRefs: new[] { LinqAssemblyRef },
419 expectedOutput: "True");
420 }
421
422 [Fact]
423 public void Test_011_BoxingConversion()
424 {
425 // Implicit reference conversions -- Boxing conversions
426
427 var testSrc = @"
428using System;
429using System.Linq;
430
431namespace Test
432{
433 public struct S
434 {
435 }
436
437 public class Program
438 {
439 enum E { START };
440
441 public static void Main()
442 {
443 IComparable v = 1;
444 int? i = 1;
445
446 var a = new [] {v, i, E.START, true, (byte)2, (sbyte)3, (short)4, (ushort)5, 6, 7U, 8L, 9UL, 10.0F, 11.0D, 12M, (char)13};
447
448 System.Console.Write(a.SequenceEqual(new IComparable[]{v, i, E.START, true, (byte)2, (sbyte)3, (short)4, (ushort)5, 6, 7U, 8L, 9UL, 10.0F, 11.0D, 12M, (char)13}));
449 }
450 }
451}
452";
453 var compilation = CompileAndVerify(
454 testSrc,
455 emitOptions: EmitOptions.CCI,
456 additionalRefs: new[] { LinqAssemblyRef },
457 expectedOutput: "True");
458 }
459
460 [Fact]
461 public void Test_012_UserDefinedImplicitConversion()
462 {
463 // User-defined implicit conversions.
464
465 var testSrc = @"
466using System.Linq;
467
468namespace Test
469{
470 public class B {}
471
472 public class C
473 {
474 public static B b = new B();
475
476 public static implicit operator B(C c)
477 {
478 return b;
479 }
480 }
481
482 public class Program
483 {
484 public static void Main()
485 {
486 B b = new B();
487 C c = new C();
488
489 var a = new [] {b, c};
490
491 System.Console.Write(a.SequenceEqual(new B[]{b, c}));
492 }
493 }
494}
495";
496 // NYI: When user-defined conversion lowering is implemented, replace the
497 // NYI: error checking below with:
498 // var compilation = CompileAndVerify(testSrc, emitOptions: EmitOptions.CCI,
499 // additionalRefs: GetReferences(), expectedOutput: "");
500 var compilation = CreateCompilationWithMscorlibAndSystemCore(testSrc);
501 compilation.VerifyDiagnostics();
502 }
503
504 [Fact]
505 public void Test_013_A_UserDefinedNullableConversions()
506 {
507 // Lifted user-defined conversions
508
509 var testSrc = @"
510using System.Linq;
511namespace Test
512{
513 public struct B { }
514 public struct C
515 {
516 public static B b = new B();
517 public static implicit operator B(C c)
518 {
519 return b;
520 }
521 }
522 public class Program
523 {
524 public static void Main()
525 {
526 C? c = new C();
527 B? b = new B();
528 if (!(new [] {b, c}.SequenceEqual(new B?[] {b, c})))
529 {
530 System.Console.WriteLine(""Test fail at struct C? implicitly convert to struct B?"");
531 }
532 }
533 }
534}
535";
536 // NYI: When lifted user-defined conversion lowering is implemented, replace the
537 // NYI: error checking below with:
538
539 // var compilation = CompileAndVerify(testSrc, emitOptions: EmitOptions.CCI,
540 // additionalRefs: GetReferences(), expectedOutput: "");
541
542 var compilation = CreateCompilationWithMscorlibAndSystemCore(testSrc);
543 compilation.VerifyDiagnostics();
544 }
545
546 // Bug 10700: We should be able to infer the array type from elements of types int? and short?
547 [Fact]
548 public void Test_013_B_NullableConversions()
549 {
550 // Lifted implicit numeric conversions
551
552 var testSrc = @"
553using System.Linq;
554namespace Test
555{
556 public class Program
557 {
558 public static void Main()
559 {
560 int? i = 1;
561 short? s = 2;
562 if (!new [] {i, s}.SequenceEqual(new int?[] {i, s}))
563 {
564 System.Console.WriteLine(""Test fail at short? implicitly convert to int?"");
565 }
566 }
567 }
568}
569";
570 // NYI: When lifted conversions are implemented, remove the diagnostics check
571 // NYI: and replace it with:
572 // var compilation = CompileAndVerify(testSrc, emitOptions: EmitOptions.CCI,
573 // additionalRefs: GetReferences(), expectedOutput: "");
574
575 var compilation = CreateCompilationWithMscorlibAndSystemCore(testSrc);
576 compilation.VerifyDiagnostics();
577 }
578
579 [Fact]
580 public void Test_014_LambdaExpression()
581 {
582 // Implicitly conversion from lambda expression to compatible delegate type
583
584 var source = @"
585using System;
586
587namespace Test
588{
589 public class Program
590 {
591 delegate int D(int i);
592
593 public static int M(int i) {return i;}
594
595 public static void Main()
596 {
597 var a = new [] {new D(M), (int i)=>{return i;}, x => x+1, (int i)=>{short s = 2; return s;}};
598
599 Console.Write(((a is D[]) && (a.Length==4)));
600 }
601 }
602}
603";
604
605 CompileAndVerify(
606 source,
607 emitOptions: EmitOptions.CCI,
608 additionalRefs: new[] { LinqAssemblyRef },
609 expectedOutput: "True");
610 }
611
612 [Fact]
613 public void Test_015_ImplicitlyTypedLocalExpr()
614 {
615 // local variable declared as "var" type is used inside an implicitly typed array.
616
617 var source = @"
618using System.Linq;
619
620namespace Test
621{
622 public class B { };
623 public class C : B { };
624
625 public class Program
626 {
627 public static void Main()
628 {
629 var b = new B();
630 var c = new C();
631
632 var a = new [] {b, c};
633
634 System.Console.Write(a.SequenceEqual(new B[]{b, c}));
635 }
636 }
637}
638";
639
640 CompileAndVerify(
641 source,
642 emitOptions: EmitOptions.CCI,
643 additionalRefs: new[] { LinqAssemblyRef },
644 expectedOutput: "True");
645 }
646
647 [Fact]
648 public void Test_016_ArrayCreationExpression()
649 {
650 // Array creation expression as element in implicitly typed arrays
651
652 var source = @"
653using System;
654
655namespace Test
656{
657 public class Program
658 {
659 public static void Main()
660 {
661 var a = new [] {new int[1] , new int[3] {11, 12, 13}, new int[] {21, 22, 23}};
662
663 Console.Write(((a is int[][]) && (a.Length==3)));
664 }
665 }
666}
667";
668
669 CompileAndVerify(
670 source,
671 emitOptions: EmitOptions.CCI,
672 additionalRefs: new[] { LinqAssemblyRef },
673 expectedOutput: "True");
674 }
675
676 [Fact]
677 public void Test_017_AnonymousObjectCreationExpression()
678 {
679 // Anonymous object creation expression as element in implicitly typed arrays
680
681 var source = @"
682using System;
683
684namespace Test
685{
686 public class Program
687 {
688 public static void Main()
689 {
690 var a = new [] {new {i = 2, s = ""bb""}, new {i = 3, s = ""cc""}};
691
692 Console.Write(((a is Array) && (a.Length==2)));
693 }
694 }
695}
696";
697
698 CompileAndVerify(
699 source,
700 emitOptions: EmitOptions.CCI,
701 additionalRefs: new[] { LinqAssemblyRef },
702 expectedOutput: "True");
703 }
704
705 [Fact]
706 public void Test_018_MemberAccessExpression()
707 {
708 // Member access expression as element in implicitly typed arrays
709
710 var source = @"
711using System.Linq;
712
713using NT = Test;
714
715namespace Test
716{
717 public class Program
718 {
719 public delegate int D(string s);
720
721 public static D d1 = new D(M2);
722
723 public static int M<T>(string s) {return 1;}
724
725 public static int M2(string s) {return 2;}
726
727 public D d2 = new D(M2);
728 public static Program p = new Program();
729
730 public static Program GetP() {return p;}
731
732 public static void Main()
733 {
734 System.Console.Write(new [] {Program.d1, Program.M<int>, GetP().d2, int.Parse, NT::Program.M2}.SequenceEqual(
735 new D[] {Program.d1, Program.M<int>, GetP().d2, int.Parse, NT::Program.M2}));
736 }
737 }
738}
739";
740
741 CompileAndVerify(
742 source,
743 emitOptions: EmitOptions.CCI,
744 additionalRefs: new[] { LinqAssemblyRef },
745 expectedOutput: "True");
746 }
747
748 [Fact]
749 public void Test_019_JaggedArray()
750 {
751 // JaggedArray in implicitly typed arrays
752
753 var source = @"
754using System;
755
756namespace Test
757{
758 public class Program
759 {
760 public static void Main()
761 {
762 var a3 = new [] { new [] {new [] {1}},
763 new [] {new int[] {2}},
764 new int[][] {new int[] {3}},
765 new int[][] {new [] {4}} };
766 if ( !((a3 is int[][][]) && (a3.Length == 4)) )
767 {
768 Console.Write(""Test fail"");
769 }
770 else
771 {
772 Console.Write(""True"");
773 }
774 }
775 }
776}
777";
778
779 CompileAndVerify(
780 source,
781 emitOptions: EmitOptions.CCI,
782 additionalRefs: new[] { LinqAssemblyRef },
783 expectedOutput: "True");
784 }
785
786 [Fact]
787 public void Test_020_MultiDimensionalArray()
788 {
789 // MultiDimensionalArray in implicitly typed arrays
790
791 var testSrc = @"
792using System;
793
794namespace Test
795{
796 public class Program
797 {
798 public static void Main()
799 {
800 var a3 = new [] { new int[,,] {{{3, 4}}},
801 new int[,,] {{{3, 4}}} };
802 if ( !((a3 is int[][,,]) && (a3.Rank == 1) && (a3.Length == 2)) )
803 {
804 Console.WriteLine(0);
805 }
806 else
807 {
808 Console.WriteLine(1);
809 }
810 }
811 }
812}";
813
814 CompileAndVerify(testSrc, expectedOutput: "1");
815 }
816
817 [Fact]
818 public void Test_021_MultiDimensionalArray_02()
819 {
820 // Implicitly typed arrays should can be used in creating MultiDimensionalArray
821
822 var testSrc = @"
823using System;
824
825namespace Test
826{
827 public class Program
828 {
829 public static void Main()
830 {
831 var a3 = new [,,] { {{2, 3, 4}}, {{2, 3, 4}} };
832 if ( !((a3 is int[,,]) && (a3.Rank == 3) && (a3.Length == 6)) )
833 {
834 Console.WriteLine(0);
835 }
836 else
837 {
838 Console.WriteLine(1);
839 }
840 }
841 }
842}
843";
844 CompileAndVerify(testSrc, expectedOutput: "1");
845 }
846
847 [Fact]
848 public void Test_022_GenericMethod()
849 {
850 // Implicitly typed arrays used in generic method
851
852 var source = @"
853using System.Linq;
854
855namespace Test
856{
857 public class Program
858 {
859 public static void Main()
860 {
861 System.Console.Write(GM(new [] {1, 2, 3}).SequenceEqual(new int[]{1, 2, 3}));
862 }
863
864 public static T GM<T>(T t)
865 {
866 return t;
867 }
868 }
869}
870";
871
872 CompileAndVerify(
873 source,
874 emitOptions: EmitOptions.CCI,
875 additionalRefs: new[] { LinqAssemblyRef },
876 expectedOutput: "True");
877 }
878
879 [Fact]
880 public void Test_023_Query()
881 {
882 // Query expression as element in implicitly typed arrays
883
884 var source = @"
885using System;
886using System.Collections;
887using System.Collections.Generic;
888using System.Linq;
889
890public class Program
891{
892 public static void Main()
893 {
894 int[] ta = new int[] {1, 2, 3, 4, 5};
895 IEnumerable i = ta;
896
897 IEnumerable[] a = new [] {i, from c in ta select c, from c in ta group c by c,
898 from c in ta select c into g select g, from c in ta where c==3 select c,
899 from c in ta orderby c select c, from c in ta orderby c ascending select c,
900 from c in ta orderby c descending select c, from c in ta where c==3 orderby c select c};
901
902 Console.Write((a is IEnumerable[]) && (a.Length==9));
903 }
904}
905";
906
907 CompileAndVerify(
908 source,
909 emitOptions: EmitOptions.CCI,
910 additionalRefs: new[] { LinqAssemblyRef },
911 expectedOutput: "True");
912 }
913
914 [Fact]
915 public void Test_023_Literal()
916 {
917 // Query expression as element in implicitly typed arrays
918
919 var source = @"
920using System;
921using System.Linq;
922
923public class Program
924{
925 public static void Main()
926 {
927 Console.Write(new [] {true, false}.SequenceEqual(new bool[] {true, false}));
928 Console.Write(new [] {0123456789U, 1234567890U, 2345678901u, 3456789012UL, 4567890123Ul, 5678901234UL, 6789012345Ul, 7890123456uL, 8901234567ul, 9012345678LU, 9123456780Lu, 1234567809LU, 2345678091LU}.SequenceEqual(
929 new ulong[] {0123456789U, 1234567890U, 2345678901u, 3456789012UL, 4567890123Ul, 5678901234UL, 6789012345Ul, 7890123456uL, 8901234567ul, 9012345678LU, 9123456780Lu, 1234567809LU, 2345678091LU}));
930 Console.Write(new [] {0123456789, 1234567890, 2345678901, 3456789012L, 4567890123L, 5678901234L, 6789012345L, 7890123456L, 8901234567L, 9012345678L, 9123456780L, 1234567809L, 2345678091L}.SequenceEqual(
931 new long[] {0123456789, 1234567890, 2345678901, 3456789012L, 4567890123L, 5678901234L, 6789012345L, 7890123456L, 8901234567L, 9012345678L, 9123456780L, 1234567809L, 2345678091L}));
932 Console.Write(new [] {0x012345U, 0x6789ABU, 0xCDEFabU, 0xcdef01U, 0X123456U, 0x12579BU, 0x13579Bu, 0x14579BLU, 0x15579BLU, 0x16579BUL, 0x17579BUl, 0x18579BuL, 0x19579Bul, 0x1A579BLU, 0x1B579BLu, 0x1C579BLU, 0x1C579BLu}.SequenceEqual(
933 new ulong[] {0x012345U, 0x6789ABU, 0xCDEFabU, 0xcdef01U, 0X123456U, 0x12579BU, 0x13579Bu, 0x14579BLU, 0x15579BLU, 0x16579BUL, 0x17579BUl, 0x18579BuL, 0x19579Bul, 0x1A579BLU, 0x1B579BLu, 0x1C579BLU, 0x1C579BLu}));
934 Console.Write(new [] {0x012345, 0x6789AB, 0xCDEFab, 0xcdef01, 0X123456, 0x12579B, 0x13579B, 0x14579BL, 0x15579BL, 0x16579BL, 0x17579BL, 0x18579BL, 0x19579BL, 0x1A579BL, 0x1B579BL, 0x1C579BL, 0x1C579BL}.SequenceEqual(
935 new long[] {0x012345, 0x6789AB, 0xCDEFab, 0xcdef01, 0X123456, 0x12579B, 0x13579B, 0x14579BL, 0x15579BL, 0x16579BL, 0x17579BL, 0x18579BL, 0x19579BL, 0x1A579BL, 0x1B579BL, 0x1C579BL, 0x1C579BL}));
936 Console.Write(new [] {0123456789F, 1234567890f, 2345678901D, 3456789012d, 3.2, 3.3F, 3.4e5, 3.5E5, 3.6E+5, 3.7E-5, 3.8e+5, 3.9e-5, 3.22E5D, .234, .23456D, .245e3, .2334e7D, 3E5, 3E-5, 3E+6, 4E4D}.SequenceEqual(
937 new double[] {0123456789F, 1234567890f, 2345678901D, 3456789012d, 3.2, 3.3F, 3.4e5, 3.5E5, 3.6E+5, 3.7E-5, 3.8e+5, 3.9e-5, 3.22E5D, .234, .23456D, .245e3, .2334e7D, 3E5, 3E-5, 3E+6, 4E4D})) ;
938 Console.Write(new [] {0123456789M, 1234567890m, 3.3M, 3.22E5M, 3.2E+4M, 3.3E-4M, .234M, .245e3M, .2334e+7M, .24e-3M, 3E5M, 3E-5M, 3E+6M}.SequenceEqual(
939 new decimal[] {0123456789M, 1234567890m, 3.3M, 3.22E5M, 3.2E+4M, 3.3E-4M, .234M, .245e3M, .2334e+7M, .24e-3M, 3E5M, 3E-5M, 3E+6M}));
940 Console.Write(new [] {0123456789, 5678901234UL, 2345678901D, 3.2, 3.4E5, 3.6E+5, 3.7E-5, 3.22E5D, .234, .23456D, .245E3, 3E5, 4E4D}.SequenceEqual(
941 new double[] {0123456789, 5678901234UL, 2345678901D, 3.2, 3.4E5, 3.6E+5, 3.7E-5, 3.22E5D, .234, .23456D, .245E3, 3E5, 4E4D}));
942 Console.Write(new [] {0123456789, 5678901234UL, 2345678901M, 3.2M, 3.4E5M, 3.6E+5M, 3.7E-5M, .234M, .245E3M, 3E5M}.SequenceEqual(
943 new decimal[] {0123456789, 5678901234UL, 2345678901M, 3.2M, 3.4E5M, 3.6E+5M, 3.7E-5M, .234M, .245E3M, 3E5M}));
944 }
945}
946";
947
948 CompileAndVerify(
949 source,
950 emitOptions: EmitOptions.CCI,
951 additionalRefs: new[] { LinqAssemblyRef },
952 expectedOutput: "TrueTrueTrueTrueTrueTrueTrueTrueTrue");
953 }
954
955 #endregion
956
957 #region "Error tests"
958
959 [Fact]
960 public void Error_NonArrayInitExpr()
961 {
962 var testSrc = @"
963namespace Test
964{
965 public class Program
966 {
967 public void Foo()
968 {
969 var a3 = new[,,] { { { 3, 4 } }, 3, 4 };
970 }
971 }
972}
973";
974 var comp = CreateCompilationWithMscorlib(testSrc);
975 comp.VerifyDiagnostics(
976 // (8,46): error CS0846: A nested array initializer is expected
977 // var a3 = new[,,] { { { 3, 4 } }, 3, 4 };
978 Diagnostic(ErrorCode.ERR_ArrayInitializerExpected, "3").WithLocation(8, 46),
979 // (8,49): error CS0846: A nested array initializer is expected
980 // var a3 = new[,,] { { { 3, 4 } }, 3, 4 };
981 Diagnostic(ErrorCode.ERR_ArrayInitializerExpected, "4").WithLocation(8, 49));
982 }
983
984 [Fact]
985 public void Error_NonArrayInitExpr_02()
986 {
987 var testSrc = @"
988namespace Test
989{
990 public class Program
991 {
992 public void Foo()
993 {
994 var a3 = new[,,] { { { 3, 4 } }, x, 4 };
995 }
996 }
997}
998";
999 var comp = CreateCompilationWithMscorlib(testSrc);
1000 comp.VerifyDiagnostics(
1001 // (8,46): error CS0103: The name 'x' does not exist in the current context
1002 // var a3 = new[,,] { { { 3, 4 } }, x, 4 };
1003 Diagnostic(ErrorCode.ERR_NameNotInContext, "x").WithArguments("x").WithLocation(8, 46),
1004 // (8,49): error CS0846: A nested array initializer is expected
1005 // var a3 = new[,,] { { { 3, 4 } }, x, 4 };
1006 Diagnostic(ErrorCode.ERR_ArrayInitializerExpected, "4").WithLocation(8, 49));
1007 }
1008
1009 [WorkItem(543571, "DevDiv")]
1010 [Fact]
1011 public void CS0826ERR_ImplicitlyTypedArrayNoBestType()
1012 {
1013 var text = @"
1014using System;
1015
1016namespace Test
1017{
1018 public class Program
1019 {
1020 enum E
1021 {
1022 Zero,
1023 FortyTwo = 42
1024 };
1025
1026 public static void Main()
1027 {
1028 E[] a = new[] { E.FortyTwo, 0 }; // Dev10 error CS0826
1029 Console.WriteLine(String.Format(""Type={0}, a[0]={1}, a[1]={2}"", a.GetType(), a[0], a[1]));
1030 }
1031 }
1032}
1033";
1034 CreateCompilationWithMscorlib(text).VerifyDiagnostics(
1035 // (16,21): error CS0826: No best type found for implicitly-typed array
1036 // E[] a = new[] { E.FortyTwo, 0 }; // Dev10 error CS0826
1037 Diagnostic(ErrorCode.ERR_ImplicitlyTypedArrayNoBestType, "new[] { E.FortyTwo, 0 }").WithLocation(16, 21));
1038 }
1039
1040 #endregion
1041 }
1042}