| Index: pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
|
| diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
|
| index 3140de771faa09907c788e27c5b211699dca252e..5e064d168d61c397e9f89fb6ab510b72f0e6a0e0 100644
|
| --- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
|
| +++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
|
| @@ -99,11 +99,10 @@ class ClosureContext {
|
| inferrer.inferReturnType(_inferredReturnType, isExpressionFunction);
|
| if (!isExpressionFunction &&
|
| returnContext != null &&
|
| - (!inferrer.typeSchemaEnvironment
|
| - .isSubtypeOf(inferredReturnType, returnContext) ||
|
| - returnContext is VoidType)) {
|
| + !_analyzerSubtypeOf(inferrer, inferredReturnType, returnContext)) {
|
| // For block-bodied functions, if the inferred return type isn't a
|
| - // subtype of the context (or the context is void), we use the context.
|
| + // subtype of the context, we use the context. We use analyzer subtyping
|
| + // rules here.
|
| // TODO(paulberry): this is inherited from analyzer; it's not part of
|
| // the spec. See also dartbug.com/29606.
|
| inferredReturnType = greatestClosure(inferrer.coreTypes, returnContext);
|
| @@ -140,6 +139,19 @@ class ClosureContext {
|
| .getLeastUpperBound(_inferredReturnType, type);
|
| }
|
| }
|
| +
|
| + static bool _analyzerSubtypeOf(
|
| + TypeInferrerImpl inferrer, DartType subtype, DartType supertype) {
|
| + if (supertype is VoidType) {
|
| + if (subtype is VoidType) return true;
|
| + if (subtype is InterfaceType &&
|
| + identical(subtype.classNode, inferrer.coreTypes.nullClass)) {
|
| + return true;
|
| + }
|
| + return false;
|
| + }
|
| + return inferrer.typeSchemaEnvironment.isSubtypeOf(subtype, supertype);
|
| + }
|
| }
|
|
|
| /// Keeps track of the local state for the type inference that occurs during
|
|
|