Roslyn: Pattern matching `is` operator doesn't function correctly across assemblies.

Created on 6 Apr 2016  路  5Comments  路  Source: dotnet/roslyn

Version Used:
Build of Visual Studio from the features/patterns branch as of 4th April 2016.

Steps to Reproduce:
1 Within a new solution, create a library project, TypeDeclarations, with the __DEMO_EXPERIMENTAL__ conditional compilation symbol set. Then create the following classes:

namespace TypeDeclarations
{
    public class A
    {
        public int Prop1 { get; set; }
    }

    public class B
    {
        public static bool operator is(A a) => a.Prop1 == 0;
    }

    public class C
    {
        public int Prop2 { get; set; }

        public static bool operator is(A a, out C c)
        {
            c = a.Prop1 != 0 ? new C { Prop2 = a.Prop1 } : null;
            return a.Prop1 != 0;
        }
    }

    public static class Patterns
    {
        public static int Pattern1(A a) => a is C(var c) ? c.Prop2 : 0;

        public static int Pattern2(A a) =>
            a match (
                case C(var c) : c.Prop2
                case B() : 0
            );
    }
}

2 Create another, cmdline, project, IsOperatorBugDemo, again with __DEMO_EXPERIMENTAL__ set. Create a main class, compile and run the code:

using System;
using TypeDeclarations;

namespace IsOperatorBugDemo
{
    static class Program
    {
        static void Main()
        {
            Console.WriteLine(Patterns.Pattern1(new A()));
            Console.WriteLine(Patterns.Pattern2(new A()));
            Console.WriteLine(Patterns.Pattern1(new A { Prop1 = 1 }));
            Console.WriteLine(Patterns.Pattern2(new A { Prop1 = 1 }));
            Console.ReadLine();
        }
    }
}

3 Modify Program.cs in step 2 to the following and try to compile and run once more:

using System;
using TypeDeclarations;

namespace IsOperatorBugDemo
{
    static class Program
    {
        static void Main()
        {
            Console.WriteLine(Pattern1(new A()));
            Console.WriteLine(Pattern2(new A()));
            Console.WriteLine(Pattern1(new A { Prop1 = 1 }));
            Console.WriteLine(Pattern2(new A { Prop1 = 1 }));
            Console.ReadLine();
        }
        private static int Pattern1(A a) => a is C(var c) ? c.Prop2 : 0;

        private static int Pattern2(A a) =>
            a match (
                case C(var c) : c.Prop2
                case B() : 0
            );
    }
}

Expected Behavior:
For both steps 2 and 3, the output should be:

0
0
1
1

Actual Behavior:
For step 2, the actual behaviour is as expected. For step 3, the IDE gives no "red squiggles" to indicate a problem, and the error list remains empty. The compilation fails though, with:

Program.cs(16,50,16,58): error CS8157: No 'operator is' declaration in 'C' was found with 1 out parameters
Program.cs(16,61,16,62): error CS0165: Use of unassigned local variable 'c'
Program.cs(20,22,20,30): error CS8157: No 'operator is' declaration in 'C' was found with 1 out parameters
Program.cs(21,22,21,25): error CS8157: No 'operator is' declaration in 'B' was found with 0 out parameters
Program.cs(20,35,20,40): error CS0428: Cannot convert method group 'Prop2' to non-delegate type 'int'. Did you intend to invoke the method?
Area-Compilers Bug New Language Feature - Pattern Matching Resolution-Fixed

Most helpful comment

Fixed in the features/patterns branch by #10590

All 5 comments

@gafter, "Pattern matching is operator doesn't function correctly across assemblies" issue created as requested.

Thank you!

c# return (this.ReturnsVoid || this.ReturnType.SpecialType != SpecialType.System_Boolean) && !this.IsGenericMethod && !this.IsVararg && this.ParameterCount > 0 && !this.IsParams();

in PEMethodSymbol shouldn't this != be ==?

@orthoxerox,

No idea if that's the true fix or not. However, it certainly fixes the problem for me, which therefore let's me get on with experiments around stop-gap solutions of DUs and pattern matching if the former doesn't make it in to C# 7. So many thanks for that.

Fixed in the features/patterns branch by #10590

Was this page helpful?
0 / 5 - 0 ratings