Bug 359594

Summary: Mono doesn't support co-/contravariant generic parameters
Product: [Mono] Mono: Runtime Reporter: Steffen Kieß <s-kiess>
Component: genericsAssignee: Mono Bugs <mono-bugs>
Status: RESOLVED DUPLICATE QA Contact: Mono Bugs <mono-bugs>
Severity: Normal    
Priority: P5 - None CC: forgotten_vxPDddArjq
Version: SVN   
Target Milestone: ---   
Hardware: x86-64   
OS: Other   
Whiteboard:
Found By: --- Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---

Description Steffen Kieß 2008-02-07 15:16:08 UTC
Mono doesn't support co-/contravariant generic parameters.

The nemerle program:

using System;

public interface A[+T] {
  getObj () : T;
}

public class B[T] : A[T] {
  public getObj () : T {
    throw Exception ();
  }
}

public class M {
  public static Main () : void {
    def b : B[string] = B ();
    def a : A[object] = b;
    _ = a.getObj ();
  }
}


which will be compiled to the IL:

.assembly extern mscorlib
{
  .ver 2:0:0:0
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
}
.assembly 'MonoCovariance'
{
  .custom instance void class [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) =  (01 00 01 01 00 00 00 00 ) // ........

  .custom instance void class [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) =  (01 00 08 00 00 00 00 00 ) // ........

  .hash algorithm 0x00008004
  .ver  0:0:0:0
}
.module MonoCovariance // GUID = {A2F61D8A-1737-45FB-9839-73E733D74B3C}


  .class interface public auto ansi abstract beforefieldinit A`1<+ T>
  {

    // method line 1
    .method public virtual  hidebysig  abstract 
           instance default !T getObj ()  cil managed 
    {
        // Method begins at RVA 0x0
    } // end of method A`1::getObj

  } // end of class A`1

  .class public auto ansi beforefieldinit B`1<T>
  	extends [mscorlib]System.Object
  	implements class A`1<!0>  {

    // method line 2
    .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 object::.ctor()
	IL_0006:  ret 
    } // end of method B`1::.ctor

    // method line 3
    .method public final  virtual  hidebysig  newslot 
           instance default !T getObj ()  cil managed 
    {
        // Method begins at RVA 0x20f4
	// Code size 8 (0x8)
	.maxstack 8
	IL_0000:  nop 
	IL_0001:  nop 
	IL_0002:  newobj instance void class [mscorlib]System.Exception::.ctor()
	IL_0007:  throw 
    } // end of method B`1::getObj

  } // end of class B`1

  .class public auto ansi beforefieldinit M
  	extends [mscorlib]System.Object
  {

    // method line 4
    .method public hidebysig  specialname  rtspecialname 
           instance default void .ctor ()  cil managed 
    {
        // Method begins at RVA 0x2100
	// Code size 7 (0x7)
	.maxstack 8
	IL_0000:  ldarg.0 
	IL_0001:  call instance void object::.ctor()
	IL_0006:  ret 
    } // end of method M::.ctor

    // method line 5
    .method public static  hidebysig 
           default void Main ()  cil managed 
    {
        // Method begins at RVA 0x2108
	.entrypoint
	// Code size 21 (0x15)
	.maxstack 3
	.locals init (
		class B`1<string>	V_0,
		class A`1<object>	V_1)
	IL_0000:  nop 
	IL_0001:  nop 
	IL_0002:  newobj instance void class B`1<string>::.ctor()
	IL_0007:  stloc.0 
	IL_0008:  nop 
	IL_0009:  ldloc.0 
	IL_000a:  stloc.1 
	IL_000b:  nop 
	IL_000c:  ldloc.1 
	IL_000d:  callvirt instance !0 class A`1<object>::getObj()
	IL_0012:  pop 
	IL_0013:  nop 
	IL_0014:  ret 
    } // end of method M::Main

  } // end of class M


will crash mono.

PEVerify says it's fine:

Microsoft (R) .NET Framework PE Verifier.  Version  2.0.50727.42
Copyright (c) Microsoft Corporation.  All rights reserved.

All Classes and Methods in C:\cygwin\tmp\peverify.QLN264\MonoCovariance.exe Verified.


Output of mono:

B<System.String> doesn't implement interface A<System.Object>

** ERROR **: file mini-trampolines.c: line 42 (mono_convert_imt_slot_to_vtable_slot): should not be reached
aborting...
Stacktrace:

  at M.Main () <0xffffffff>
  at M.Main () <0x00037>
  at (wrapper runtime-invoke) System.Object.runtime_invoke_void (object,intptr,intptr,intptr) <0xffffffff>

Native stacktrace:

	/home/steffen/mono-svn/bin/mono [0x537eed]
	/lib/libpthread.so.0 [0x2b850cf757d0]
	/lib/libc.so.6(gsignal+0x35) [0x2b850d436025]
	/lib/libc.so.6(abort+0x110) [0x2b850d437a80]
	/usr/lib/libglib-2.0.so.0(g_log+0) [0x2b850caed4b0]
	/usr/lib/libglib-2.0.so.0(g_log+0x83) [0x2b850caed533]
	/usr/lib/libglib-2.0.so.0(g_assert_warning+0x76) [0x2b850caed5b6]
	/home/steffen/mono-svn/bin/mono [0x53c6b7]
	/home/steffen/mono-svn/bin/mono [0x53ca38]
	[0x40000160]

Debug info from gdb:

Using host libthread_db library "/lib/libthread_db.so.1".
[Thread debugging using libthread_db enabled]
[New Thread 0x2b850d989040 (LWP 11642)]
[New Thread 0x40224950 (LWP 11644)]
[New Thread 0x40023950 (LWP 11643)]
0x00002b850d4a1c0b in fork () from /lib/libc.so.6
  3 Thread 0x40023950 (LWP 11643)  0x00002b850cf74e81 in nanosleep ()
   from /lib/libpthread.so.0
  2 Thread 0x40224950 (LWP 11644)  0x00002b850cf71b99 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0
  1 Thread 0x2b850d989040 (LWP 11642)  0x00002b850d4a1c0b in fork ()
   from /lib/libc.so.6

Thread 3 (Thread 0x40023950 (LWP 11643)):
#0  0x00002b850cf74e81 in nanosleep () from /lib/libpthread.so.0
#1  0x00000000004d685f in collection_thread (unused=<value optimized out>)
    at collection.c:34
#2  0x00002b850cf6d3f7 in start_thread () from /lib/libpthread.so.0
#3  0x00002b850d4db97d in clone () from /lib/libc.so.6
#4  0x0000000000000000 in ?? ()

Thread 2 (Thread 0x40224950 (LWP 11644)):
#0  0x00002b850cf71b99 in pthread_cond_wait@@GLIBC_2.3.2 ()
   from /lib/libpthread.so.0
#1  0x00000000004e1aa5 in timedwait_signal_poll_cond (cond=0x2aaaab5f8268, 
    mutex=0x2aaaab5f8240, timeout=0x1, alertable=-1) at handles.c:1443
#2  0x00000000004e4017 in _wapi_handle_timedwait_signal_handle (
    handle=<value optimized out>, timeout=0x0, alertable=0) at handles.c:1523
#3  0x00000000004d1a53 in WaitForSingleObjectEx (handle=0x404, 
    timeout=4294967295, alertable=0) at wait.c:200
#4  0x000000000053db81 in finalizer_thread (unused=<value optimized out>)
    at gc.c:894
#5  0x000000000046cd7c in start_wrapper (data=<value optimized out>)
    at threads.c:589
#6  0x00000000004d6593 in thread_start_routine (args=0x2aaaab661a60)
    at threads.c:282
#7  0x00000000004ed7b2 in GC_start_routine (arg=<value optimized out>)
    at pthread_support.c:1369
#8  0x00002b850cf6d3f7 in start_thread () from /lib/libpthread.so.0
#9  0x00002b850d4db97d in clone () from /lib/libc.so.6
#10 0x0000000000000000 in ?? ()

Thread 1 (Thread 0x2b850d989040 (LWP 11642)):
#0  0x00002b850d4a1c0b in fork () from /lib/libc.so.6
#1  0x00002b850cb1335d in ?? () from /usr/lib/libglib-2.0.so.0
#2  0x00002b850cb13eaf in g_spawn_sync () from /usr/lib/libglib-2.0.so.0
#3  0x00002b850cb14368 in g_spawn_command_line_sync ()
   from /usr/lib/libglib-2.0.so.0
#4  0x0000000000537f7f in mono_handle_native_sigsegv (
    signal=<value optimized out>, ctx=<value optimized out>)
    at mini-exceptions.c:1046
#5  <signal handler called>
#6  0x00002b850d436025 in raise () from /lib/libc.so.6
#7  0x00002b850d437a80 in abort () from /lib/libc.so.6
#8  0x00002b850caed4b0 in g_logv () from /usr/lib/libglib-2.0.so.0
#9  0x00002b850caed533 in g_log () from /usr/lib/libglib-2.0.so.0
#10 0x00002b850caed5b6 in g_assert_warning () from /usr/lib/libglib-2.0.so.0
#11 0x000000000053c6b7 in mono_convert_imt_slot_to_vtable_slot (slot=0x88ad70, 
    regs=<value optimized out>, code=<value optimized out>, 
    method=<value optimized out>, impl_method=0x7fff9e61d5b8)
    at mini-trampolines.c:42
#12 0x000000000053ca38 in mono_magic_trampoline (regs=0x7fff9e61d7b0, 
    code=0x40010327 "L\213,$H\203�\030������\004�U\212", m=0x8a5830, 
    tramp=<value optimized out>) at mini-trampolines.c:125
#13 0x0000000040000160 in ?? ()
#14 0x0000000000000000 in ?? ()
#0  0x00002b850d4a1c0b in fork () from /lib/libc.so.6


=================================================================
Got a SIGABRT while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries 
used by your application.
=================================================================

Mono is SVN rev 95083.
Comment 1 Forgotten User vxPDddArjq 2008-02-07 16:44:05 UTC

*** This bug has been marked as a duplicate of bug 321674 ***