Description
Whenever an expression:
- Has a static type of
Never
, - Is associated by flow analysis with an
ExpressionInfo
object*, - And is used in a conditional context**,
flow anaylsis forgets the fact that the code is unreachable is forgotten when analyzing the "true" and "false" branches of the conditional.
*Expressions are associated with an ExpressionInfo
object whenever they might require special treatment by flow analysis. This includes reads of local variables (and parameters), property gets, boolean literals, null literals, conditional expressions, the expression this
, and any of the expressions produced by ||
, &&
, is
, is!
, ==
, !=
, and prefix !
.
**A "conditional context" means the condition of an assert
, do
, for
, if
, or while
, or a conditional expression, or an operand of ||
, &&
, or prefix !
.
For example, in this code:
void f(Never n) {
final _ = n ? 1 : 2;
print('Unreachable!');
}
The above conditions are met for the read of the variable n
, so flow analysis erroneously considers both 1
and 2
to be reachable expressions, and hence it considers the remainder of the function f
to be reachable too. Therefore, the analyzer fails to emit an "unreachable code" warning.
Whereas in this code:
void g(Never n) {
final _ = (throw 0) ? 1 : 2; // Warning on `1` and on `2`.
print('Unreachable!'); // Warning.
}
The above conditions are not met, because (throw 0)
is not associated by flow analysis with an ExpressionInfo
object. So she analyzer correctly reports "unreachable code" warnings.
See dart-lang/language#4287 (comment) for more context.
I'll try to work on a fix for this in the next week or two.