Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pattern matching an enum using an enum value following by using "with expression" on a record causes a compilation error #75074

Closed
NicholasMoss opened this issue Sep 12, 2024 · 5 comments · Fixed by #75075
Assignees
Labels
Area-Compilers Bug Regression untriaged Issues and PRs which have not yet been triaged by a lead
Milestone

Comments

@NicholasMoss
Copy link

NicholasMoss commented Sep 12, 2024

Version Used:
Visual Studio 17.12.0 Preview 2.0
DotNet 9.0.100-rc.1.24452.12

Steps to Reproduce:
Create a console app with just this snippet

enum E { A, B }
record R(int E) { }

static class TestClass
{
    public static R TestMethod(E testEnum, R record) =>
        testEnum is E.A ? record with { E = 1 } : record with { E = 1 };
}

Diagnostic Id:

Build started at 11:46...
1>------ Build started: Project: ConsoleApp1, Configuration: Debug Any CPU ------
1>C:\Program Files\dotnet\sdk\9.0.100-rc.1.24452.12\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.RuntimeIdentifierInference.targets(326,5): message NETSDK1057: You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy
1>...\Program.cs(9,33,9,37): error CS1073: Unexpected token 'with'
1>...\Program.cs(9,48,9,49): error CS1002: ; expected
1>...\Program.cs(9,48,9,49): error CS1519: Invalid token ':' in class, record, struct, or interface member declaration
1>...\Program.cs(9,66,9,67): error CS1519: Invalid token '=' in class, record, struct, or interface member declaration
1>Done building project "ConsoleApp1.csproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
========== Build completed at 11:46 and took 01.248 seconds ==========

Expected Behavior:
Code would compile as it does using stable compiler

Actual Behavior:
Errors as shown above

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels Sep 12, 2024
@NicholasMoss
Copy link
Author

NicholasMoss commented Sep 12, 2024

I have also found issues when using the linq query syntax

enum E { A, B }
record R(int E) { }

static class TestClass
{
    public static IEnumerable<R> TestMethod(E testEnum, R[] records) =>
        testEnum is E.A
            ? from item in records
              select item
            : records;
}

Which produces the following errors

Build started at 14:07...
1>------ Build started: Project: ConsoleApp1, Configuration: Debug Any CPU ------
1>C:\Program Files\dotnet\sdk\9.0.100-rc.1.24452.12\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.RuntimeIdentifierInference.targets(326,5): message NETSDK1057: You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy
1>...\Program.cs(10,20,10,24): error CS1002: ; expected
1>...\Program.cs(10,25,10,27): error CS1519: Invalid token 'in' in class, record, struct, or interface member declaration
1>...\Program.cs(11,22,11,26): error CS1002: ; expected
1>...\Program.cs(12,13,12,14): error CS1519: Invalid token ':' in class, record, struct, or interface member declaration
1>...\Program.cs(12,22,12,23): error CS1519: Invalid token ';' in class, record, struct, or interface member declaration
1>Done building project "ConsoleApp1.csproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
========== Build completed at 14:07 and took 01.687 seconds ==========

@KyouyamaKazusa0805
Copy link

KyouyamaKazusa0805 commented Sep 12, 2024

See #66841 (comment)

In short, because you defined a property named E, which is conflicted with type declaration E. You should append an extra discard token _ to tell compiler that here E is a type with a discard, and not be a field (i.e. use is E _ instead).

C# compiler will make is Type to be recognized as a type, but C# also introduced a pattern type called "constant pattern", which also uses such syntax is ConstantField, which leads to a confliction.

@NicholasMoss
Copy link
Author

NicholasMoss commented Sep 12, 2024

This is only a snippet to replicate it in a standalone solution and only applies to the preview compiler. In the actual solution where I hit these issues the names do not overlap.

The E part is unrelated which you can prove by wrapping the enum parts in parenthesis (which the analyzers tell you are unnecessary)

enum E { A, B }
record R(int E) { }

static class TestClass
{
    public static IEnumerable<R> TestMethod(E testEnum, R[] records) =>
        testEnum is (E.A)
            ? from item in records
              select item
            : records;
}

This will build successfully.

Note if you create a console app with that code you will still get the error even if you the property from E to something else.

@KyouyamaKazusa0805
Copy link

KyouyamaKazusa0805 commented Sep 12, 2024

This compiles fine because you don't have a type also called A.

Please note that brackets like (E.A) will be treated as a normal pattern E.A. Therefore you can remove the bracket - it also compiles.

To make an confliction, just declare a constant and a type, and both named same within a same scope.

@DoctorKrolic
Copy link
Contributor

DoctorKrolic commented Sep 12, 2024

There is nothing to do with semantics here, this is purely a parser regression introduced in #72805. It doesn't matter what additional types or variables you declare: the expression just isn't parsed correctly and produces a syntax error

@jaredpar jaredpar added this to the 17.12 milestone Sep 20, 2024
@jaredpar jaredpar added the Bug label Sep 20, 2024
@333fred 333fred assigned 333fred and jcouv and unassigned cston Sep 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers Bug Regression untriaged Issues and PRs which have not yet been triaged by a lead
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants