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 |