Skip to content

Commit 0887806

Browse files
stereotype441commit-bot@chromium.org
authored andcommitted
Flow analysis: introduce TypeOperations.tryPromoteToType method.
Previously, any attempt to promote type A to type B produced type B if B was a subtype of A, and failed otherwise. But in order to support promotion of type parameters, we need the ability to produce a fresh "intersection type" (e.g. `T & int`). The new `TypeOperations.tryPromoteToType method` makes this possible by giving the client the opportunity to synthesize the new type when necessary. Change-Id: If671d5d865f38469a878329180c3a1c94e25a42c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122582 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
1 parent 04702d8 commit 0887806

File tree

4 files changed

+36
-3
lines changed

4 files changed

+36
-3
lines changed

pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,16 @@ class TypeSystemTypeOperations
277277
return typeSystem.promoteToNonNull(type);
278278
}
279279

280+
@override
281+
DartType tryPromoteToType(DartType to, DartType from) {
282+
// TODO(paulberry): implement appropriate logic for type variable promotion.
283+
if (isSubtypeOf(to, from)) {
284+
return to;
285+
} else {
286+
return null;
287+
}
288+
}
289+
280290
@override
281291
DartType variableType(PromotableElement variable) {
282292
return variable.type;

pkg/front_end/lib/src/fasta/flow_analysis/flow_analysis.dart

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,11 +1054,11 @@ class FlowModel<Variable, Type> {
10541054
Type previousType = info.promotedType;
10551055
previousType ??= typeOperations.variableType(variable);
10561056

1057-
if (!typeOperations.isSubtypeOf(type, previousType) ||
1058-
typeOperations.isSameType(type, previousType)) {
1057+
Type newType = typeOperations.tryPromoteToType(type, previousType);
1058+
if (newType == null || typeOperations.isSameType(newType, previousType)) {
10591059
return this;
10601060
}
1061-
return _updateVariableInfo(variable, info.withPromotedType(type));
1061+
return _updateVariableInfo(variable, info.withPromotedType(newType));
10621062
}
10631063

10641064
/// Updates the state to indicate that the given [writtenVariables] are no
@@ -1325,6 +1325,10 @@ abstract class TypeOperations<Variable, Type> {
13251325
/// `FutureOr<int?>`), so [type] may be returned even if it is nullable.
13261326
Type /*!*/ promoteToNonNull(Type type);
13271327

1328+
/// Tries to promote to the first type from the second type, and returns the
1329+
/// promoted type if it succeeds, otherwise null.
1330+
Type tryPromoteToType(Type to, Type from);
1331+
13281332
/// Return the static type of the given [variable].
13291333
Type variableType(Variable variable);
13301334
}

pkg/front_end/test/fasta/flow_analysis/flow_analysis_test.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2092,6 +2092,15 @@ class _Harness implements TypeOperations<_Var, _Type> {
20922092
_flow.finish();
20932093
}
20942094

2095+
@override
2096+
_Type tryPromoteToType(_Type to, _Type from) {
2097+
if (isSubtypeOf(to, from)) {
2098+
return to;
2099+
} else {
2100+
return null;
2101+
}
2102+
}
2103+
20952104
LazyExpression variableRead(_Var variable) {
20962105
return () {
20972106
var expr = _Expression();

pkg/nnbd_migration/lib/src/decorated_type_operations.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ class DecoratedTypeOperations
3434
return type.withNode(_graph.never);
3535
}
3636

37+
@override
38+
DecoratedType tryPromoteToType(DecoratedType to, DecoratedType from) {
39+
// TODO(paulberry): implement appropriate logic for type variable promotion.
40+
if (isSubtypeOf(to, from)) {
41+
return to;
42+
} else {
43+
return null;
44+
}
45+
}
46+
3747
@override
3848
DecoratedType variableType(PromotableElement variable) {
3949
return _variableRepository.decoratedElementType(variable);

0 commit comments

Comments
 (0)