You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Dead code is really tricky. Users like to have some type checking there, but it's legitimate for the type checker to ignore it entirely. Dead code checks are a best effort.
The typechecker is working here in the goal of preventing runtime errors—the dead code can't produce an error. But this is a failure in the related goal of avoiding bugs; the existence of unreachable code itself is often a bug. I found this issue because of a refactor that introduced an early return and missed some important behavior.
The text was updated successfully, but these errors were encountered:
Variables being typed as nothing in unreachable code is an appropriate application of the type refinement rules. Given a nullable int, an if ($x is null) return; would refine to int. An unconditional return is equivalent to if ($x is mixed) return;. After this refinement, only nothing remains.
Treating dead code as an error would result in a lot of undesirable behavior. Given a function fun() with a return type annotation of nullable int and the following code.
$x=fun();
if ($xisint) return$x;
// Create a default value and return it.
If I know that fun() only every returns ints and I make the return type int instead of nullable int, Hack would report errors on this code. This would discourage tightening return types, since every time you do, the typechecker makes it look like you broke everything. In fact, you didn't break anything. Your code has not changed its behavior.
I don't really know enough about type systems to discuss intelligently what should be inferred for unreachable code—nothing seems reasonable—but I do think it would make the typechecker more useful for finding bugs if it identified and emitted errors for unreachable code.
Running UnreachableCodeLinter—which is limited to much less sophisticated analysis than the typechecker—on Slack's codebase, found ~20 unreachable blocks, several of which represented logic bugs.
In your example I disagree that identifying the errors would be undesirable. It's already pretty common for changing or constraining type annotations to produce new typechecker errors. I think it would be useful to be alerted that code you thought might execute at some point will never run. Nothing is broken in the sense that the runtime will error, but not all bugs manifest as runtime errors.
Describe the bug
Errors in code after a return statement are not identified.
Standalone code, or other way to reproduce the problem
Expected behavior
Typechecker error about the undefined variable or error about unreachable code.
Actual behavior
No errors.
Environment
Additional context
This is related to #8660, where @Wilfred writes:
The typechecker is working here in the goal of preventing runtime errors—the dead code can't produce an error. But this is a failure in the related goal of avoiding bugs; the existence of unreachable code itself is often a bug. I found this issue because of a refactor that introduced an early return and missed some important behavior.
The text was updated successfully, but these errors were encountered: