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

'is not' and [DoesNotReturn] #57798

Closed
Djoums opened this issue Nov 16, 2021 · 4 comments
Closed

'is not' and [DoesNotReturn] #57798

Djoums opened this issue Nov 16, 2021 · 4 comments
Labels
Area-Compilers Resolution-By Design The behavior reported in the issue matches the current design untriaged Issues and PRs which have not yet been triaged by a lead

Comments

@Djoums
Copy link

Djoums commented Nov 16, 2021

Description

Functions with the [DoesNotReturn] attribute are not handled correctly with the is not operator.

Reproduction Steps

[DoesNotReturn]
private static void InvalidOperation() => throw new InvalidOperationException();

public static void Main()
{
    object obj = new List<int>();

    if (obj is not List<int> list)
        InvalidOperation();

    Console.WriteLine(list.Count); // CS0165: Use of unassigned local variable 'list'
}

Expected behavior

list must be defined, because of the [DoesNotReturn] attribute.

Actual behavior

CS0165: Use of unassigned local variable 'list'

Regression?

Didn't test previous versions.

Known Workarounds

Surprisingly, declaring the function as nested does work.

public static void Main()
{
    object obj = new List<int>();

    if (obj is not List<int> list)
        InvalidOperation();

    Console.WriteLine(list.Count); // Works

    [DoesNotReturn]
    static void InvalidOperation() => throw new InvalidOperationException();
}

Configuration

Using .Net 6 on Windows 10, VS Code.

Other information

No response

@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@stephentoub stephentoub transferred this issue from dotnet/runtime Nov 16, 2021
@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 16, 2021
@333fred
Copy link
Member

333fred commented Nov 16, 2021

DoesNotReturn is a nullable-related attribute only. It does not have the strong guarantees needed to actually prevent your code from compiling if your method does actually return, similar to all the rest of the nullable code-analysis attributes. Because of this, definite assignment cannot take it into account. See dotnet/csharplang#538 for the language proposal that would create a stronger guarantee via a bottom type, which would enable this scenario.

@333fred 333fred closed this as completed Nov 16, 2021
@333fred 333fred added the Resolution-By Design The behavior reported in the issue matches the current design label Nov 16, 2021
@Djoums
Copy link
Author

Djoums commented Nov 16, 2021

@333fred Sorry to ping you but I have the feeling noone's ever going to read this thread now that you closed it.

You only addressed half of the issue here, why does it work for a nested function ? Is that also 'by design' ?

@333fred
Copy link
Member

333fred commented Nov 16, 2021

You only addressed half of the issue here, why does it work for a nested function ? Is that also 'by design' ?

Yes, that is also by design. That's not the attribute doing anything at all: while definite assignment cannot do whole program analysis (as we can't solve the halting problem) it can look inside local functions. You can see in this example that, even with the attribute removed, definite assignment can pay attention to the body of the local function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers Resolution-By Design The behavior reported in the issue matches the current design untriaged Issues and PRs which have not yet been triaged by a lead
Projects
None yet
Development

No branches or pull requests

2 participants