Skip to content

Commit b85c499

Browse files
kallentuCommit Queue
authored and
Commit Queue
committed
[flow] Part 1 Issue 3658 - Store variable information after a write.
Assignments in the condition of an if statements don't store the promoted information (for the write of that variable). This fix stores the promotion of that expression for when we use it to null check or otherwise. Part 1 because there's still some holes with postfix operators and null asserts that need to be fixed, but this behaviour stands on its own at the moment. Everything is behind the flag so we'll iterate. Bug: dart-lang/language#3658 Change-Id: I8663f089a451468651efccadeb3991b34a37d899 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/388903 Reviewed-by: Paul Berry <[email protected]> Commit-Queue: Kallen Tu <[email protected]>
1 parent 627b5e8 commit b85c499

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart

+10
Original file line numberDiff line numberDiff line change
@@ -6268,6 +6268,16 @@ class _FlowAnalysisImpl<Node extends Object, Statement extends Node,
62686268
newSsaNode,
62696269
operations,
62706270
unpromotedType: unpromotedType);
6271+
6272+
// Update the type of the variable for looking up the write expression.
6273+
if (inferenceUpdate4Enabled && node is Expression) {
6274+
_Reference<Type> reference = _variableReference(
6275+
variableKey,
6276+
unpromotedType,
6277+
);
6278+
_storeExpressionInfo(node, reference);
6279+
_storeExpressionReference(node, reference);
6280+
}
62716281
}
62726282
}
62736283

pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart

+64
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,37 @@ main() {
293293
]);
294294
});
295295

296+
test('equalityOp(x == null) when x is an assignment expression', () {
297+
// int? x;
298+
// if ((x = <int?>) == null) {
299+
// return;
300+
// }
301+
// x is promoted to `int`.
302+
303+
var x = Var('x');
304+
h.run([
305+
declare(x, type: 'int?'),
306+
if_(x.write(expr('int?')).eq(nullLiteral), [
307+
return_(),
308+
]),
309+
checkPromoted(x, 'int'),
310+
]);
311+
});
312+
313+
test(
314+
'equalityOp(x == null) when x is an assignment expression'
315+
'and inference-update-4 is disabled', () {
316+
var x = Var('x');
317+
h.disableInferenceUpdate4();
318+
h.run([
319+
declare(x, type: 'int?'),
320+
if_(x.write(expr('int?')).eq(nullLiteral), [
321+
return_(),
322+
]),
323+
checkNotPromoted(x),
324+
]);
325+
});
326+
296327
test('equalityOp(x == null) when x is non-nullable', () {
297328
var x = Var('x');
298329
h.run([
@@ -1634,6 +1665,39 @@ main() {
16341665
]);
16351666
});
16361667

1668+
test(
1669+
'isExpression_end() variables in assignment expressions are promoted',
1670+
() {
1671+
// num x;
1672+
// if ((x = <int>) is int) {
1673+
// x is promoted to `int`.
1674+
// }
1675+
// x is not promoted
1676+
1677+
var x = Var('x');
1678+
h.run([
1679+
declare(x, type: 'num'),
1680+
if_(x.write(expr('int')).is_('int'), [
1681+
checkPromoted(x, 'int'),
1682+
]),
1683+
checkNotPromoted(x),
1684+
]);
1685+
});
1686+
1687+
test(
1688+
'isExpression_end() variables in assignment expressions are not'
1689+
' promoted when inference-update-4 is disabled', () {
1690+
var x = Var('x');
1691+
h.disableInferenceUpdate4();
1692+
h.run([
1693+
declare(x, type: 'num'),
1694+
if_(x.write(expr('int')).is_('int'), [
1695+
checkNotPromoted(x),
1696+
]),
1697+
checkNotPromoted(x),
1698+
]);
1699+
});
1700+
16371701
test('on an arbitrary expression', () {
16381702
h.addMember('C', 'f', 'Object?');
16391703
h.run([

0 commit comments

Comments
 (0)