Skip to content

Commit 363da90

Browse files
stereotype441commit-bot@chromium.org
authored andcommitted
Fix "why not promoted" functionality for compound indexed assignment.
Bug: #44898 Change-Id: I40c6087a0db2c67106f9ce138b79a8a5769b37de Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193834 Commit-Queue: Paul Berry <[email protected]> Reviewed-by: Johnni Winther <[email protected]>
1 parent b13dea3 commit 363da90

File tree

5 files changed

+140
-119
lines changed

5 files changed

+140
-119
lines changed

pkg/_fe_analyzer_shared/test/flow_analysis/why_not_promoted/data/argument_type_not_assignable_nullability_error.dart

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -429,51 +429,47 @@ class C29 {
429429
}
430430

431431
indexSetCompound(C29 c, List<int> values) {
432-
// TODO(paulberry): get this to work with the CFE
433432
if (c.bad == null) return;
434433
values[
435434
/*analyzer.notPromoted(propertyNotPromoted(target: member:C29.bad, type: int?))*/ c
436-
.bad] += 1;
435+
. /*cfe.notPromoted(propertyNotPromoted(target: member:C29.bad, type: int?))*/ bad] += 1;
437436
}
438437

439438
class C30 {
440439
int? bad;
441440
}
442441

443442
indexSetIfNull(C30 c, List<int?> values) {
444-
// TODO(paulberry): get this to work with the CFE
445443
if (c.bad == null) return;
446444
values[
447445
/*analyzer.notPromoted(propertyNotPromoted(target: member:C30.bad, type: int?))*/ c
448-
.bad] ??= 1;
446+
. /*cfe.notPromoted(propertyNotPromoted(target: member:C30.bad, type: int?))*/ bad] ??= 1;
449447
}
450448

451449
class C31 {
452450
int? bad;
453451
}
454452

455453
indexSetPreIncDec(C31 c, List<int> values) {
456-
// TODO(paulberry): get this to work with the CFE
457454
if (c.bad == null) return;
458455
++values[
459456
/*analyzer.notPromoted(propertyNotPromoted(target: member:C31.bad, type: int?))*/ c
460-
.bad];
457+
. /*cfe.notPromoted(propertyNotPromoted(target: member:C31.bad, type: int?))*/ bad];
461458
--values[
462459
/*analyzer.notPromoted(propertyNotPromoted(target: member:C31.bad, type: int?))*/ c
463-
.bad];
460+
. /*cfe.notPromoted(propertyNotPromoted(target: member:C31.bad, type: int?))*/ bad];
464461
}
465462

466463
class C32 {
467464
int? bad;
468465
}
469466

470467
indexSetPostIncDec(C32 c, List<int> values) {
471-
// TODO(paulberry): get this to work with the CFE
472468
if (c.bad == null) return;
473469
values[
474470
/*analyzer.notPromoted(propertyNotPromoted(target: member:C32.bad, type: int?))*/ c
475-
.bad]++;
471+
. /*cfe.notPromoted(propertyNotPromoted(target: member:C32.bad, type: int?))*/ bad]++;
476472
values[
477473
/*analyzer.notPromoted(propertyNotPromoted(target: member:C32.bad, type: int?))*/ c
478-
.bad]--;
474+
. /*cfe.notPromoted(propertyNotPromoted(target: member:C32.bad, type: int?))*/ bad]--;
479475
}

pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
// @dart = 2.9
66

7+
import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
78
import 'package:_fe_analyzer_shared/src/util/link.dart';
89
import 'package:front_end/src/api_prototype/lowering_predicates.dart';
910
import 'package:kernel/ast.dart';
@@ -3372,6 +3373,8 @@ class InferenceVisitor
33723373

33733374
VariableDeclaration indexVariable;
33743375
Expression readIndex = indexResult.expression;
3376+
Map<DartType, NonPromotionReason> Function() whyNotPromotedIndex =
3377+
inferrer.flowAnalysis?.whyNotPromoted(readIndex);
33753378
Expression writeIndex;
33763379
if (isPureExpression(readIndex)) {
33773380
writeIndex = clonePureExpression(readIndex);
@@ -3382,7 +3385,8 @@ class InferenceVisitor
33823385
}
33833386

33843387
readIndex = inferrer.ensureAssignable(
3385-
readIndexType, indexResult.inferredType, readIndex);
3388+
readIndexType, indexResult.inferredType, readIndex,
3389+
whyNotPromoted: whyNotPromotedIndex);
33863390

33873391
ExpressionInferenceResult readResult = _computeIndexGet(
33883392
node.readOffset,
@@ -3403,7 +3407,8 @@ class InferenceVisitor
34033407
.member;
34043408

34053409
writeIndex = inferrer.ensureAssignable(
3406-
writeIndexType, indexResult.inferredType, writeIndex);
3410+
writeIndexType, indexResult.inferredType, writeIndex,
3411+
whyNotPromoted: whyNotPromotedIndex);
34073412

34083413
ExpressionInferenceResult valueResult = inferrer
34093414
.inferExpression(node.value, valueType, true, isVoidAllowed: true);
@@ -5055,6 +5060,8 @@ class InferenceVisitor
50555060

50565061
VariableDeclaration indexVariable;
50575062
Expression readIndex = indexResult.expression;
5063+
Map<DartType, NonPromotionReason> Function() whyNotPromotedIndex =
5064+
inferrer.flowAnalysis?.whyNotPromoted(readIndex);
50585065
Expression writeIndex;
50595066
if (isPureExpression(readIndex)) {
50605067
writeIndex = clonePureExpression(readIndex);
@@ -5065,7 +5072,8 @@ class InferenceVisitor
50655072
}
50665073

50675074
readIndex = inferrer.ensureAssignable(
5068-
readIndexType, indexResult.inferredType, readIndex);
5075+
readIndexType, indexResult.inferredType, readIndex,
5076+
whyNotPromoted: whyNotPromotedIndex);
50695077

50705078
ExpressionInferenceResult readResult = _computeIndexGet(
50715079
node.readOffset,
@@ -5110,7 +5118,8 @@ class InferenceVisitor
51105118
DartType binaryType = binaryResult.inferredType;
51115119

51125120
writeIndex = inferrer.ensureAssignable(
5113-
writeIndexType, indexResult.inferredType, writeIndex);
5121+
writeIndexType, indexResult.inferredType, writeIndex,
5122+
whyNotPromoted: whyNotPromotedIndex);
51145123

51155124
binary = inferrer.ensureAssignable(valueType, binaryType, binary,
51165125
fileOffset: node.fileOffset);

pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,17 @@ class TypeInferrerImpl implements TypeInferrer {
316316
if (args.isNotEmpty) {
317317
nonPromotionReasonText += '(${args.join(', ')})';
318318
}
319-
dataForTesting.flowAnalysisResult.nonPromotionReasons[node] =
319+
TreeNode origNode = node;
320+
while (origNode is VariableGet &&
321+
origNode.variable.name == null &&
322+
origNode.variable.initializer != null) {
323+
// This is a read of a synthetic variable, presumably from a "let".
324+
// Find the original expression.
325+
// TODO(johnniwinther): add a general solution for getting the
326+
// original node for testing.
327+
origNode = (origNode as VariableGet).variable.initializer;
328+
}
329+
dataForTesting.flowAnalysisResult.nonPromotionReasons[origNode] =
320330
nonPromotionReasonText;
321331
}
322332
// Note: this will always pick the first viable reason (only). I
@@ -478,7 +488,8 @@ class TypeInferrerImpl implements TypeInferrer {
478488
Template<Message Function(DartType, DartType, bool)>
479489
nullabilityNullTypeErrorTemplate,
480490
Template<Message Function(DartType, DartType, DartType, DartType, bool)>
481-
nullabilityPartErrorTemplate}) {
491+
nullabilityPartErrorTemplate,
492+
Map<DartType, NonPromotionReason> Function() whyNotPromoted}) {
482493
assert(contextType != null);
483494

484495
// [errorTemplate], [nullabilityErrorTemplate], and
@@ -607,14 +618,15 @@ class TypeInferrerImpl implements TypeInferrer {
607618
declaredContextType ?? contextType,
608619
isNonNullableByDefault));
609620
} else {
621+
whyNotPromoted ??= flowAnalysis?.whyNotPromoted(expression);
610622
result = _wrapUnassignableExpression(
611623
expression,
612624
expressionType,
613625
contextType,
614626
nullabilityErrorTemplate.withArguments(expressionType,
615627
declaredContextType ?? contextType, isNonNullableByDefault),
616628
context: getWhyNotPromotedContext(
617-
flowAnalysis?.whyNotPromoted(expression)(),
629+
whyNotPromoted?.call(),
618630
expression,
619631
(type) => typeSchemaEnvironment.isSubtypeOf(type,
620632
contextType, SubtypeCheckMode.withNullabilities)));

pkg/front_end/test/spell_checking_list_code.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,7 @@ ordered
809809
orders
810810
ordinal
811811
org
812+
orig
812813
orphancy
813814
orphans
814815
ors
@@ -884,6 +885,7 @@ preexisting
884885
preorder
885886
presented
886887
presubmit
888+
presumably
887889
prev
888890
prime
889891
printer

0 commit comments

Comments
 (0)