Repository: dotnet/roslyn
File: src/Compilers/CSharp/Test/Emit3/Semantics/PatternMatchingTests_ListPatterns.cs (C#)

Code before:
            // (13,18): warning CS8509: The switch expression does not handle all possible values of its input type (it is not exhaustive). For example, the pattern '_' is not covered.
            //         return c switch
            Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustive, "switch").WithArguments("_").WithLocation(13, 18)
            );
    }

    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70046")]
    public void PointerType_ListPattern()
    {
        var source = """
            unsafe class C
            {
                void M()
                {
                    void* v = null;
                    if (v is [])
                    {
                    }
                }
            }
            """;
        var compilation = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll);
        compilation.VerifyDiagnostics(
            // (6,18): error CS8521: Pattern-matching is not permitted for pointer types.
            //         if (v is [])
            Diagnostic(ErrorCode.ERR_PointerTypeInPatternMatching, "[]").WithLocation(6, 18));
    }

    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70046")]
    public void FunctionPointerType_ListPattern()
    {
        var source = """
            unsafe class C
            {
                void M()
                {
                    delegate*<void> f = null;
                    if (f is [])
                    {
                    }
                }
            }
            """;
        var compilation = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll);
        compilation.VerifyDiagnostics(
            // (6,18): error CS8521: Pattern-matching is not permitted for pointer types.
            //         if (f is [])
            Diagnostic(ErrorCode.ERR_PointerTypeInPatternMatching, "[]").WithLocation(6, 18));
    }
}


Review comment (bug):
It doesn't look like we test the path that would actually crash. Should we construct an IOperation tree?

Code after:
            // (13,18): warning CS8509: The switch expression does not handle all possible values of its input type (it is not exhaustive). For example, the pattern '_' is not covered.
            //         return c switch
            Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustive, "switch").WithArguments("_").WithLocation(13, 18)
            );
    }

    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70046")]
    public void PointerType_ListPattern_NoIndex()
    {
        var source = """
            unsafe class C
            {
                void M()
                {
                    void* v = null;
                    if (v is [])
                    {
                    }
                }
            }
            """;
        var compilation = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll);
        compilation.VerifyDiagnostics(
            // (6,18): error CS8985: List patterns may not be used for a value of type 'void*'. No suitable 'Length' or 'Count' property was found.
            //         if (v is [])
            Diagnostic(ErrorCode.ERR_ListPatternRequiresLength, "[]").WithArguments("void*").WithLocation(6, 18),
            // (6,18): error CS0518: Predefined type 'System.Index' is not defined or imported
            //         if (v is [])
            Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "[]").WithArguments("System.Index").WithLocation(6, 18),
            // (6,18): error CS0242: The operation in question is undefined on void pointers
            //         if (v is [])
            Diagnostic(ErrorCode.ERR_VoidError, "[]").WithLocation(6, 18));

        var semanticModel = compilation.GetSemanticModel(compilation.SyntaxTrees.Single());
        var pattern = compilation.SyntaxTrees.Single().GetRoot().DescendantNodes().OfType<IsPatternExpressionSyntax>().Single();
        compilation.VerifyOperationTree(pattern, """
            IIsPatternOperation (OperationKind.IsPattern, Type: System.Boolean, IsInvalid) (Syntax: 'v is []')
                Value:
                  ILocalReferenceOperation: v (OperationKind.LocalReference, Type: System.Void*) (Syntax: 'v')
                Pattern:
                  IListPatternOperation (OperationKind.ListPattern, Type: null, IsInvalid) (Syntax: '[]') (InputType: System.Void*, NarrowedType: System.Void*, DeclaredSymbol: null, LengthSymbol: null, IndexerSymbol: null)
                    Patterns (0)
            """);
    }

    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70046")]
    public void PointerType_ListPattern_WithIndex()
    {
        var source = """
            unsafe class C
            {