Skip to content

Commit 3eeba4a

Browse files
chloestefantsovaCommit Queue
authored and
Commit Queue
committed
[cfe] Refactor FunctionNode.futureValueType into emitted value type
Previously we would encode the type of the value returned in `async` functions as the field `futureValueType` on `FunctionNode`. For all other kinds of functions, such as `sync`, `sync*`, and `async*`, that field would be null. This CL renames `futureValueType` into `emittedVAlueType`, and for functions of kinds `async`, `sync*`, and `async*` that is expected to be the type of values emitted via `return` or `yield` statements. For `sync` functions that field is supposed to contain `null`. In response to #54159 TEST=existing Change-Id: I1efdbcc4e75d150f5618c7ca50cfe49a0e54fce6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/341662 Reviewed-by: Alexander Markov <[email protected]> Reviewed-by: Johnni Winther <[email protected]> Reviewed-by: Ömer Ağacan <[email protected]> Commit-Queue: Chloe Stefantsova <[email protected]> Reviewed-by: Mayank Patke <[email protected]>
1 parent 8d8c4c6 commit 3eeba4a

File tree

755 files changed

+2289
-2266
lines changed

Some content is hidden

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

755 files changed

+2289
-2266
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ class ImpactBuilder extends StaticTypeVisitor implements ImpactRegistry {
202202
break;
203203

204204
case ir.AsyncMarker.Async:
205-
registerAsync(function.futureValueType!);
205+
registerAsync(function.emittedValueType!);
206206
break;
207207

208208
case ir.AsyncMarker.AsyncStar:

pkg/compiler/lib/src/js_model/element_map_impl.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -2254,7 +2254,7 @@ class JsElementEnvironment extends ElementEnvironment
22542254
return _getSyncStarElementType(returnType);
22552255
case AsyncMarker.ASYNC:
22562256
return elementMap.getDartType(
2257-
getFunctionNode(elementMap, function)!.futureValueType!);
2257+
getFunctionNode(elementMap, function)!.emittedValueType!);
22582258
case AsyncMarker.ASYNC_STAR:
22592259
return _getAsyncStarElementType(returnType);
22602260
}

pkg/compiler/lib/src/kernel/transformations/modular/async_lowering.dart

+3-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class AsyncLowering {
3636

3737
bool _shouldTryAsyncLowering(FunctionNode node) =>
3838
node.asyncMarker == AsyncMarker.Async &&
39-
node.futureValueType != null &&
39+
node.emittedValueType != null &&
4040
_functions.last.shouldLower;
4141

4242
void enterFunction(FunctionNode node) {
@@ -54,7 +54,7 @@ class AsyncLowering {
5454

5555
void _wrapBodySync(FunctionNode node) {
5656
node.asyncMarker = AsyncMarker.Sync;
57-
final futureValueType = node.futureValueType!;
57+
final futureValueType = node.emittedValueType!;
5858
_updateFunctionBody(
5959
node,
6060
ReturnStatement(StaticInvocation(
@@ -69,7 +69,7 @@ class AsyncLowering {
6969
}
7070

7171
void _wrapReturns(_FunctionData functionData, FunctionNode node) {
72-
final futureValueType = node.futureValueType!;
72+
final futureValueType = node.emittedValueType!;
7373
for (final returnStatement in functionData.returnStatements) {
7474
final expression = returnStatement.expression;
7575
// Ensure the returned future has a runtime type (T) matching the

pkg/dart2wasm/lib/transformers.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ class _WasmTransformer extends Transformer {
464464
_addCompleterToController(controller, completer, fileOffset)),
465465
tryFinally,
466466
]),
467-
futureValueType: const VoidType(),
467+
emittedValueType: const VoidType(),
468468
returnType: InterfaceType(
469469
coreTypes.futureClass, Nullability.nonNullable, [const VoidType()]),
470470
asyncMarker: AsyncMarker.Async,
@@ -544,7 +544,7 @@ class _WasmTransformer extends Transformer {
544544
coreTypes.objectNullableRawType, Nullability.nonNullable),
545545
asyncMarker: AsyncMarker.Async,
546546
dartAsyncMarker: AsyncMarker.Async,
547-
futureValueType: coreTypes.objectNullableRawType,
547+
emittedValueType: coreTypes.objectNullableRawType,
548548
));
549549

550550
// Call `asyncMap`.

pkg/dev_compiler/lib/src/kernel/compiler.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -4192,7 +4192,7 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
41924192
// In the body of an `async`, `await` is generated simply as `yield`.
41934193
var gen = emitGeneratorFn((_) => []);
41944194
var returnType = _currentLibrary!.isNonNullableByDefault
4195-
? function.futureValueType!
4195+
? function.emittedValueType!
41964196
// Otherwise flatten the return type because futureValueType(T) is not
41974197
// defined for legacy libraries.
41984198
: _types.flatten(function

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

+3-5
Original file line numberDiff line numberDiff line change
@@ -1305,11 +1305,9 @@ class BodyBuilder extends StackListenerImpl
13051305
asyncModifier,
13061306
body);
13071307
body = inferredFunctionBody.body;
1308-
function.futureValueType = inferredFunctionBody.futureValueType;
1309-
assert(
1310-
!(function.asyncMarker == AsyncMarker.Async &&
1311-
function.futureValueType == null),
1312-
"No future value type computed.");
1308+
function.emittedValueType = inferredFunctionBody.emittedValueType;
1309+
assert(function.asyncMarker == AsyncMarker.Sync ||
1310+
function.emittedValueType != null);
13131311
}
13141312

13151313
if (_context.returnType is! OmittedTypeBuilder) {

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

+45-27
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ abstract class ClosureContext {
4040
/// the unknown type.
4141
DartType get yieldContext;
4242

43-
DartType? get futureValueType;
43+
DartType? get emittedValueType;
4444

4545
factory ClosureContext(InferenceVisitorBase inferrer, AsyncMarker asyncMarker,
4646
DartType returnContext, bool needToInferReturnType) {
@@ -142,6 +142,9 @@ class _SyncClosureContext implements ClosureContext {
142142
@override
143143
DartType get yieldContext => const UnknownType();
144144

145+
@override
146+
DartType? get emittedValueType => null;
147+
145148
final DartType _declaredReturnType;
146149

147150
final bool _needToInferReturnType;
@@ -161,9 +164,6 @@ class _SyncClosureContext implements ClosureContext {
161164
/// being inferred.
162165
List<DartType>? _returnExpressionTypes;
163166

164-
@override
165-
DartType? get futureValueType => null;
166-
167167
_SyncClosureContext(this.inferrer, this._returnContext,
168168
this._declaredReturnType, this._needToInferReturnType) {
169169
if (_needToInferReturnType) {
@@ -493,6 +493,9 @@ class _AsyncClosureContext implements ClosureContext {
493493
@override
494494
DartType get yieldContext => const UnknownType();
495495

496+
@override
497+
DartType? emittedValueType;
498+
496499
final DartType _declaredReturnType;
497500

498501
final bool _needToInferReturnType;
@@ -512,15 +515,12 @@ class _AsyncClosureContext implements ClosureContext {
512515
/// being inferred.
513516
List<DartType>? _returnExpressionTypes;
514517

515-
@override
516-
DartType? futureValueType;
517-
518518
_AsyncClosureContext(
519519
this.inferrer,
520520
this._returnContext,
521521
this._declaredReturnType,
522522
this._needToInferReturnType,
523-
this.futureValueType) {
523+
this.emittedValueType) {
524524
if (_needToInferReturnType) {
525525
_returnStatements = [];
526526
_returnExpressionTypes = [];
@@ -531,14 +531,14 @@ class _AsyncClosureContext implements ClosureContext {
531531
DartType returnType, ReturnStatement statement, DartType expressionType) {
532532
if (inferrer.isNonNullableByDefault) {
533533
assert(
534-
futureValueType != null, "Future value type has not been computed.");
534+
emittedValueType != null, "Future value type has not been computed.");
535535

536536
if (statement.expression == null) {
537537
// It is a compile-time error if s is `return;`, unless T_v is void,
538538
// dynamic, or Null.
539-
if (futureValueType is VoidType ||
540-
futureValueType is DynamicType ||
541-
futureValueType is NullType) {
539+
if (emittedValueType is VoidType ||
540+
emittedValueType is DynamicType ||
541+
emittedValueType is NullType) {
542542
// Valid return;
543543
} else {
544544
statement.expression = inferrer.helper.wrapInProblem(
@@ -560,7 +560,7 @@ class _AsyncClosureContext implements ClosureContext {
560560

561561
DartType flattenedExpressionType =
562562
inferrer.typeSchemaEnvironment.flatten(expressionType);
563-
if (futureValueType is VoidType &&
563+
if (emittedValueType is VoidType &&
564564
!(flattenedExpressionType is VoidType ||
565565
flattenedExpressionType is DynamicType ||
566566
flattenedExpressionType is NullType)) {
@@ -573,8 +573,8 @@ class _AsyncClosureContext implements ClosureContext {
573573
statement.expression!.fileOffset,
574574
noLength)
575575
..parent = statement;
576-
} else if (!(futureValueType is VoidType ||
577-
futureValueType is DynamicType) &&
576+
} else if (!(emittedValueType is VoidType ||
577+
emittedValueType is DynamicType) &&
578578
flattenedExpressionType is VoidType) {
579579
// It is a compile-time error if s is `return e;`, T_v is neither void
580580
// nor dynamic, and flatten(S) is void.
@@ -588,13 +588,13 @@ class _AsyncClosureContext implements ClosureContext {
588588
} else if (flattenedExpressionType is! VoidType &&
589589
!inferrer.typeSchemaEnvironment
590590
.performNullabilityAwareSubtypeCheck(
591-
flattenedExpressionType, futureValueType!)
591+
flattenedExpressionType, emittedValueType!)
592592
.isSubtypeWhenUsingNullabilities()) {
593593
// It is a compile-time error if s is `return e;`, flatten(S) is not
594594
// void, S is not assignable to T_v, and flatten(S) is not a subtype
595595
// of T_v.
596596
statement.expression = inferrer.ensureAssignable(
597-
futureValueType!, expressionType, statement.expression!,
597+
emittedValueType!, expressionType, statement.expression!,
598598
fileOffset: statement.expression!.fileOffset,
599599
runtimeCheckedType:
600600
inferrer.computeGreatestClosure2(_returnContext),
@@ -831,10 +831,10 @@ class _AsyncClosureContext implements ClosureContext {
831831
}
832832

833833
if (inferrer.isNonNullableByDefault) {
834-
futureValueType =
834+
emittedValueType =
835835
computeFutureValueType(inferrer.coreTypes, inferredType);
836836
} else {
837-
futureValueType = inferrer.typeSchemaEnvironment.flatten(inferredType);
837+
emittedValueType = inferrer.typeSchemaEnvironment.flatten(inferredType);
838838
}
839839

840840
for (int i = 0; i < _returnStatements!.length; ++i) {
@@ -915,21 +915,25 @@ class _SyncStarClosureContext implements ClosureContext {
915915
@override
916916
DartType get yieldContext => _yieldElementContext;
917917

918+
@override
919+
DartType? get emittedValueType => _emittedValueType;
920+
918921
final DartType _declaredReturnType;
919922

923+
DartType? _emittedValueType;
924+
920925
final bool _needToInferReturnType;
921926

922927
/// A list of return expression types in functions whose return type is
923928
/// being inferred.
924929
List<DartType>? _yieldElementTypes;
925930

926-
@override
927-
DartType? get futureValueType => null;
928-
929931
_SyncStarClosureContext(this.inferrer, this._yieldElementContext,
930932
this._declaredReturnType, this._needToInferReturnType) {
931933
if (_needToInferReturnType) {
932934
_yieldElementTypes = [];
935+
} else {
936+
_emittedValueType = inferrer.computeGreatestClosure(_yieldElementContext);
933937
}
934938
}
935939

@@ -1009,8 +1013,13 @@ class _SyncStarClosureContext implements ClosureContext {
10091013
inferredType = inferrer.computeGreatestClosure2(_declaredReturnType);
10101014
}
10111015

1012-
return demoteTypeInLibrary(inferredType,
1016+
DartType demotedType = demoteTypeInLibrary(inferredType,
10131017
isNonNullableByDefault: inferrer.isNonNullableByDefault);
1018+
_emittedValueType = inferrer.getTypeArgumentOf(
1019+
inferrer.typeSchemaEnvironment.getUnionFreeType(demotedType,
1020+
isNonNullableByDefault: inferrer.isNonNullableByDefault),
1021+
inferrer.coreTypes.iterableClass);
1022+
return demotedType;
10141023
}
10151024

10161025
@override
@@ -1050,21 +1059,25 @@ class _AsyncStarClosureContext implements ClosureContext {
10501059
@override
10511060
DartType get yieldContext => _yieldElementContext;
10521061

1062+
@override
1063+
DartType? get emittedValueType => _emittedValueType;
1064+
10531065
final DartType _declaredReturnType;
10541066

1067+
DartType? _emittedValueType;
1068+
10551069
final bool _needToInferReturnType;
10561070

10571071
/// A list of return expression types in functions whose return type is
10581072
/// being inferred.
10591073
List<DartType>? _yieldElementTypes;
10601074

1061-
@override
1062-
DartType? get futureValueType => null;
1063-
10641075
_AsyncStarClosureContext(this.inferrer, this._yieldElementContext,
10651076
this._declaredReturnType, this._needToInferReturnType) {
10661077
if (_needToInferReturnType) {
10671078
_yieldElementTypes = [];
1079+
} else {
1080+
_emittedValueType = inferrer.computeGreatestClosure(_yieldElementContext);
10681081
}
10691082
}
10701083

@@ -1142,8 +1155,13 @@ class _AsyncStarClosureContext implements ClosureContext {
11421155
inferredType = inferrer.computeGreatestClosure2(_declaredReturnType);
11431156
}
11441157

1145-
return demoteTypeInLibrary(inferredType,
1158+
DartType demotedType = demoteTypeInLibrary(inferredType,
11461159
isNonNullableByDefault: inferrer.isNonNullableByDefault);
1160+
_emittedValueType = inferrer.getTypeArgumentOf(
1161+
inferrer.typeSchemaEnvironment.getUnionFreeType(demotedType,
1162+
isNonNullableByDefault: inferrer.isNonNullableByDefault),
1163+
inferrer.coreTypes.streamClass);
1164+
return demotedType;
11471165
}
11481166

11491167
@override

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

+2-6
Original file line numberDiff line numberDiff line change
@@ -2326,11 +2326,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
23262326
}
23272327
bodyResult = closureContext.handleImplicitReturn(
23282328
this, function.body!, bodyResult, fileOffset);
2329-
function.futureValueType = closureContext.futureValueType;
2330-
assert(
2331-
!(function.asyncMarker == AsyncMarker.Async &&
2332-
function.futureValueType == null),
2333-
"No future value type computed.");
2329+
function.emittedValueType = closureContext.emittedValueType;
23342330

23352331
if (bodyResult.hasChanged) {
23362332
function.body = bodyResult.statement..parent = function;
@@ -3778,7 +3774,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
37783774

37793775
/// Computes the `futureValueTypeSchema` for the type schema [type].
37803776
///
3781-
/// This is the same as the [futureValueType] except that this handles
3777+
/// This is the same as the [emittedValueType] except that this handles
37823778
/// the unknown type.
37833779
DartType computeFutureValueTypeSchema(DartType type) {
37843780
return type.accept1(new FutureValueTypeVisitor(unhandledTypeHandler:

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

+5-6
Original file line numberDiff line numberDiff line change
@@ -206,12 +206,11 @@ class TypeInferrerImpl implements TypeInferrer {
206206
result =
207207
closureContext.handleImplicitReturn(visitor, body, result, fileOffset);
208208
visitor.checkCleanState();
209-
DartType? futureValueType = closureContext.futureValueType;
210-
assert(!(asyncMarker == AsyncMarker.Async && futureValueType == null),
211-
"No future value type computed.");
209+
DartType? emittedValueType = closureContext.emittedValueType;
210+
assert(asyncMarker == AsyncMarker.Sync || emittedValueType != null);
212211
flowAnalysis.finish();
213212
return new InferredFunctionBody(
214-
result.hasChanged ? result.statement : body, futureValueType);
213+
result.hasChanged ? result.statement : body, emittedValueType);
215214
}
216215

217216
@override
@@ -432,7 +431,7 @@ class TypeInferrerImplBenchmarked implements TypeInferrer {
432431

433432
class InferredFunctionBody {
434433
final Statement body;
435-
final DartType? futureValueType;
434+
final DartType? emittedValueType;
436435

437-
InferredFunctionBody(this.body, this.futureValueType);
436+
InferredFunctionBody(this.body, this.emittedValueType);
438437
}

pkg/front_end/test/macros/incremental/data/tests/user_macro/main.0.dart.expect

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ macro class MethodMacro extends core::Object implements api::ClassDeclarationsMa
3636
: super core::Object::•()
3737
;
3838
@#C2
39-
method buildDeclarationsForClass(api::ClassDeclaration clazz, api::MemberDeclarationBuilder builder) → FutureOr<void> async /* futureValueType= void */ {}
39+
method buildDeclarationsForClass(api::ClassDeclaration clazz, api::MemberDeclarationBuilder builder) → FutureOr<void> async /* emittedValueType= void */ {}
4040
}
4141

4242
library;

pkg/front_end/test/macros/incremental/data/tests/user_macro/main.1.dart.expect

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ macro class MethodMacro extends core::Object implements api::ClassDeclarationsMa
3333
: super core::Object::•()
3434
;
3535
@#C2
36-
method buildDeclarationsForClass(api::ClassDeclaration clazz, api::MemberDeclarationBuilder builder) → FutureOr<void> async /* futureValueType= void */ {
36+
method buildDeclarationsForClass(api::ClassDeclaration clazz, api::MemberDeclarationBuilder builder) → FutureOr<void> async /* emittedValueType= void */ {
3737
builder.{api::MemberDeclarationBuilder::declareInType}(new api::DeclarationCode::fromString(mac2::generateBody())){(api::DeclarationCode) → void};
3838
}
3939
}

pkg/front_end/test/macros/incremental/data/tests/user_macro/main.2.dart.expect

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ macro class MethodMacro extends core::Object implements api::ClassDeclarationsMa
3535
: super core::Object::•()
3636
;
3737
@#C2
38-
method buildDeclarationsForClass(api::ClassDeclaration clazz, api::MemberDeclarationBuilder builder) → FutureOr<void> async /* futureValueType= void */ {
38+
method buildDeclarationsForClass(api::ClassDeclaration clazz, api::MemberDeclarationBuilder builder) → FutureOr<void> async /* emittedValueType= void */ {
3939
builder.{api::MemberDeclarationBuilder::declareInType}(new api::DeclarationCode::fromString(mac2::generateBody())){(api::DeclarationCode) → void};
4040
}
4141
}

0 commit comments

Comments
 (0)