Skip to content

Commit 79c3917

Browse files
stereotype441Commit Queue
authored andcommitted
[cfe] Fix type field promotion on LHS of ??.
The CFE was passing the original LHS expression to `flowAnalysis.ifNullExpression_rightBegin`. This was incorrect; it needs to pass the rewritten LHS expression. Most of the time this was harmless, since in most cases: - The expression on the LHS of `??` was not promotable, in which case passing the wrong expression didn't matter, - Or the expression on the of `??` was a read of a local variable, in which case there was no problem, since local variable reads don't require rewriting. However, in cases where the LHS of `??` is a read of a promotable property, it does matter, since property reads are often rewritten during inference. Fixes #56874. Bug: #56874 Change-Id: Ie42b96b0bc14faec38e8dbcb9e11534d4a1db0dc Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/389140 Commit-Queue: Paul Berry <[email protected]> Reviewed-by: Johnni Winther <[email protected]> Reviewed-by: Chloe Stefantsova <[email protected]>
1 parent 70cab20 commit 79c3917

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

pkg/front_end/lib/src/type_inference/inference_visitor.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2029,7 +2029,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
20292029
// This ends any shorting in `node.left`.
20302030
Expression left = lhsResult.expression;
20312031

2032-
flowAnalysis.ifNullExpression_rightBegin(node.left, new SharedTypeView(t1));
2032+
flowAnalysis.ifNullExpression_rightBegin(left, new SharedTypeView(t1));
20332033

20342034
// - Let `T2` be the type of `e2` inferred with context type `J`, where:
20352035
// - If `K` is `_` or `dynamic`, `J = T1`.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// Tests that a promotable field access appearing on the LHS of `??` is properly
6+
// promoted in a code path where it is known to be non-null.
7+
8+
import 'package:expect/expect.dart';
9+
import '../static_type_helper.dart';
10+
11+
class A {
12+
final int? _f1;
13+
14+
A(this._f1);
15+
}
16+
17+
test(A a) {
18+
a._f1.expectStaticType<Exactly<int?>>();
19+
a._f1 ?? [a._f1.expectStaticType<Exactly<int?>>(), throw ''];
20+
a._f1.expectStaticType<Exactly<int>>();
21+
}
22+
23+
main() {
24+
test(A(0));
25+
Expect.throws(() => test(A(null)));
26+
}

0 commit comments

Comments
 (0)