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
Flow analysis: implement type promotions for or-patterns.
There are three ways type promotion can occur in an or-pattern:
(1) the scrutinee variable (if any) might be promoted, e.g.:
f(Object x) {
if (x case int _ && < 0 || int _ && > 10) {
// `x` is promoted to `int` because both sides of the `||`
// promote the scrutinee variable to `int`.
}
}
(2) the implicit temporary variable that holds the matched value might
be promoted, e.g.:
f(Object Function() g) {
if (g() case (int _ && < 0 || int _ && > 10) && (var x)) {
// `x` has type `int` because both sides of the `||` promote
// the matched value to `int`.
}
}
For this sort of promotion to work, we need to
(3) explicitly matched variables might be promoted at the time of the
match, e.g.:
f<T>(T t) {
if (t is int) {
if (t case var x && < 0 || 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 cases (1) and (2) without any
extra work, because those promotions are joined as a natural
consequence of the flow control join at the end of matching the
logical-or pattern.
However, flow analysis has to do some extra work for case (3), 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 necessary to track the association between
the individual declared variable patterns and the joined pattern
variable (and this is bookkeeping that flow analysis is already
doing). So as part of this change I went ahead and removed the
`getJoinedVariableComponents` method (which was previously used by
flow analysis to query this association). This reduces the
constraints on the analyzer and CFE implementations by not requiring
them to do this bookkeeping themselves.
In the process I've made two additional small changes:
- I modified the logic for assigning types and finality to joined
variables so that if there is a finality conflict but no type
conflict, the common type is used; conversely, if there is a type
conflict but no finality conflict, the common finality is used.
This should help reduce follow-on errors.
- I added logic to ensure that if a variable is only declared on one
side or the other of a logical-or, flow analysis still considers
that variable to be definitely assigned. This should help reduce
follow-on errors.
Change-Id: I62f17adb6a51a583707c216ed48d941d1c621eea
Bug: #50419
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/279756
Commit-Queue: Paul Berry <[email protected]>
Reviewed-by: Johnni Winther <[email protected]>
0 commit comments