Bug 378189 - gmcs requires void-returning invocation in lambda expression
Summary: gmcs requires void-returning invocation in lambda expression
Status: RESOLVED FIXED
: 392448 (view as bug list)
Alias: None
Product: Mono: Compilers
Classification: Mono
Component: C# (show other bugs)
Version: SVN
Hardware: x86-64 Ubuntu
: P5 - None : Normal
Target Milestone: ---
Assignee: Marek Safar
QA Contact: Mono Bugs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-04-08 23:33 UTC by Casey Marshall
Modified: 2008-07-08 15:02 UTC (History)
1 user (show)

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


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Casey Marshall 2008-04-08 23:33:01 UTC
I can't think up a better summary. This code fails to compile:

>>>>
using System;
using System.Collections;
using System.Collections.Generic;

public static class ext
{
        static public void Apply<T>(IEnumerable<T> a, Action<T> fn)
        {
                foreach (T ai in a)
                        fn(ai);
        }
}

public class action
{
        public static void Main(string[] argv)
        {
                ArrayList list = new ArrayList();
                ext.Apply(argv, str => list.Add(str));
        }
}
<<<<

Failing with:

action.cs(19,21): error CS1502: The best overloaded method match for `ext.Apply<string>(System.Collections.Generic.IEnumerable<string>, System.Action<string>)' has some invalid arguments
action.cs(7,28): (Location of the symbol related to previous error)
action.cs(19,21): error CS1503: Argument 2: Cannot convert type `lambda expression' to `System.Action<string>'
Compilation failed: 2 error(s), 0 warnings

It looks like it was this change: http://anonsvn.mono-project.com/viewcvs/trunk/mcs/mcs/lambda.cs?rev=99156&r1=98957&r2=99156

...which confuses me. Why can't an invocation that returns a non-void type be used here?
Comment 1 Casey Marshall 2008-04-08 23:34:17 UTC
Or possibly this change: http://anonsvn.mono-project.com/viewcvs/trunk/mcs/mcs/lambda.cs?rev=98957&r1=98284&r2=98957
Comment 2 Casey Marshall 2008-06-11 00:23:32 UTC
Ping.

Still an issue with rev. 105078.
Comment 3 M. David Peterson 2008-06-17 00:07:52 UTC
As well at rev. 105925

In my particular case, this bug makes itself know via:

Bug: "Cannot convert type `lambda expression' to `System.Action'"

    ./Async.cs(143,29): error CS1502: The best overloaded method match for `EeekSoft.Asynchronous.AsyncExtensions.Run(System.Collections.Generic.IEnumerator<EeekSoft.Asynchronous.IAsync>, System.Action)' has some invalid arguments
    ./Async.cs(189,30): (Location of the symbol related to previous error)
    ./Async.cs(143,29): error CS1503: Argument 2: Cannot convert type `lambda expression' to `System.Action'


This bug makes itself known on recent SVN revisions but -- strangely -- compiles just fine on 1.9.1
Compiles as expect on MS.NET

Steps to repro:  Using recent SVN revision,

    svn co http://nuxleus.googlecode.com/svn/trunk/nuxleus/Source/Nuxleus.Extension.Linq/
    co Nuxleus.Extension.Linq
    gmcs -t:library -recurse:*.cs -r:System.Xml -r:System.Xml.Linq -out:Nuxleus.Extension.Aws.dll


Expected results: As per release 1.9.1,

    $ which mono
    /usr/bin/mono
    $ mono -V
    Mono JIT compiler version 1.9.1 (tarball)
    Copyright (C) 2002-2007 Novell, Inc and Contributors. www.mono-project.com
            TLS:           __thread
            GC:            none
            SIGSEGV:       altstack
            Notifications: epoll
            Architecture:  amd64
            Disabled:      none
    $ gmcs -t:library -recurse:*.cs -r:System.Xml -r:/usr/lib/mono/3.5/System.Xml.Linq -out:Nuxleus.Extension.Aws.dll
    $


Actual results: As per SVN 105925 (tarbal)

    $ which mono
    /usr/bin/mono
    $ mono -V
    Mono JIT compiler version 105925 (tarball)
    Copyright (C) 2002-2008 Novell, Inc and Contributors. www.mono-project.com
            TLS:           __thread
            GC:            Included Boehm (with typed GC)
            SIGSEGV:       altstack
            Notifications: epoll
            Architecture:  amd64
            Disabled:      none
    $ gmcs -t:library -recurse:*.cs -r:System.Xml -r:System.Xml.Linq -out:Nuxleus.Extension.Aws.dll
    ./Async.cs(143,29): error CS1502: The best overloaded method match for `EeekSoft.Asynchronous.AsyncExtensions.Run(System.Collections.Generic.IEnumerator<EeekSoft.Asynchronous.IAsync>, System.Action)' has some invalid arguments
    ./Async.cs(189,30): (Location of the symbol related to previous error)
    ./Async.cs(143,29): error CS1503: Argument 2: Cannot convert type `lambda expression' to `System.Action'
    Compilation failed: 2 error(s), 0 warnings
    $
Comment 4 M. David Peterson 2008-07-06 12:57:52 UTC
(In reply to comment #1 from Casey Marshall)
> Or possibly this change:
> http://anonsvn.mono-project.com/viewcvs/trunk/mcs/mcs/lambda.cs?rev=98957&r1=98284&r2=98957

So I just recompiled Mono head (r107318), reverting lamda.cs to its state in r98284 and the problem goes away.  Of course I have no clue what, if any, regressions would be introduced by reverting to r98284, but at least this should provide a clue as to how this bug can be fixed.


Comment 5 Casey Marshall 2008-07-06 19:41:45 UTC
The exact issue is in lambda.cs, ContextualReturn.DoResolve. If the expression is an invocation, and the containing context resolves to `void', it explicitly tests if the return type of the invocation is `void'.

I believe this is incorrect, though it does resolve another bug (Bug 370577), where resolving same-named methods fails -- this happens to resolve that bug because one of the methods in the test case takes an Action<T>, and thus would require a void expression, which the lambda method doesn't match. From the test case, it's obvious that only one `Foo' method is appropriate, since it's being called where it is returning a value (of type string). It's a problem of overload resolution given that one of the methods is generic.

The implementation also now seems to contradict the comments above that class describing its purpose: that a contextual return behaves as either `return expr()' or as `expr(); return;', depending on the containing context.
Comment 6 Marek Safar 2008-07-08 14:57:01 UTC
Fixed in SVN.
Comment 7 Marek Safar 2008-07-08 15:02:40 UTC
*** Bug 392448 has been marked as a duplicate of this bug. ***