We can statically determine that code is unreachable, due to terminal statements or statically known branches:
def f():
x = 1
return
reveal_type(x) # ???
def g():
x = 1
if True:
return
reveal_type(x) # ???
We should consider how we want to handle this. I think the uncontroversial part is that we should produce a (possibly optional?) diagnostic about the code being unreachable. But after that, there are several options:
-
We could mark all bindings as not visible once we reach a terminal statement. That would produce an unresolved-reference errors. This seems least helpful, since it seems likely that the user either (a) didn't intend for the code to become unreachable or (b) is inserting e.g. early returns as part of a debugging process. In both cases the user expects the supposedly unreachable code to be well-typed, and would want diagnostics about ways that it's not.
-
We could consider the bindings visible, but update their inferred type to be Never to signify that those symbols wouldn't have any values in the unreachable code. This is arguably the most accurate interpretation, but doesn't provide much value over the "this code is unreachable" diagnostic.
-
We could type-check the unreachable code as if it were reachable. Note that this would only apply to truly unreachable code, but not in something like:
def h(cond: bool):
x = 1
if cond:
return
reveal_type(x) # revealed: Literal[1]
Here, the return statement isn't always executed, and so the reveal_type is not unreachable, and the obviously correct result is Literal[1].
We should also look into what mypy and pyright do here, to see if there's an obvious community consensus we should follow.
We can statically determine that code is unreachable, due to terminal statements or statically known branches:
We should consider how we want to handle this. I think the uncontroversial part is that we should produce a (possibly optional?) diagnostic about the code being unreachable. But after that, there are several options:
We could mark all bindings as not visible once we reach a terminal statement. That would produce an
unresolved-referenceerrors. This seems least helpful, since it seems likely that the user either (a) didn't intend for the code to become unreachable or (b) is inserting e.g. early returns as part of a debugging process. In both cases the user expects the supposedly unreachable code to be well-typed, and would want diagnostics about ways that it's not.We could consider the bindings visible, but update their inferred type to be
Neverto signify that those symbols wouldn't have any values in the unreachable code. This is arguably the most accurate interpretation, but doesn't provide much value over the "this code is unreachable" diagnostic.We could type-check the unreachable code as if it were reachable. Note that this would only apply to truly unreachable code, but not in something like:
Here, the
returnstatement isn't always executed, and so thereveal_typeis not unreachable, and the obviously correct result isLiteral[1].We should also look into what mypy and pyright do here, to see if there's an obvious community consensus we should follow.