Skip to content

Commit 3337849

Browse files
committed
[cfe] Implement new static types for arithmetic operations
Closes #41559 Closes #42577 Change-Id: I22da02731c106ec354d72a649c5b6ac6091b9292 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/155324 Reviewed-by: Dmitry Stefantsov <[email protected]>
1 parent 7c7e931 commit 3337849

File tree

45 files changed

+7260
-202
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+7260
-202
lines changed

pkg/compiler/lib/src/ir/static_type.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -350,9 +350,9 @@ abstract class StaticTypeVisitor extends StaticTypeBase {
350350
ir.DartType receiverType = visitNode(node.receiver);
351351
ArgumentTypes argumentTypes = _visitArguments(node.arguments);
352352
ir.DartType returnType;
353-
if (typeEnvironment.isOverloadedArithmeticOperator(node.target)) {
353+
if (typeEnvironment.isSpecialCasedBinaryOperator(node.target)) {
354354
ir.DartType argumentType = argumentTypes.positional[0];
355-
returnType = typeEnvironment.getTypeOfOverloadedArithmetic(
355+
returnType = typeEnvironment.getTypeOfSpecialCasedBinaryOperator(
356356
receiverType, argumentType);
357357
} else {
358358
ir.Class superclass = node.target.enclosingClass;
@@ -386,7 +386,7 @@ abstract class StaticTypeVisitor extends StaticTypeBase {
386386
/// target as to avoid visiting the argument twice.
387387
bool isSpecialCasedBinaryOperator(ir.Member interfaceTarget) {
388388
return interfaceTarget is ir.Procedure &&
389-
typeEnvironment.isOverloadedArithmeticOperator(interfaceTarget);
389+
typeEnvironment.isSpecialCasedBinaryOperator(interfaceTarget);
390390
}
391391

392392
ir.Member _getMember(ir.Class cls, String name) {
@@ -639,7 +639,7 @@ abstract class StaticTypeVisitor extends StaticTypeBase {
639639
node, argumentTypes, getterType, interfaceTarget);
640640
if (isSpecialCasedBinaryOperator(interfaceTarget)) {
641641
ir.DartType argumentType = argumentTypes.positional[0];
642-
return typeEnvironment.getTypeOfOverloadedArithmetic(
642+
return typeEnvironment.getTypeOfSpecialCasedBinaryOperator(
643643
receiverType, argumentType);
644644
} else if (getterType is ir.FunctionType) {
645645
return getterType.returnType;

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

Lines changed: 107 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -600,18 +600,24 @@ class InferenceVisitor
600600
..fileOffset = node.readOffset;
601601
}
602602

603-
ExpressionInferenceResult binaryResult = _computeBinaryExpression(
604-
node.binaryOffset, read, readType, node.binaryName, node.rhs);
605-
Expression binary = binaryResult.expression;
606-
DartType binaryType = binaryResult.inferredType;
607-
608603
ObjectAccessTarget writeTarget = node.setter == null
609604
? const ObjectAccessTarget.missing()
610605
: new ExtensionAccessTarget(
611606
node.setter, null, ProcedureKind.Setter, extensionTypeArguments);
612607

613608
DartType valueType = inferrer.getSetterType(writeTarget, receiverType);
614609

610+
ExpressionInferenceResult binaryResult = _computeBinaryExpression(
611+
node.binaryOffset,
612+
valueType,
613+
read,
614+
readType,
615+
node.binaryName,
616+
node.rhs);
617+
618+
Expression binary = binaryResult.expression;
619+
DartType binaryType = binaryResult.inferredType;
620+
615621
Expression value = inferrer.ensureAssignable(valueType, binaryType, binary,
616622
isVoidAllowed: true);
617623

@@ -2612,14 +2618,20 @@ class InferenceVisitor
26122618
Expression read = readResult.expression;
26132619
DartType readType = readResult.inferredType;
26142620

2615-
ExpressionInferenceResult binaryResult = _computeBinaryExpression(
2616-
node.binaryOffset, read, readType, node.binaryName, node.rhs);
2617-
DartType binaryType = binaryResult.inferredType;
2618-
26192621
ObjectAccessTarget writeTarget = inferrer.findInterfaceMember(
26202622
receiverType, node.propertyName, node.writeOffset,
26212623
setter: true, instrumented: true, includeExtensionMethods: true);
26222624
DartType writeType = inferrer.getSetterType(writeTarget, receiverType);
2625+
2626+
ExpressionInferenceResult binaryResult = _computeBinaryExpression(
2627+
node.binaryOffset,
2628+
writeType,
2629+
read,
2630+
readType,
2631+
node.binaryName,
2632+
node.rhs);
2633+
DartType binaryType = binaryResult.inferredType;
2634+
26232635
Expression binary =
26242636
inferrer.ensureAssignableResult(writeType, binaryResult);
26252637

@@ -3550,8 +3562,13 @@ class InferenceVisitor
35503562
/// [fileOffset] is used as the file offset for created nodes. [leftType] is
35513563
/// the already inferred type of the [left] expression. The inferred type of
35523564
/// [right] is computed by this method.
3553-
ExpressionInferenceResult _computeBinaryExpression(int fileOffset,
3554-
Expression left, DartType leftType, Name binaryName, Expression right) {
3565+
ExpressionInferenceResult _computeBinaryExpression(
3566+
int fileOffset,
3567+
DartType contextType,
3568+
Expression left,
3569+
DartType leftType,
3570+
Name binaryName,
3571+
Expression right) {
35553572
assert(binaryName != equalsName);
35563573

35573574
ObjectAccessTarget binaryTarget = inferrer.findInterfaceMember(
@@ -3566,13 +3583,21 @@ class InferenceVisitor
35663583
DartType rightType =
35673584
inferrer.getPositionalParameterTypeForTarget(binaryTarget, leftType, 0);
35683585

3569-
bool isOverloadedArithmeticOperatorAndType =
3570-
inferrer.isOverloadedArithmeticOperatorAndType(binaryTarget, leftType);
3586+
bool isSpecialCasedBinaryOperator = inferrer
3587+
.isSpecialCasedBinaryOperatorForReceiverType(binaryTarget, leftType);
3588+
3589+
bool typeNeeded = !inferrer.isTopLevel || isSpecialCasedBinaryOperator;
35713590

3572-
bool typeNeeded =
3573-
!inferrer.isTopLevel || isOverloadedArithmeticOperatorAndType;
3574-
ExpressionInferenceResult rightResult = inferrer
3575-
.inferExpression(right, rightType, typeNeeded, isVoidAllowed: true);
3591+
DartType rightContextType = rightType;
3592+
if (isSpecialCasedBinaryOperator) {
3593+
rightContextType = inferrer.typeSchemaEnvironment
3594+
.getContextTypeOfSpecialCasedBinaryOperator(
3595+
contextType, leftType, rightType,
3596+
isNonNullableByDefault: inferrer.isNonNullableByDefault);
3597+
}
3598+
ExpressionInferenceResult rightResult = inferrer.inferExpression(
3599+
right, rightContextType, typeNeeded,
3600+
isVoidAllowed: true);
35763601
if (rightResult.inferredType == null) {
35773602
assert(!typeNeeded,
35783603
"Missing right type for overloaded arithmetic operator.");
@@ -3584,9 +3609,11 @@ class InferenceVisitor
35843609

35853610
right = inferrer.ensureAssignableResult(rightType, rightResult);
35863611

3587-
if (isOverloadedArithmeticOperatorAndType) {
3612+
if (isSpecialCasedBinaryOperator) {
35883613
binaryType = inferrer.typeSchemaEnvironment
3589-
.getTypeOfOverloadedArithmetic(leftType, rightResult.inferredType);
3614+
.getTypeOfSpecialCasedBinaryOperator(
3615+
leftType, rightResult.inferredType,
3616+
isNonNullableByDefault: inferrer.isNonNullableByDefault);
35903617
}
35913618

35923619
Expression binary;
@@ -4202,23 +4229,30 @@ class InferenceVisitor
42024229
left = read;
42034230
}
42044231

4205-
ExpressionInferenceResult binaryResult = _computeBinaryExpression(
4206-
node.binaryOffset, left, readType, node.binaryName, node.rhs);
4207-
Expression binary = binaryResult.expression;
4208-
DartType binaryType = binaryResult.inferredType;
4209-
42104232
ObjectAccessTarget writeTarget = inferrer.findInterfaceMember(
42114233
receiverType, indexSetName, node.writeOffset,
42124234
includeExtensionMethods: true);
42134235

42144236
DartType writeIndexType =
42154237
inferrer.getIndexKeyType(writeTarget, receiverType);
4238+
4239+
DartType valueType =
4240+
inferrer.getIndexSetValueType(writeTarget, receiverType);
4241+
4242+
ExpressionInferenceResult binaryResult = _computeBinaryExpression(
4243+
node.binaryOffset,
4244+
valueType,
4245+
left,
4246+
readType,
4247+
node.binaryName,
4248+
node.rhs);
4249+
Expression binary = binaryResult.expression;
4250+
DartType binaryType = binaryResult.inferredType;
4251+
42164252
Expression writeIndex = createVariableGet(indexVariable);
42174253
writeIndex = inferrer.ensureAssignable(
42184254
writeIndexType, indexResult.inferredType, writeIndex);
42194255

4220-
DartType valueType =
4221-
inferrer.getIndexSetValueType(writeTarget, receiverType);
42224256
binary = inferrer.ensureAssignable(valueType, binaryType, binary,
42234257
fileOffset: node.fileOffset);
42244258

@@ -4342,17 +4376,23 @@ class InferenceVisitor
43424376
left = read;
43434377
}
43444378

4345-
ExpressionInferenceResult binaryResult = _computeBinaryExpression(
4346-
node.binaryOffset, left, readType, node.binaryName, node.rhs);
4347-
Expression binary = binaryResult.expression;
4348-
DartType binaryType = binaryResult.inferredType;
4349-
43504379
ObjectAccessTarget writeTarget = inferrer.findInterfaceMember(
43514380
nonNullReceiverType, node.propertyName, node.writeOffset,
43524381
setter: true, includeExtensionMethods: true);
43534382

43544383
DartType valueType =
43554384
inferrer.getSetterType(writeTarget, nonNullReceiverType);
4385+
4386+
ExpressionInferenceResult binaryResult = _computeBinaryExpression(
4387+
node.binaryOffset,
4388+
valueType,
4389+
left,
4390+
readType,
4391+
node.binaryName,
4392+
node.rhs);
4393+
Expression binary = binaryResult.expression;
4394+
DartType binaryType = binaryResult.inferredType;
4395+
43564396
binary = inferrer.ensureAssignable(valueType, binaryType, binary,
43574397
fileOffset: node.fileOffset);
43584398

@@ -4477,25 +4517,31 @@ class InferenceVisitor
44774517
} else {
44784518
left = read;
44794519
}
4480-
4481-
ExpressionInferenceResult binaryResult = _computeBinaryExpression(
4482-
node.binaryOffset, left, readType, node.binaryName, node.rhs);
4483-
Expression binary = binaryResult.expression;
4484-
DartType binaryType = binaryResult.inferredType;
4485-
44864520
ObjectAccessTarget writeTarget = node.setter != null
44874521
? new ObjectAccessTarget.interfaceMember(node.setter,
44884522
isPotentiallyNullable: false)
44894523
: const ObjectAccessTarget.missing();
44904524

44914525
DartType writeIndexType =
44924526
inferrer.getIndexKeyType(writeTarget, inferrer.thisType);
4527+
4528+
DartType valueType =
4529+
inferrer.getIndexSetValueType(writeTarget, inferrer.thisType);
4530+
4531+
ExpressionInferenceResult binaryResult = _computeBinaryExpression(
4532+
node.binaryOffset,
4533+
valueType,
4534+
left,
4535+
readType,
4536+
node.binaryName,
4537+
node.rhs);
4538+
Expression binary = binaryResult.expression;
4539+
DartType binaryType = binaryResult.inferredType;
4540+
44934541
Expression writeIndex = createVariableGet(indexVariable);
44944542
writeIndex = inferrer.ensureAssignable(
44954543
writeIndexType, indexResult.inferredType, writeIndex);
44964544

4497-
DartType valueType =
4498-
inferrer.getIndexSetValueType(writeTarget, inferrer.thisType);
44994545
Expression binaryReplacement = inferrer.ensureAssignable(
45004546
valueType, binaryType, binary,
45014547
fileOffset: node.fileOffset);
@@ -4643,24 +4689,31 @@ class InferenceVisitor
46434689
left = read;
46444690
}
46454691

4646-
ExpressionInferenceResult binaryResult = _computeBinaryExpression(
4647-
node.binaryOffset, left, readType, node.binaryName, node.rhs);
4648-
Expression binary = binaryResult.expression;
4649-
DartType binaryType = binaryResult.inferredType;
4650-
46514692
ObjectAccessTarget writeTarget = node.setter != null
46524693
? new ExtensionAccessTarget(
46534694
node.setter, null, ProcedureKind.Operator, extensionTypeArguments)
46544695
: const ObjectAccessTarget.missing();
46554696

46564697
DartType writeIndexType =
46574698
inferrer.getIndexKeyType(writeTarget, receiverType);
4658-
Expression writeIndex = createVariableGet(indexVariable);
4659-
writeIndex = inferrer.ensureAssignable(
4660-
writeIndexType, indexResult.inferredType, writeIndex);
46614699

46624700
DartType valueType =
46634701
inferrer.getIndexSetValueType(writeTarget, inferrer.thisType);
4702+
4703+
ExpressionInferenceResult binaryResult = _computeBinaryExpression(
4704+
node.binaryOffset,
4705+
valueType,
4706+
left,
4707+
readType,
4708+
node.binaryName,
4709+
node.rhs);
4710+
4711+
Expression binary = binaryResult.expression;
4712+
DartType binaryType = binaryResult.inferredType;
4713+
4714+
Expression writeIndex = createVariableGet(indexVariable);
4715+
writeIndex = inferrer.ensureAssignable(
4716+
writeIndexType, indexResult.inferredType, writeIndex);
46644717
binary = inferrer.ensureAssignable(valueType, binaryType, binary,
46654718
fileOffset: node.fileOffset);
46664719

@@ -5832,8 +5885,13 @@ class InferenceVisitor
58325885
BinaryExpression node, DartType typeContext) {
58335886
ExpressionInferenceResult leftResult =
58345887
inferrer.inferExpression(node.left, const UnknownType(), true);
5835-
return _computeBinaryExpression(node.fileOffset, leftResult.expression,
5836-
leftResult.inferredType, node.binaryName, node.right);
5888+
return _computeBinaryExpression(
5889+
node.fileOffset,
5890+
typeContext,
5891+
leftResult.expression,
5892+
leftResult.inferredType,
5893+
node.binaryName,
5894+
node.right);
58375895
}
58385896

58395897
ExpressionInferenceResult visitUnary(

0 commit comments

Comments
 (0)