Bug 318251 (MONO75248) - [GMCS]junk read by reflection for nested generic types
Summary: [GMCS]junk read by reflection for nested generic types
Status: RESOLVED WONTFIX
Alias: MONO75248
Product: Mono: Runtime
Classification: Mono
Component: io-layer (show other bugs)
Version: 1.1
Hardware: Other Other
: P3 - Medium : Enhancement
Target Milestone: ---
Assignee: Martin Baulig
QA Contact: Mono Bugs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-06-13 14:26 UTC by Michal Moskal
Modified: 2007-09-15 21:24 UTC (History)
0 users

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments
testcase (1.14 KB, application/octet-stream)
2005-06-13 14:27 UTC, Thomas Wiest
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Wiest 2007-09-15 19:21:03 UTC


---- Reported by malekith@pld-linux.org 2005-06-13 07:26:33 MST ----

Description of Problem:

When you define a nested generic type inside another generic type, mono's
reflection takes !1 as a reference to wrong type parameter (namely the one
from nested class not the global class).

For the following piece of Nemerle code:


  interface IComp ['a] {  }
  class opt ['c] { }

abstract class Func [p1, r]
{
  public apply (x : p1) : r { throw System.Exception () }
}

  class NemerleMap ['a, 'b] where 'a : IComp ['a]
  {
    public Find (k : 'a) : opt ['b]
    {
      null
    }

    public Fold['d] (y : 'a) : void
    {
      def x = lambda ();
      _ = x.apply (y);
    }

     class lambda [d, aa, bb] : Func [aa, aa] where aa : IComp [aa] {
        public  apply2 (x : aa) : aa {
          x;
        }
      }

  }

after compiling it to a dll reflection says that return type of Find is
opt<aa> and not opt<'b>. monodis handles it right, ms.net reflection,
peverify and ildasm are also all OK with this.

Steps to reproduce the problem:
1. untar attachment
2. compile and run attached C# program for reading assembly

Actual Results:
opt<aa>

Expected Results:
opt<'b>

Additional Information:
I'm using svn trunk.



---- Additional Comments From malekith@pld-linux.org 2005-06-13 07:27:27 MST ----

Created an attachment (id=168123)
testcase




---- Additional Comments From nazgul@omega.pl 2005-06-13 13:45:53 MST ----

After a little debugging I found out that there is some serious data
invariants violation in runtime. The bug occurs, because in 

mono_metadata_lookup_generic_inst

the incorrect cache value is returned:

(gdb) p ginst->type_argv[0]->data.generic_param.name
$4 = 0xb752a748 "'b"
(gdb) p cached
$5 = (MonoGenericInst *) 0x8274df8
(gdb) p cached -> type_argv[0]->data.generic_param.name
$6 = 0xb752a74d "aa"

indeed their metadata used in hashtable compare are the same:

(gdb) p cached -> type_argv[0]->data.generic_param.owner
$7 = (MonoGenericContainer *) 0x8274850
(gdb) p ginst->type_argv[0]->data.generic_param.owner
$8 = (MonoGenericContainer *) 0x8274850

but evidently the value already in cache have wrong generic context
attached:

(gdb) p cached -> type_argv[0]->data.generic_param.owner->klass->name
$10 = 0xb752a708 "NemerleMap"
(gdb) p cached -> type_argv[0]->data.generic_param.name
$11 = 0xb752a74d "aa"

I dunno where it gets such context...



---- Additional Comments From martin@ximian.com 2005-06-15 15:41:36 MST ----

The `out.exe' has an incorrect nested class - it's missing the type
parameters from the containing class.  Since this is a violation of
the spec and it'd require a lot of work, let's close this as WONTFIX.



---- Additional Comments From martin@ximian.com 2005-06-15 15:42:06 MST ----

Equivalent C# test case:

=====
interface IComp<a>
{ }
 
class opt<c>
{ }
 
abstract class Func<p1,r>
{
        public r apply (p1 x)
        {
                throw new System.Exception ();
        }
}
 
class NemerleMap<a,b>
        where a : IComp<a>
{
        public opt<b> Find (a k)
        {
                return null;
        }
 
        public void Fold<d> (a y)
        {
        }
 
        class lambda<d,aa,bb> : Func<aa,aa>
                where aa : IComp<aa>
        {
                public aa apply2 (aa x)
                {
                        return x;
                }
        }
}
====



---- Additional Comments From martin@ximian.com 2005-06-15 15:43:25 MST ----

Note that this is encoded in IL as:

====
.class private auto ansi beforefieldinit NemerleMap`2<(class
IComp`1<!a>) a,b>
       extends [mscorlib]System.Object
{
  .class auto ansi nested private beforefieldinit lambda`3<(class
IComp`1<!a>) a,b,d,(class IComp`1<!aa>) aa,
                                                           bb>
         extends class Func`2<!aa,!aa>
====

when compiled with csc - ie. the nested class inherits the type
parameters of its parent.



---- Additional Comments From malekith@pld-linux.org 2005-06-16 05:39:31 MST ----

Is it violation of C# spec or IL/metadata spec?

Anyway we had the type parameters copied by at the end not at the
beginning of the parameter list, so I'll just fix it on our side.

Imported an attachment (id=168123)

Unknown bug field "cf_op_sys_details" encountered while moving bug
   <cf_op_sys_details>amd 64 pld linux</cf_op_sys_details>
Unknown operating system unknown. Setting to default OS "Other".