Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(451)

Unified Diff: pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart

Issue 2886873005: Minor type inference fixes to do with null and bottom types. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 38fda54600efd850d7abe06aa87e58bd29076acb..645f9fa0d900cc58886e5b8264165a2b0e8ac2dc 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
@@ -195,9 +195,8 @@ abstract class TypeInferrerImpl extends TypeInferrer {
return inferredType;
}
- /// Modifies a type as appropriate when inferring a variable's type or a
- /// closure return type.
- DartType inferDeclarationOrReturnType(DartType initializerType) {
+ /// Modifies a type as appropriate when inferring a declared variable's type.
+ DartType inferDeclarationType(DartType initializerType) {
if (initializerType is BottomType ||
(initializerType is InterfaceType &&
initializerType.classNode == coreTypes.nullClass)) {
@@ -386,8 +385,8 @@ abstract class TypeInferrerImpl extends TypeInferrer {
// if `B’` contains no `return` expressions.
DartType inferredReturnType;
if (needToSetReturnType || typeNeeded) {
- inferredReturnType =
- inferDeclarationOrReturnType(_closureContext.inferredReturnType);
+ inferredReturnType = inferReturnType(
+ _closureContext.inferredReturnType, isExpressionFunction);
if (!isExpressionFunction &&
returnContext != null &&
!typeSchemaEnvironment.isSubtypeOf(
@@ -598,9 +597,32 @@ abstract class TypeInferrerImpl extends TypeInferrer {
var inferredType = expression != null
? inferExpression(expression, typeContext, closureContext != null)
: const VoidType();
+ if (expression == null) {
+ // Analyzer treats bare `return` statements as having no effect on the
+ // inferred type of the closure. TODO(paulberry): is this what we want
+ // for Fasta?
+ return;
+ }
closureContext?.updateInferredReturnType(this, inferredType);
}
+ /// Modifies a type as appropriate when inferring a closure return type.
+ DartType inferReturnType(DartType returnType, bool isExpressionFunction) {
+ if (returnType == null) {
+ // Analyzer infers `Null` if there is no `return` expression; the spec
+ // says to return `void`. TODO(paulberry): resolve this difference.
+ return coreTypes.nullClass.rawType;
+ }
+ if (isExpressionFunction &&
+ returnType is InterfaceType &&
+ identical(returnType.classNode, coreTypes.nullClass)) {
+ // Analyzer coerces `Null` to `dynamic` in expression functions; the spec
+ // doesn't say to do this. TODO(paulberry): resolve this difference.
+ return const DynamicType();
+ }
+ return returnType;
+ }
+
/// Performs the core type inference algorithm for static variable getters.
///
/// [typeContext], [typeNeeded], and the return value behave as described in
@@ -690,7 +712,7 @@ abstract class TypeInferrerImpl extends TypeInferrer {
void inferVariableDeclaration(DartType declaredType, Expression initializer,
int offset, void setType(DartType type)) {
if (initializer == null) return;
- var inferredType = inferDeclarationOrReturnType(
+ var inferredType = inferDeclarationType(
inferExpression(initializer, declaredType, declaredType == null));
if (strongMode && declaredType == null) {
instrumentation?.record(Uri.parse(uri), offset, 'type',
@@ -891,12 +913,9 @@ class _ClosureContext {
_ClosureContext(this.isAsync, this.isGenerator, this.returnContext);
- /// Gets the return type that was inferred for the current closure.
+ /// Gets the return type that was inferred for the current closure, or `null`
+ /// if there were no `return` statements.
get inferredReturnType {
- if (_inferredReturnType == null) {
- // No return statement found.
- return const VoidType();
- }
return _inferredReturnType;
}

Powered by Google App Engine
This is Rietveld 408576698