http://bugzilla.novell.com/show_bug.cgi?id=591226
http://bugzilla.novell.com/show_bug.cgi?id=591226#c0 Summary: Using Reflection.Emit to generate a generic method may lead to invalid codegen Classification: Mono Product: Mono: Runtime Version: 2.6.x Platform: x86 OS/Version: All Status: NEW Severity: Normal Priority: P5 - None Component: generics AssignedTo: [email protected] ReportedBy: [email protected] QAContact: [email protected] Found By: --- Blocker: --- User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; MS-RTC LM 8; InfoPath.2; .NET4.0C; .NET4.0E) It looks like if two non-generic classes are emitted into a module, with one containing a specialized call to a generic method defined in the other, there’s a problem with the code generated for the specialized call. Reproducible: Always Steps to Reproduce: 1. Download the latest F# CTP http://www.microsoft.com/downloads/details.aspx?FamilyID=b55f0532-ac3c-4106-918c-5586a953a7da&displaylang=en 2. Run FSI.exe through Mono 3. Enter the following code: let myFunc x y = if x > y then stdout.WriteLine("greater {0} {1}",x,y); if x < y then stdout.WriteLine("less {0} {1}",x,y); if x = y then stdout.WriteLine("equal {0} {1}",x,y); myFunc 1 4;; Actual Results: The above will yield the following output using Mono 2.6.3 (tested on both Windows 7 and Mac OS X 10.5.8/Intel): greater 1 4 less 1 4 equal 1 4 val myFunc : 'a -> 'a -> unit when 'a : comparison Expected Results: The above is incorrect. The output should be: less 1 4 val myFunc : 'a -> 'a -> unit when 'a : comparison Copy and paste the following code fragment into fsi.exe: let myFunc x y = if x > y then stdout.WriteLine("greater {0} {1}",x,y); if x < y then stdout.WriteLine("less {0} {1}",x,y); if x = y then stdout.WriteLine("equal {0} {1}",x,y); myFunc 1 4;; The above will yield the following output using Mono 2.6.3 (tested on both Windows 7 and Mac OS X 10.5.8/Intel): greater 1 4 less 1 4 equal 1 4 val myFunc : 'a -> 'a -> unit when 'a : comparison The above is incorrect. The output should be: less 1 4 val myFunc : 'a -> 'a -> unit when 'a : comparison On the Microsoft CLR, the correct output is generated. It looks like if two non-generic classes are emitted into a module, with one containing a specialized call to a generic method defined in the other, there’s a problem with the code generated for the specialized call. (To be clear, in the example above, fsi.exe will emit two classes - one with myFunc defined as a static method, and another with a static “main” method that calls “myFunc 1 4”. When the fragment is evaluated, the “main” method is called.) Here’s a clearer example that will produce the same incorrect output: type A() = member a.Foo x y = if x > y then stdout.WriteLine("greater {0} {1}",x,y); if x < y then stdout.WriteLine("less {0} {1}",x,y); if x = y then stdout.WriteLine("equal {0} {1}",x,y); and B() = member b.Bar x y = let a = A() in a.Foo x y let _ = let b = B() in b.Bar 1 4 And one more sample, reported by a user: let reduce gen = match gen with | [_; _] -> printfn "path1" 1 | [_] -> printfn "path2" 2 | _ -> 3 printfn "result = %A" (reduce [1;2]) In this case, the expression “reduce [1;2]” will evaluate to “path2”, where it should evaluate to “path1”. It’s important to note that in all of these cases, if the “call” method is emitted separately from the generic method (that is, as two separate evaluated expressions), the correct code will be generated. For example: // evaluate the definition of myFunc let myFunc x y = if x > y then stdout.WriteLine("greater {0} {1}",x,y); if x < y then stdout.WriteLine("less {0} {1}",x,y); if x = y then stdout.WriteLine("equal {0} {1}",x,y);; val myFunc : 'a -> 'a -> unit when 'a : comparison // Ok, fsi.exe has evaluated it - now call it less 1 4 val it : unit = () // correct! -- Configure bugmail: http://bugzilla.novell.com/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are the QA contact for the bug. You are the assignee for the bug. _______________________________________________ mono-bugs maillist - [email protected] http://lists.ximian.com/mailman/listinfo/mono-bugs
