Bug 318987 (MONO76097) - [GMCS] iterators in generic methods
Summary: [GMCS] iterators in generic methods
Status: RESOLVED FIXED
Alias: MONO76097
Product: Mono: Compilers
Classification: Mono
Component: C# (show other bugs)
Version: 1.1
Hardware: Other Other
: P3 - Medium : Major
Target Milestone: ---
Assignee: Martin Baulig
QA Contact: Mono Bugs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-09-14 10:06 UTC by Peter Sestoft
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
a patch that fixes a bug that causes internal exception inside GenericTypeParameterBuilder (1.14 KB, patch)
2005-10-19 14:20 UTC, Thomas Wiest
Details | Diff

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


---- Reported by sestoft@dina.kvl.dk 2005-09-14 03:06:49 MST ----

Description of Problem:

The gmcs 1.1.9 type checker does not take type parameter constraint Aa : Af
into account when checking method body.

Steps to reproduce the problem:
1. Compile the program inserted below
2. Observe unexpected compiler error message

Actual Results:

https://bugzilla.novell.com/show_bug.cgi?id=MONO15.cs(24,20): error CS1594: Delegate `Fun<Af,Rf>' has some invalid arguments
https://bugzilla.novell.com/show_bug.cgi?id=MONO15.cs(24,20): error CS1503: Argument 1: Cannot convert from `Aa' to `in Af'
Compilation failed: 2 error(s), 0 warnings

Expected Results:

It should compile without problems, and does in MS beta 2.

// -------------------

using System;
using System.Collections.Generic;

class MyTest {
  public static void Main(String[] args) {
    foreach (Object d in Map<int,int,String,Object>
	                    (delegate (int x) { return x.ToString(); }, 
			     FromTo(10,20)))
      Console.WriteLine(d);
  }

  // Map with argument/result co/contravariance:
  // Aa=argument, Rr=result, Af=f's argument, Rf=f's result

  public static IEnumerable<Rr> Map<Aa,Af,Rf,Rr>(Fun<Af,Rf> f, 
                                                 IEnumerable<Aa> xs) 
    where Aa : Af 
    where Rf : Rr 
  { 
    foreach (Aa x in xs)
      yield return f(x);    // gmcs 1.1.9 bug: cannot convert Aa to Af
  }

  // FromTo : int * int -> int stream

  public static IEnumerable<int> FromTo(int from, int to) { 
    for (int i=from; i<=to; i++)
      yield return i;
  }
}



---- Additional Comments From atsushi@ximian.com 2005-10-19 00:41:20 MST ----

This is the output from csc (beta2). Obviously Foo is missing in the
code above.

76097.cs(15,50): error CS0246: The type or namespace name 'Fun' could
not be found (are you missing a using directive or an assembly reference?)



---- Additional Comments From sestoft@dina.kvl.dk 2005-10-19 04:36:10 MST ----

Sorry, somehow I neglected to include this declaration:

  public delegate R Fun<A1,R>(A1 x);



---- Additional Comments From atsushi@ximian.com 2005-10-19 07:19:21 MST ----

Ok, now I got the exception stack trace below:

Unhandled Exception: System.NotSupportedException: Operation is not
supported.
in <0x00014>
System.Reflection.Emit.GenericTypeParameterBuilder:GetGenericArguments ()
in <0x0006d> Mono.CSharp.TypeManager:GetNumberOfTypeArguments
(System.Type t)
in <0x0000b> Mono.CSharp.TypeManager:HasGenericArguments (System.Type t)
in <0x00030> Mono.CSharp.ConstructedType:CheckConstraint
(Mono.CSharp.EmitContext ec, System.Type ptype, Mono.CSharp.Expression
expr, System.Type ctype)
in <0x0042a> Mono.CSharp.ConstructedType:CheckConstraints
(Mono.CSharp.EmitContext ec, Int32 index)
in <0x00018> Mono.CSharp.ConstructedType:CheckConstraints
(Mono.CSharp.EmitContext ec)
in <0x00125> Mono.CSharp.Expression:ResolveAsTypeTerminal
(Mono.CSharp.EmitContext ec, Boolean silent)
in <0x00010> Mono.CSharp.Expression:ResolveAsTypeTerminal
(Mono.CSharp.EmitContext ec)
in <0x00502> Mono.CSharp.Iterator:Create_Block ()
in <0x000dd> Mono.CSharp.Iterator:DefineNestedTypes ()
in <0x00b48> Mono.CSharp.TypeContainer:DefineType ()
in <0x000d8> Mono.CSharp.Class:DefineType ()
in <0x00834> Mono.CSharp.TypeContainer:DoDefineMembers ()
in <0x00050> Mono.CSharp.TypeContainer:DefineMembers
(Mono.CSharp.TypeContainer container)
in <0x0024f> Mono.CSharp.RootContext:PopulateTypes ()
in <0x00b7b> Mono.CSharp.Driver:MainDriver (System.String[] args)
in <0x00051> Mono.CSharp.Driver:Main (System.String[] args)

Am attaching a patch that *does not* fix the bug but does fix the
exception.



---- Additional Comments From atsushi@ximian.com 2005-10-19 07:20:29 MST ----

Created an attachment (id=168505)
a patch that fixes a bug that causes internal exception inside GenericTypeParameterBuilder




---- Additional Comments From martin@ximian.com 2005-10-19 14:13:56 MST ----

Well, that patch is definitely a no-go - of course, just returning an
empty list is not an option here.

What we need to do for GenericTypeParameterBuilder's is lookup its
definition via typemanager; ie. we get the `TypeContainer' which
defines its containing class and then lookup the `TypeParameter' for it.

I'll have a look at this.



---- Additional Comments From martin@ximian.com 2005-10-19 14:17:23 MST ----

Ooops, I was confused - I tought it was trying to get the constraints
from the type parameter.



---- Additional Comments From martin@ximian.com 2005-10-19 14:18:51 MST ----

So the correct fix is in TypeManager.GetNumberOfTypeArguments():
  if (t.IsGenericParameter)
    return 0;



---- Additional Comments From martin@ximian.com 2005-10-19 14:37:06 MST ----

I think I have an idea:

=====
(*) #0: 0x404cc329 in
Mono.CSharp.TypeManager.GetTypeParameterConstraints(System.Type)+0x59
at /work/gondor/mono/mcs/gmcs/generic.cs:1834
    #1: 0x404d8b9e in
Mono.CSharp.ConstructedType.CheckConstraint(Mono.CSharp.EmitContext,System.Type,Mono.CSharp.Expression,System.Type)+0x266
at /work/gondor/mono/mcs/gmcs/generic.cs:1305
    #2: 0x404b150d in
Mono.CSharp.ConstructedType.CheckConstraints(Mono.CSharp.EmitContext,System.Int32)+0x65d
at /work/gondor/mono/mcs/gmcs/generic.cs:1386
    #3: 0x404b0e3b in
Mono.CSharp.ConstructedType.CheckConstraints(Mono.CSharp.EmitContext)+0x2b
at /work/gondor/mono/mcs/gmcs/generic.cs:1458
    #4: 0x404a6b88 in
Mono.CSharp.Expression.ResolveAsTypeTerminal(Mono.CSharp.EmitContext,System.Boolean)+0x1d8
at /work/gondor/mono/mcs/gmcs/ecore.cs:272
    #5: 0x404a69a7 in
Mono.CSharp.Expression.ResolveAsTypeTerminal(Mono.CSharp.EmitContext)+0x27
at /work/gondor/mono/mcs/gmcs/ecore.cs:247
    #6: 0x404d7d36 in Mono.CSharp.Iterator.Create_Block()+0x76e at
/work/gondor/mono/mcs/gmcs/iterators.cs:663
    #7: 0x404d331d in Mono.CSharp.Iterator.DefineNestedTypes()+0x135
at /work/gondor/mono/mcs/gmcs/iterators.cs:611
    #8: 0x404a4863 in Mono.CSharp.TypeContainer.DefineType()+0x112b at
/work/gondor/mono/mcs/gmcs/class.cs:1375
    #9: 0x404a370d in Mono.CSharp.Class.DefineType()+0x145 at
/work/gondor/mono/mcs/gmcs/class.cs:3179
    #10: 0x404b3f27 in
Mono.CSharp.TypeContainer.DoDefineMembers()+0xb4f at
/work/gondor/mono/mcs/gmcs/class.cs:1639
    #11: 0x404b330c in
Mono.CSharp.TypeContainer.DefineMembers(Mono.CSharp.TypeContainer)+0x64
at /work/gondor/mono/mcs/gmcs/class.cs:1531
    #12: 0x404b20df in Mono.CSharp.RootContext.PopulateTypes()+0x357
at /work/gondor/mono/mcs/gmcs/rootcontext.cs:529
    #13: 0x40427982 in
Mono.CSharp.Driver.MainDriver(System.String[])+0x155a at
/work/gondor/mono/mcs/gmcs/driver.cs:1603
    #14: 0x40017ed5 in Mono.CSharp.Driver.Main(System.String[])+0xa5
at /work/gondor/mono/mcs/gmcs/driver.cs:287
=====

We're called from RootContext.PopulateTypes(), but still the type
parameter's constraints are not defined yet.  I believe this is some
problem with generic methods and iterators.



---- Additional Comments From martin@ximian.com 2005-10-19 23:40:37 MST ----

Fixed in SVN.

Imported an attachment (id=168505)

Unknown operating system unknown. Setting to default OS "Other".