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

UnreachableAfterAttribute and unreachable code detecting #59

Closed
knat opened this issue Jan 23, 2015 · 10 comments
Closed

UnreachableAfterAttribute and unreachable code detecting #59

knat opened this issue Jan 23, 2015 · 10 comments
Labels

Comments

@knat
Copy link

knat commented Jan 23, 2015

The normal code:

void M()
{
    throw new Exception();
    Console.WriteLine();//warning CS0162: Unreachable code detected
}
int M2()
{
    if (...) return 42;
    throw new Exception();
}

But if a method definitely throws exceptions:

void Throw() 
{
    throw new Exception();
}
void M()
{
    Throw();
    Console.WriteLine();//no CS0162 warning
}
int M2()
{
    if (...) return 42;
    Throw();
}//error CS0161: not all code paths return a value

I suggest adding an UnreachableAfterAttribute, and the compiler is aware of it:

[UnreachableAfter]
void Throw() 
{
    throw new Exception();
}
void M()
{
    Throw();
    Console.WriteLine();//warning CS0162: Unreachable code detected
}
int M2()
{
    if (...) return 42;
    Throw();
}//OK
@weltkante
Copy link
Contributor

This would be also useful for the inverse case, where you have a method returning a result but your last statement is a call to a method which does a guaranteed throw. Currently the compiler will complain that the outer method does not return a result.

Note that the compiler really should check that all paths of the annotated method actually throw and none of them returns. If the compiler just believes you when you tag on that attribute and doesn't check it, it would introduce a new kind of bug at runtime.

The name of the attribute "unreachable after" sounds a bit off, in other languages it's usually something like "does not return" or "no return".

@theoy theoy added this to the Unknown milestone Jan 23, 2015
@svick
Copy link
Contributor

svick commented Jan 23, 2015

Should this be just a hint to the compiler (so that it can produce better warnings, like @knat suggested), or should it be actual language feature (which would change what code is allowed, per @gavaldor)?

@theoy
Copy link
Contributor

theoy commented Jan 23, 2015

Good question @svick :) , compiler and language are often used interchangeably, and I've gotten used to most people being ambiguous as to which one do they really mean :)

That said - I do think that reachability is part of the language, especially as it affects definite assignment. This is an interesting request because it allows for user code to participate in the definition of reachability... which is an interesting design bridge to cross. At the moment we benefit from the definition being wholly defined within the language, and thus can provide a more reliable analysis.

I have used the corresponding C++ constructs when I've had to write native code though, and appreciated its existence. I'd be curious how we land after more discussion reflection.

@theoy
Copy link
Contributor

theoy commented Jan 28, 2015

Also filed by @stephentoub as issue #127

@gafter
Copy link
Member

gafter commented Feb 3, 2015

This is more valuable as a type rather than an attribute. See Scala's Nothing type. Now proposed as #1226.

@stephentoub
Copy link
Member

@gafter, can you elaborate? How would you see that playing in C#/.NET?

@gafter
Copy link
Member

gafter commented Feb 3, 2015

The compiler would treat a value of the type specially for definite assignment purposes - whenever a value of this type appears on the stack, everything is definitely assigned and the code is unreachable. The code generator would throw an exception at any point where the type appears on the stack to cover the loopholes that the compiler cannot catch. I implemented this for java in the closures project and it was straightforward.

@stephentoub
Copy link
Member

Changing the return type of a method is a binary breaking change, so we wouldn't be able to use a return-type-based approach on existing framework methods that might otherwise benefit, e.g. ExceptionDispatchInfo.Throw, Environment.FailFast, etc. Not a deal breaker, but definitely something to factor in.

@gafter
Copy link
Member

gafter commented Feb 3, 2015

Yes, one would not use this for existing methods. Rather one would introduce new methods.

@MadsTorgersen
Copy link
Contributor

Let's track this overall topic with #1226.

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

No branches or pull requests

8 participants