Bugzilla – Bug 316237
[GMCS]: Casting to a generic instance
Last modified: 2007-09-15 21:24:46 UTC
---- Reported by luca.barbieri@gmail.com 2004-10-13 18:11:28 MST ---- Description of Problem: The attached code doesn't work, which is astounding. Steps to reproduce the problem: 1. Compile the C# code attached with CVS gmcs and run with CVS mono Actual Results: Unhandled Exception: System.InvalidCastException: Cannot cast from source type to destination type. in [0x00000] (at /home/lb/pers/src/test.cs:13) MainClass:Main (string[]) Expected Results: No exceptions. C# code: class MainClass { class Gen<T> { } class Der : Gen<int> { } static int Main(string[] args) { Gen<int> b = (Gen<int>)(object)new Der(); return 0; } } Disassembled IL code: .assembly extern mscorlib { .ver 2:0:3600:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. } .assembly 'test' { .hash algorithm 0x00008004 .ver 0:0:0:0 } .module test.exe // GUID = {C792D86F-B92C-41AF-8420-E7F2C08BE1AD} .class private auto ansi beforefieldinit MainClass extends [mscorlib]System.Object { // method line 1 .method public hidebysig specialname rtspecialname instance default void .ctor () cil managed { // Method begins at RVA 0x20ec // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void class [mscorlib]System.Object::.ctor() IL_0006: ret } // end of method MainClass::instance default void .ctor () // method line 2 .method private static hidebysig default int32 Main (string[] args) cil managed { // Method begins at RVA 0x20f4 .entrypoint // Code size 13 (0xd) .maxstack 2 .locals init ( class 'MainClass/Gen`1'<int32> V_0) IL_0000: newobj instance void class 'MainClass/Der'::.ctor() IL_0005: castclass class 'MainClass/Gen`1'<int32> IL_000a: stloc.0 IL_000b: ldc.i4.0 IL_000c: ret } // end of method MainClass::default int32 Main (string[] args) .class nested private auto ansi beforefieldinit 'Gen`1'<T> extends [mscorlib]System.Object { // method line 3 .method public hidebysig specialname rtspecialname instance default void .ctor () cil managed { // Method begins at RVA 0x2110 // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void class [mscorlib]System.Object::.ctor() IL_0006: ret } // end of method Gen`1::instance default void .ctor () } // end of class Gen`1 .class nested private auto ansi beforefieldinit Der extends class 'MainClass/Gen`1'<int32> { // method line 4 .method public hidebysig specialname rtspecialname instance default void .ctor () cil managed { // Method begins at RVA 0x2118 // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void class 'MainClass/Gen`1'<int32>::.ctor() IL_0006: ret } // end of method Der::instance default void .ctor () } // end of class Der } // end of class MainClass ---- Additional Comments From luca.barbieri@gmail.com 2004-10-13 18:21:03 MST ---- It also fails if Gen<int> is replaced with Gen<REF_TYPE> where REF_TYPE is a reference type, while of course it works if Gen<int> is replaced with a non-generic type. ---- Additional Comments From martin@ximian.com 2004-10-13 18:44:03 MST ---- Very funny summary ;-) ---- Additional Comments From luca.barbieri@gmail.com 2004-10-13 19:02:11 MST ---- Are you sure that the problem is gmcs? The IL code it generates seems correct. ---- Additional Comments From luca.barbieri@gmail.com 2004-10-13 19:12:30 MST ---- This code also FAILS: class MainClass { class Base { } class Gen<T> : Base { } class Der : Gen<int> { } static int Main(string[] args) { Base b = (Base)(object)new Der(); return 0; } } And this too FAILS: class MainClass { class Base { } class Gen<T> : Base { } class Der<T> : Gen<T> { } static int Main(string[] args) { Gen<int> b = (Gen<int>)(object)new Der<int>(); return 0; } } But this WORKS: class MainClass { class Base { } class Gen<T> : Base { } class Der<T> : Gen<T> { } static int Main(string[] args) { Base b = (Base)(object)new Der<int>(); return 0; } } This also WORKS: class MainClass { class Base { } class Gen<T> : Base { } class Der<T> : Gen<int> { } static int Main(string[] args) { Base b = (Base)(object)new Der<int>(); return 0; } } But very surprisingly this FAILS: class MainClass { class Base { } class Gen<T> : Base { } class Der : Gen<int> { } static int Main(string[] args) { Base b = (Base)(object)new Der(); return 0; } } ---- Additional Comments From martin@ximian.com 2004-10-13 19:36:09 MST ---- This is not a blocker, resetting priority. ---- Additional Comments From martin@ximian.com 2004-11-22 09:15:19 MST ---- Fixed in SVN. Unknown bug field "cf_op_sys_details" encountered while moving bug <cf_op_sys_details>Fedora Development on Pentium M</cf_op_sys_details> Unknown operating system unknown. Setting to default OS "Other".