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

Infallible var pattern causes "not all code paths return a value" #76059

Open
NinoFloris opened this issue Nov 23, 2024 · 1 comment
Open

Infallible var pattern causes "not all code paths return a value" #76059

NinoFloris opened this issue Nov 23, 2024 · 1 comment
Labels
Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead

Comments

@NinoFloris
Copy link

NinoFloris commented Nov 23, 2024

Version Used: '4.12.0-3.24523.4 (f3348c2)'. Language version: latest (13.0).

Steps to Reproduce:

int _value;
int Value() => _value;
string? EnsureValid(int value) => value switch 
{ 
    42 => throw new System.Exception("Fatal"),
    > 42 => "additional data"
    _ => null 
}
int NextValue() => _value++;

int Pseudo()
{
    var current = Value();
    while(EnsureValid(current) is var result) 
    { 
        if (result is "additional data")
            return current;
        current = NextValue();
    }
}

int Minimized()
{
   while(1 is var number) {}
}

int Compiles()
{
    var current = Value();
    while(true) 
    { 
        var result = EnsureValid(current);
        if (result is "additional data")
            return current;
        current = NextValue();
    } 
}

Diagnostic Id: CS0161

Expected Behavior:
I expect this to compile as a while(true) {} would.

I couldn't come up with a particular reason for this to work differently from a true loop condition, there is no function call or other opaqueness to semantically cloud the equivalence with true, and the pattern always succeeds according to the language spec.

As for the code, you could argue the call and pattern belongs in the while body, however there are cases where doing something like this actually reads quite naturally. Certain coding patterns may rely on breaking out of the loop through another channel (exceptions in this case) and look fairly natural as part of the loop condition.

Actual Behavior:

    error CS0161: 'Pseudo()': not all code paths return a value
    error CS0161: 'Minimized()': not all code paths return a value
@dotnet-issue-labeler dotnet-issue-labeler bot added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels Nov 23, 2024
@CyrusNajmabadi
Copy link
Member

I didn't believe the language ever thinks of patterns as constant values. But it's reasonable to say that it could for certain cases. I think that would be needed here so that it would know which points of the method are reachable or not.

So for this to happen, I think it would be necessary to change the language, which would happen at dotnet/csharplang.

If you started a discussion there, and tagged me, I'd be willing to bring this idea to the ldm to see what the team thinks about this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead
Projects
None yet
Development

No branches or pull requests

2 participants