Bug 17469 - Mono C# compiler erroneously emits CS0030 compiler errors for implicit or explicit user-defined conversion followed by standard explicit conversion
Summary: Mono C# compiler erroneously emits CS0030 compiler errors for implicit or exp...
Status: VERIFIED FIXED
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 11:49 UTC by Richard Cook
Modified: 2014-02-25 13:18 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 FIXED

Description Richard Cook 2014-01-28 11:49:08 UTC
The Mono C# compiler (mcs) does not compile chained user-defined conversions and instead emits compiler error CS0030. Both the 2.x and 3.x series of Mono compilers exhibit this behaviour. Here's a repro for this issue:

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

public class A<T>
{
    public static explicit operator T(A<T> source)
    {
        throw new System.NotImplementedException();
    }
}

public class Test
{
    public void M()
    {
        A<System.DateTime?> source = null;
        N((System.DateTime)source);
    }

    public void N(System.DateTime dateTime) { }
}

===== 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
Test.cs(14,11): error CS0030: Cannot convert type `System.DateTime?' to `System.DateTime'
Test.cs(14,11): error CS0030: Cannot convert type `A<System.DateTime?>' to `System.DateTime'
Test.cs(14,9): error CS1502: The best overloaded method match for `Test.N(System.DateTime)' has some invalid arguments
Test.cs(17,17): (Location of the symbol related to previous error)
Test.cs(14,9): error CS1503: Argument `#1' cannot convert `object' expression to type `System.DateTime'
Compilation failed: 4 error(s), 0 warnings

# From Mono-3.2.3 command prompt
$ mcs /target:library Test.cs
Test.cs(14,11): error CS0030: Cannot convert type `System.DateTime?' to `System.DateTime'
Test.cs(14,28): error CS0030: Cannot convert type `A<System.DateTime?>' to `System.DateTime'
Compilation failed: 2 error(s), 0 warnings

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-28 12:50:28 UTC
Note that the implicitness or explicitness of the conversion does not matter. I have another code sample which illustrates another related issue which might be of interest:

===== Test2.cs =====

namespace ImplicitConversion
{
    public class A<T>
    {
        public static implicit operator T(A<T> source)
        {
            throw new System.NotImplementedException();
        }
    }

    public class Test
    {
        public void M()
        {
            A<int?> source = null;
            if (source == 0)
            {
            }
        }
    }
}

namespace ExplicitConversion
{
    public class A<T>
    {
        public static explicit operator T(A<T> source)
        {
            throw new System.NotImplementedException();
        }
    }

    public class Test
    {
        public void M()
        {
            A<int?> source = null;
            if ((int)source == 0)
            {
            }
        }
    }
}

===== End of Test2.cs ====

This compiles with csc.exe. It fails under Mono 2.10.9 and 3.2.3 in slightly different ways:

# From Mono 2.10.9 command prompt
$ mcs /target:library Test2.cs
Test2.cs(18,24): error CS0019: Operator `==' cannot be applied to operands of
type `ImplicitConversion.A<int?>' and `int'

Test2.cs(40,17): error CS0030: Cannot convert type `int?' to `int'
Test2.cs(40,17): error CS0030: Cannot convert type `ExplicitConversion.A<int?>'
to `int'
Compilation failed: 3 error(s), 0 warnings

Under Mono 3.2.3, only the CS0030 errors are emitted:

# From Mono 3.2.3 command prompt
$ mcs /target:library Test2.cs
Test2.cs(40,17): error CS0030: Cannot convert type `int?' to `int'
Test2.cs(40,22): error CS0030: Cannot convert type `ExplicitConversion.A<int?>'
to `int'
Compilation failed: 2 error(s), 0 warnings

The CS0030 errors are the same as the bug illustrated by my first repro. The CS0019 bug, however, looks like it has been fixed between 2.x and 3.x. In fact, I have tested against a Mono 3.0.7-based compiler and this exhibits the CS0019 bug indicating that this issue was fixed some time between 3.0.7 and 3.2.3.
Comment 2 Richard Cook 2014-01-28 16:26:29 UTC
I have corrected the title since this is _not_ chaining of two user-defined conversions: A<DateTime?> -> DateTime? is a user-defined conversion while DateTime? -> DateTime is a standard implicit conversion. Since the latter is a standard implicit conversion, the user-defined conversion can be implicit or explicit.
Comment 3 Richard Cook 2014-01-28 16:31:43 UTC
Sorry. It's a standard _explicit_ conversion since the DateTime?-to-DateTime involves a cast.
Comment 4 Marek Safar 2014-01-31 08:05:48 UTC
Fixed in master
Comment 5 Richard Cook 2014-02-07 17:49:11 UTC
Thanks, Marek. I have verified the fixes.