Bug 17470 - Mono C# compiler incorrectly resolves property access over method group when name of property matches its class name and class of method group
Summary: Mono C# compiler incorrectly resolves property access over method group when ...
Status: VERIFIED NOT_REPRODUCIBLE
Alias: None
Product: Compilers
Classification: Mono
Component: C# ()
Version: unspecified
Hardware: All All
: --- normal
Target Milestone: ---
Assignee: Marek Safar
URL:
Depends on:
Blocks:
 
Reported: 2014-01-28 12:24 UTC by Richard Cook
Modified: 2014-02-25 13:17 UTC (History)
4 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
VERIFIED NOT_REPRODUCIBLE

Description Richard Cook 2014-01-28 12:24:44 UTC
The Mono C# compiler (mcs) incorrectly resolves property access over method group when name of property matches its class name and class of method group. This results in compiler error CS0120 when the ambiguity is resolved in the context of a static method when the property is an instance property. csc.exe resolves the expression to the method group instead.

Note that prior to Mono 3.x, mcs's behaviour matched that of csc.exe. Here's a repro:

===== Test.cs =====

using System.Collections.Generic;
using System.Linq;

public class A
{
    public static A Get(int value) { return default(A); }
}

public class B
{
    public static void StaticMethod()
    {
        // Compiler should resolve A.Get to method group A.Get.
        // Instead, old versions of Mono resolve A to instance
        // property A which is not legal as we do not have a
        // instance reference at this point.
        ((IEnumerable<int>)null).Select(A.Get);
    }

    public A A // Property same name as type
    {
        get { return default(A); }
    }
}

===== End of Test.cs =====

Command lines:

# From Visual Studio 2013 command prompt
$ csc /target:library Test.cs
Microsoft (R) Visual C# Compiler version 12.0.21005.1
Copyright (C) Microsoft Corporation. All rights reserved.

# From Mono-2.10.9 command prompt
$ mcs /target:library Test.cs
[No errors]

# From Mono-3.2.3 command prompt
$ mcs /target:library Test.cs
Test.cs(17,41): error CS0120: An object reference is required to access non-static member `B.A'
Compilation failed: 1 error(s), 0 warnings

I've also tested against a compiler based on the Mono 3.0.7 code base and this emits the same errors as Mono 3.2.3. It looks like a regression was introduced between the 2.x and 3.x series of compilers.

Note that I only see these errors when consuming the System.Enumerable.Linq.Select extension method. I have tried defining a method with similar signature and compiling against this instead:

public static class MyExtension
{
    public delegate TResult MyFunc<TSource, TResult>(TSource source);

    public static void MySelect<TSource, TResult>(this IEnumerable<TSource> items, MyFunc<TSource, TResult> func) { }
}

This compiles without errors on csc and mcs 2.10.9 and 3.2.3. I also tried moving the custom extension method into a separate assembly to try to determine if this is a problem to do with type import and it still compiles correctly with csc/mcs. I wonder if there's something special about the LINQ extensions and/or their metadata.

Thanks, Richard.

Richard Cook | Principal engineer
Coverity | Columbia Center Tower | 701 Fifth Avenue, Suite 1220 | Seattle, WA
98104
The Leader in Development Testing
Read our profile in Forbes, Coverity Gets Code Right 25% Faster
Comment 1 Richard Cook 2014-01-29 13:55:59 UTC
I have a simpler repro:

===== Test.cs =====

public class A
{
    public static A Get(int value) { return default(A); }
}

public class B
{
    public delegate TResult Func<TArg, TResult>(TArg arg);
    public delegate TResult Func<TArg0, TArg1, TResult>(TArg0 arg0, TArg1
arg1);

    public static void StaticMethod()
    {
        Foo<int, A>(A.Get);
    }

    public static void Foo<TSource, TResult>(Func<TSource, TResult> selector) {
}
    public static void Foo<TSource, TResult>(Func<TSource, int, TResult>
selector) { }

    public A A // Property same name as type
    {
        get { return default(A); }
    }
}

===== End of Test.cs =====

It turns out that System.Enumerable.Linq.Select is a red herring. This
reproducer does not depend on LINQ or extension methods. The critical thing is
that in addition to the ambiguity between "A as a type" and "A as a property",
the additional ambiguity between which overload of Foo to use is required. If I
remove the second Foo method then this reproducer will compile. Thus, it looks
like mcs is supposed to handle the "Color Color rule" but fails to do so in
the presence of method overloads.
Comment 2 Richard Cook 2014-01-30 13:53:44 UTC
It did some more digging:

Mono 2.10.8.1 generates incorrect CS0120
Mono 3.0.7 generates incorrect CS0120
Mono 3.2.4 (master) behaves correctly

It looks like this issue was fixed some time between 3.0.7 and 3.2.4.
Comment 3 Richard Cook 2014-01-31 19:08:04 UTC
This looks like it's a duplicate of bug 14384.
Comment 4 Richard Cook 2014-02-12 15:25:04 UTC
I have verified that it's fixed.