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

DoesNotReturn looked like it returned #3826

Closed
sjb-sjb opened this issue Aug 27, 2020 · 3 comments
Closed

DoesNotReturn looked like it returned #3826

sjb-sjb opened this issue Aug 27, 2020 · 3 comments

Comments

@sjb-sjb
Copy link

sjb-sjb commented Aug 27, 2020

Using UWP, .NET Core 3, I declared

/// <summary>Applied to a method that will never return under any circumstance.</summary>
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public sealed class DoesNotReturnAttribute : Attribute   { }

and then a helper function

    [DoesNotReturn] public static void Rethrow(this Exception exception)
    {
        ExceptionDispatchInfo.Capture(exception).Throw();
    }

and then I used it like this (simplified version),

    public T GetService<T>( ) where T : class
    {
        try { 
            return null!;
        } catch (Exception e) {
            e.Rethrow();
        }
    }

Actual: The compiler found an error that not all code paths of GetService return a value.

Expected was that there would be no error since the [DoesNotReturn] attribute should tell the compiler that the Rethrow method does not return.

Maybe [DoesNotReturn] is somehow only used in nullability analysis and not in flow of control analysis? How can I get the compiler to detect that all code paths in GetService return a value (aside from the rather gauche tactic of adding a redundant throw statement after e.Rethrow()) ?

@CyrusNajmabadi
Copy link
Member

CyrusNajmabadi commented Aug 27, 2020

Maybe [DoesNotReturn] is somehow only used in nullability analysis and not in flow of control analysis?

That is correct.

How can I get the compiler to detect that all code paths in GetService return a value

By returning a value in all codepaths, or making sure the endpoitn of the method is not reachable. :)

--

Closing out as this is a question and the question has been answered.

@GrabYourPitchforks
Copy link
Member

Related: #538. Presumably if that feature existed then OP's Rethrow helper method would have a never return type instead of a void return type.

@sjb-sjb
Copy link
Author

sjb-sjb commented Aug 27, 2020

Saw something along the following lines suggested somewhere. Save one vertical line!

public static Exception Capture(this Exception exception)
{
    ExceptionDispatchInfo.Capture(exception).Throw();
    return null!; // Caller should write "throw exception.Capture();" to keep compiler happy. 
}

...
throw exception.Capture();
...

How's that for a logical way to do things?

If I understand correctly then just using "throw;" in a catch clause would not capture the exception stack -- documentation is not very clear on this point though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants