167cf8e637
There are two ways type promotion can occur when switch cases share a body:
(1) the scrutinee variable (if any) might be promoted, e.g.:
f(Object x) {
switch (x) {
case int _ && < 0:
case int _ && > 10:
// `x` is promoted to `int` because both cases promote the
// scrutinee variable to `int`.
}
}
(2) explicitly matched variables might be promoted at the time of the
match, e.g.:
f<T>(T t) {
if (t is int) {
switch (t) {
case var x && < 0:
case var x && > 10:
// `x` has type `T` but is promoted to `T&int`, because
// both declarations of `x` are in a context where the
// matched value has type `T&int`.
}
}
}
The existing flow analysis logic handles case (1) without any extra
work, because those promotions are joined as a natural consequence of
the flow control join at the end of matching the cases.
However, flow analysis has to do some extra work for case (2), because
the two copies of variable `x` are associated with different variable
declarations (and hence have different promotion keys). To ensure
that the promotions are joined in this case, we need to copy the flow
model for the two copies of `x` into a common promotion key prior to
doing the flow control join.
The bookkeeping necessary to figure out a common promotion key is
similar to the bookkeeping for logical-or patterns.
Bug: https://github.com/dart-lang/sdk/issues/50419
Change-Id: I9ee4ec5d797dae28099aafbaf34fbbeeee5cd626
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/280201
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>