Skip to content

Commit a7158eb

Browse files
stereotype441Commit Queue
authored andcommitted
[cfe] Move assignability checking for for-element conditions earlier.
Previously, the logic to validate that the condition part of a for-element (a "for" loop inside a collection) was done in `InferenceVisitorImpl.checkElement` and `InferenceVisitorImpl.checkMapEntry` (which execute after the type of the collection has been fully inferred). This CL moves the logic to `InferenceVisitorImpl._inferForElementBase` and `InferenceVisitorImpl._inferForMapEntryBase` (so that the assignability check happens right after the condition has been visited by the type inferrer). Moving the assignability checking earlier ensures that if there is an assignability error, the flow analysis "why not promoted" information will still be valid, increasing the chances that the user can be given a helpful "why not promoted" context message. Change-Id: Ie239a88c94da1bf476fa9e1361053df2d1a56ba2 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/388223 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Paul Berry <[email protected]>
1 parent 8c5dce6 commit a7158eb

File tree

1 file changed

+12
-37
lines changed

1 file changed

+12
-37
lines changed

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

Lines changed: 12 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2658,7 +2658,11 @@ class InferenceVisitorImpl extends InferenceVisitorBase
26582658
ExpressionInferenceResult conditionResult = inferExpression(
26592659
element.condition!, coreTypes.boolRawType(Nullability.nonNullable),
26602660
isVoidAllowed: false);
2661-
element.condition = conditionResult.expression..parent = element;
2661+
Expression assignableCondition = ensureAssignable(
2662+
coreTypes.boolRawType(Nullability.nonNullable),
2663+
conditionResult.inferredType,
2664+
conditionResult.expression);
2665+
element.condition = assignableCondition..parent = element;
26622666
inferredConditionTypes[element.condition!] = conditionResult.inferredType;
26632667
}
26642668
flowAnalysis.for_bodyBegin(null, element.condition);
@@ -2816,28 +2820,12 @@ class InferenceVisitorImpl extends InferenceVisitorBase
28162820
checkElement(otherwise, item, typeArgument, inferredSpreadTypes,
28172821
inferredConditionTypes);
28182822
}
2819-
case ForElement(:Expression? condition, :Expression body):
2820-
if (condition != null) {
2821-
DartType conditionType = inferredConditionTypes[condition]!;
2822-
Expression assignableCondition = ensureAssignable(
2823-
coreTypes.boolRawType(Nullability.nonNullable),
2824-
conditionType,
2825-
condition);
2826-
item.condition = assignableCondition..parent = item;
2827-
}
2823+
case ForElement(:Expression body):
28282824
if (body is ControlFlowElement) {
28292825
checkElement(body, item, typeArgument, inferredSpreadTypes,
28302826
inferredConditionTypes);
28312827
}
2832-
case PatternForElement(:Expression? condition, :Expression body):
2833-
if (condition != null) {
2834-
DartType conditionType = inferredConditionTypes[condition]!;
2835-
Expression assignableCondition = ensureAssignable(
2836-
coreTypes.boolRawType(Nullability.nonNullable),
2837-
conditionType,
2838-
condition);
2839-
item.condition = assignableCondition..parent = item;
2840-
}
2828+
case PatternForElement(:Expression body):
28412829
if (body is ControlFlowElement) {
28422830
checkElement(body, item, typeArgument, inferredSpreadTypes,
28432831
inferredConditionTypes);
@@ -4954,8 +4942,11 @@ class InferenceVisitorImpl extends InferenceVisitorBase
49544942
ExpressionInferenceResult conditionResult = inferExpression(
49554943
entry.condition!, coreTypes.boolRawType(Nullability.nonNullable),
49564944
isVoidAllowed: false);
4957-
entry.condition = conditionResult.expression..parent = entry;
4958-
// TODO(johnniwinther): Ensure assignability of condition?
4945+
Expression condition = ensureAssignable(
4946+
coreTypes.boolRawType(Nullability.nonNullable),
4947+
conditionResult.inferredType,
4948+
conditionResult.expression);
4949+
entry.condition = condition..parent = entry;
49594950
inferredConditionTypes[entry.condition!] = conditionResult.inferredType;
49604951
}
49614952
flowAnalysis.for_bodyBegin(null, entry.condition);
@@ -5210,26 +5201,10 @@ class InferenceVisitorImpl extends InferenceVisitorBase
52105201
entry.otherwise = otherwise..parent = entry;
52115202
}
52125203
case ForMapEntry():
5213-
if (entry.condition != null) {
5214-
DartType conditionType = inferredConditionTypes[entry.condition]!;
5215-
Expression condition = ensureAssignable(
5216-
coreTypes.boolRawType(Nullability.nonNullable),
5217-
conditionType,
5218-
entry.condition!);
5219-
entry.condition = condition..parent = entry;
5220-
}
52215204
MapLiteralEntry body = checkMapEntry(entry.body, keyType, valueType,
52225205
inferredSpreadTypes, inferredConditionTypes, offsets);
52235206
entry.body = body..parent = entry;
52245207
case PatternForMapEntry():
5225-
if (entry.condition != null) {
5226-
DartType conditionType = inferredConditionTypes[entry.condition]!;
5227-
Expression condition = ensureAssignable(
5228-
coreTypes.boolRawType(Nullability.nonNullable),
5229-
conditionType,
5230-
entry.condition!);
5231-
entry.condition = condition..parent = entry;
5232-
}
52335208
MapLiteralEntry body = checkMapEntry(entry.body, keyType, valueType,
52345209
inferredSpreadTypes, inferredConditionTypes, offsets);
52355210
entry.body = body..parent = entry;

0 commit comments

Comments
 (0)