Description
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 thereveal_type
is 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.
Activity