Skip to content

Commit 615f40b

Browse files
stereotype441commit-bot@chromium.org
authored and
commit-bot@chromium.org
committed
Ensure that null is not used as a context in more places.
This CL changes the handling of writeContext (for complex assignments), returnOrYieldContext (for closures), expectedType (for ensureAssignable), and receiverType (for findInterfaceMember) so that they no longer use `null` to represent a context; they use UnknownType or DynamicType as appropriate. It also changes the handling of expectedType (for ensureAssignable) so that it does not require the type to be known. That makes this CL simpler and paves the way for fixing #31792. Change-Id: Ib1be06182f9a9e9f77a9eb81f5daf2364de0f3a7 Reviewed-on: https://dart-review.googlesource.com/44800 Commit-Queue: Paul Berry <paulberry@google.com> Reviewed-by: Kevin Millikin <kmillikin@google.com>
1 parent f368719 commit 615f40b

File tree

6 files changed

+41
-38
lines changed

6 files changed

+41
-38
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ class BodyBuilder<Arguments> extends ScopeListener<JumpTarget>
604604
return member.procedure.function.returnType;
605605
} else {
606606
assert(member is KernelConstructorBuilder);
607-
return null;
607+
return const DynamicType();
608608
}
609609
}
610610

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

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,7 @@ abstract class ShadowComplexAssignment extends ShadowSyntheticExpression {
390390

391391
_ComplexAssignmentInferenceResult _inferRhs(
392392
ShadowTypeInferrer inferrer, DartType readType, DartType writeContext) {
393+
assert(writeContext != null);
393394
var writeOffset = write == null ? -1 : write.fileOffset;
394395
Procedure combinerMember;
395396
DartType combinedType;
@@ -448,7 +449,8 @@ abstract class ShadowComplexAssignment extends ShadowSyntheticExpression {
448449
_storeLetType(inferrer, replacedRhs ?? rhs, rhsType);
449450
if (nullAwareCombiner != null) {
450451
MethodInvocation equalsInvocation = nullAwareCombiner.condition;
451-
inferrer.findMethodInvocationMember(writeContext, equalsInvocation,
452+
inferrer.findMethodInvocationMember(
453+
greatestClosure(inferrer.coreTypes, writeContext), equalsInvocation,
452454
silent: true);
453455
// Note: the case of readType=null only happens for erroneous code.
454456
combinedType = readType == null
@@ -1079,7 +1081,7 @@ class ShadowIndexAssign extends ShadowComplexAssignmentWithReceiver {
10791081
inferrer.getCalleeFunctionType(writeMember, receiverType, false);
10801082
DartType expectedIndexTypeForWrite;
10811083
DartType indexContext = const UnknownType();
1082-
DartType writeContext;
1084+
DartType writeContext = const UnknownType();
10831085
if (calleeType.positionalParameters.length >= 2) {
10841086
// TODO(paulberry): we ought to get a context for the index expression
10851087
// from the index formal parameter, but analyzer doesn't so for now we
@@ -1089,7 +1091,7 @@ class ShadowIndexAssign extends ShadowComplexAssignmentWithReceiver {
10891091
}
10901092
var indexType = inferrer.inferExpression(index, indexContext, true);
10911093
_storeLetType(inferrer, index, indexType);
1092-
if (writeContext != null) {
1094+
if (writeContext is! UnknownType) {
10931095
inferrer.ensureAssignable(
10941096
expectedIndexTypeForWrite,
10951097
indexType,
@@ -1660,10 +1662,9 @@ class ShadowReturnStatement extends ReturnStatement implements ShadowStatement {
16601662
var closureContext = inferrer.closureContext;
16611663
var typeContext = !closureContext.isGenerator
16621664
? closureContext.returnOrYieldContext
1663-
: null;
1665+
: const UnknownType();
16641666
var inferredType = expression != null
1665-
? inferrer.inferExpression(
1666-
expression, typeContext ?? const UnknownType(), true)
1667+
? inferrer.inferExpression(expression, typeContext, true)
16671668
: const VoidType();
16681669
// Analyzer treats bare `return` statements as having no effect on the
16691670
// inferred type of the closure. TODO(paulberry): is this what we want
@@ -1695,14 +1696,14 @@ class ShadowStaticAssignment extends ShadowComplexAssignment {
16951696

16961697
@override
16971698
DartType _inferExpression(ShadowTypeInferrer inferrer, DartType typeContext) {
1698-
DartType readType;
1699+
DartType readType = const DynamicType(); // Only used in error recovery
16991700
var read = this.read;
17001701
if (read is StaticGet) {
17011702
readType = read.target.getterType;
17021703
_storeLetType(inferrer, read, readType);
17031704
}
17041705
Member writeMember;
1705-
DartType writeContext;
1706+
DartType writeContext = const UnknownType();
17061707
var write = this.write;
17071708
if (write is StaticSet) {
17081709
writeContext = write.target.setterType;
@@ -2193,7 +2194,7 @@ class ShadowVariableAssignment extends ShadowComplexAssignment {
21932194
if (read is VariableGet) {
21942195
readType = read.promotedType ?? read.variable.type;
21952196
}
2196-
DartType writeContext;
2197+
DartType writeContext = const UnknownType();
21972198
var write = this.write;
21982199
if (write is VariableSet) {
21992200
writeContext = write.variable.type;
@@ -2347,17 +2348,21 @@ class ShadowYieldStatement extends YieldStatement implements ShadowStatement {
23472348
@override
23482349
void _inferStatement(ShadowTypeInferrer inferrer) {
23492350
var closureContext = inferrer.closureContext;
2350-
var typeContext =
2351-
closureContext.isGenerator ? closureContext.returnOrYieldContext : null;
2352-
if (isYieldStar && typeContext != null) {
2353-
typeContext = inferrer.wrapType(
2354-
typeContext,
2355-
closureContext.isAsync
2356-
? inferrer.coreTypes.streamClass
2357-
: inferrer.coreTypes.iterableClass);
2351+
DartType inferredType;
2352+
if (closureContext.isGenerator) {
2353+
var typeContext = closureContext.returnOrYieldContext;
2354+
if (isYieldStar && typeContext != null) {
2355+
typeContext = inferrer.wrapType(
2356+
typeContext,
2357+
closureContext.isAsync
2358+
? inferrer.coreTypes.streamClass
2359+
: inferrer.coreTypes.iterableClass);
2360+
}
2361+
inferredType = inferrer.inferExpression(expression, typeContext, true);
2362+
} else {
2363+
inferredType =
2364+
inferrer.inferExpression(expression, const UnknownType(), true);
23582365
}
2359-
var inferredType = inferrer.inferExpression(
2360-
expression, typeContext ?? const UnknownType(), true);
23612366
closureContext.handleYield(
23622367
inferrer, isYieldStar, inferredType, expression, fileOffset);
23632368
}

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

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,9 @@ class ClosureContext {
195195
}
196196

197197
ClosureContext._(this.isAsync, this.isGenerator, this.returnOrYieldContext,
198-
this._needToInferReturnType, this._needImplicitDowncasts);
198+
this._needToInferReturnType, this._needImplicitDowncasts) {
199+
assert(returnOrYieldContext != null);
200+
}
199201

200202
/// Updates the inferred return type based on the presence of a return
201203
/// statement returning the given [type].
@@ -446,12 +448,13 @@ abstract class TypeInferrerImpl extends TypeInferrer {
446448
typeSchemaEnvironment.isSubtypeOf(actualType, expectedType);
447449
}
448450

449-
/// Checks whether [actualType] can be assigned to [expectedType], and inserts
450-
/// an implicit downcast if appropriate.
451+
/// Checks whether [actualType] can be assigned to the greatest closure of
452+
/// [expectedType], and inserts an implicit downcast if appropriate.
451453
Expression ensureAssignable(DartType expectedType, DartType actualType,
452454
Expression expression, int fileOffset,
453455
{bool isReturnFromAsync = false}) {
454-
assert(expectedType == null || isKnown(expectedType));
456+
assert(expectedType != null);
457+
expectedType = greatestClosure(coreTypes, expectedType);
455458

456459
DartType initialExpectedType = expectedType;
457460
if (isReturnFromAsync && !isAssignable(expectedType, actualType)) {
@@ -549,6 +552,8 @@ abstract class TypeInferrerImpl extends TypeInferrer {
549552
Expression receiver,
550553
bool setter: false,
551554
bool silent: false}) {
555+
assert(receiverType != null && isKnown(receiverType));
556+
552557
// Our non-strong golden files currently don't include interface
553558
// targets, so we can't store the interface target without causing tests
554559
// to fail. TODO(paulberry): fix this.
@@ -793,7 +798,7 @@ abstract class TypeInferrerImpl extends TypeInferrer {
793798
if (type is InterfaceType && identical(type.classNode, class_)) {
794799
return type.typeArguments[0];
795800
} else {
796-
return null;
801+
return const UnknownType();
797802
}
798803
}
799804

@@ -1135,7 +1140,11 @@ abstract class TypeInferrerImpl extends TypeInferrer {
11351140

11361141
DartType inferLocalFunction(FunctionNode function, DartType typeContext,
11371142
int fileOffset, DartType returnContext) {
1138-
bool hasImplicitReturnType = returnContext == null;
1143+
bool hasImplicitReturnType = false;
1144+
if (returnContext == null) {
1145+
hasImplicitReturnType = true;
1146+
returnContext = const DynamicType();
1147+
}
11391148
if (!isTopLevel) {
11401149
var positionalParameters = function.positionalParameters;
11411150
for (var i = 0; i < positionalParameters.length; i++) {
@@ -1234,9 +1243,7 @@ abstract class TypeInferrerImpl extends TypeInferrer {
12341243
// Let `N'` be `N[T/S]`. The [ClosureContext] constructor will adjust
12351244
// accordingly if the closure is declared with `async`, `async*`, or
12361245
// `sync*`.
1237-
if (returnContext != null) {
1238-
returnContext = substitution.substituteType(returnContext);
1239-
}
1246+
returnContext = substitution.substituteType(returnContext);
12401247

12411248
// Apply type inference to `B` in return context `N’`, with any references
12421249
// to `xi` in `B` having type `Pi`. This produces `B’`.

tests/language_2/language_2_dart2js.status

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2061,15 +2061,12 @@ async_await_syntax_test/c03a: Crash # Interpolated value #1 is not an Expression
20612061
async_await_syntax_test/c05a: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
20622062
async_await_syntax_test/c06a: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
20632063
async_await_syntax_test/c09a: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
2064-
async_await_syntax_test/c10a: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
20652064
async_await_syntax_test/d01a: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
20662065
async_await_syntax_test/d02a: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
20672066
async_await_syntax_test/d03a: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
20682067
async_await_syntax_test/d05a: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
20692068
async_await_syntax_test/d06a: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
2070-
async_await_syntax_test/d08b: MissingCompileTimeError
20712069
async_await_syntax_test/d09a: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
2072-
async_await_syntax_test/d10a: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
20732070
async_await_test/02: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
20742071
async_await_test/03: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
20752072
async_await_test/none: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).

tests/language_2/language_2_dartdevc.status

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,6 @@ abstract_getter_test/01: MissingCompileTimeError
323323
abstract_syntax_test/00: MissingCompileTimeError
324324
additional_interface_adds_optional_args_concrete_subclass_test: MissingCompileTimeError
325325
additional_interface_adds_optional_args_concrete_test: MissingCompileTimeError
326-
async_await_syntax_test/c10a: MissingCompileTimeError
327-
async_await_syntax_test/d08b: MissingCompileTimeError
328-
async_await_syntax_test/d10a: MissingCompileTimeError
329326
async_or_generator_return_type_stacktrace_test/01: MissingCompileTimeError
330327
async_or_generator_return_type_stacktrace_test/02: MissingCompileTimeError
331328
async_or_generator_return_type_stacktrace_test/03: MissingCompileTimeError

tests/language_2/language_2_kernel.status

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ abstract_override_adds_optional_args_concrete_test: MissingCompileTimeError # Is
2828
abstract_syntax_test/00: MissingCompileTimeError # Issue 32013.
2929
additional_interface_adds_optional_args_concrete_subclass_test: MissingCompileTimeError # Issue 32014.
3030
additional_interface_adds_optional_args_concrete_test: MissingCompileTimeError # Issue 32014.
31-
async_await_syntax_test/c10a: MissingCompileTimeError
32-
async_await_syntax_test/d08b: MissingCompileTimeError
33-
async_await_syntax_test/d10a: MissingCompileTimeError
3431
async_or_generator_return_type_stacktrace_test/01: MissingCompileTimeError
3532
async_or_generator_return_type_stacktrace_test/02: MissingCompileTimeError
3633
async_or_generator_return_type_stacktrace_test/03: MissingCompileTimeError

0 commit comments

Comments
 (0)