Bugzilla – Bug 378189
gmcs requires void-returning invocation in lambda expression
Last modified: 2008-07-08 15:02:40 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?
Or possibly this change: http://anonsvn.mono-project.com/viewcvs/trunk/mcs/mcs/lambda.cs?rev=98957&r1=98284&r2=98957
Ping. Still an issue with rev. 105078.
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 $
(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.
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.
Fixed in SVN.
*** Bug 392448 has been marked as a duplicate of this bug. ***