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

Unified Diff: lib/src/checker/rules.dart

Issue 1050703002: Downwards closure inference (Closed) Base URL: git@github.com:dart-lang/dart-dev-compiler.git@master
Patch Set: Address comments Created 5 years, 9 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
« no previous file with comments | « lib/runtime/dart/collection.js ('k') | lib/src/info.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/checker/rules.dart
diff --git a/lib/src/checker/rules.dart b/lib/src/checker/rules.dart
index 5fe33e6f811ca1fba3e9cb48f4be27fde31d851c..7b87793fbdd0fddff02e43c6ca2d55649219403e 100644
--- a/lib/src/checker/rules.dart
+++ b/lib/src/checker/rules.dart
@@ -570,6 +570,7 @@ class DownwardsInference {
bool inferExpression(Expression e, DartType t) {
if (e is Conversion) return inferExpression(e.node, t);
if (rules.isSubTypeOf(rules.getStaticType(e), t)) return true;
+ if (e is FunctionExpression) return _inferFunctionExpression(e, t);
if (e is ListLiteral) return _inferListLiteral(e, t);
if (e is MapLiteral) return _inferMapLiteral(e, t);
if (e is NamedExpression) return _inferNamedExpression(e, t);
@@ -723,6 +724,33 @@ class DownwardsInference {
return inferExpression(e.expression, t);
}
+ bool _inferFunctionExpression(FunctionExpression e, DartType t) {
+ if (t is! FunctionType) return false;
+ var returnT = (t as FunctionType).returnType;
+ if (returnT.isDynamic) return false;
+ var eType = e.staticType;
+ if (eType is! FunctionType) return false;
+ if (e.body is! ExpressionFunctionBody) return false;
+ var body = (e.body as ExpressionFunctionBody).expression;
+ if (!inferExpression(body, returnT)) return false;
+ // TODO(leafp): Try narrowing the argument types if possible
+ // to get better code in the function body. This requires checking
+ // that the body is well-typed at the more specific type.
+ var element = (e.element as ExecutableElementImpl);
+ var oldReturnT = element.returnType;
+ element.returnType = returnT;
+ // Work around dynamic as bottom for now by handling function literals
+ // with dynamic arguments specially. We already know the body is typable
+ // at the chosen type, and if all args are dynamic, then function must be
+ // typeable.
+ if ((eType as FunctionType).parameters.every((x) => x.type.isDynamic)) {
+ return true;
+ }
+ if (rules.isSubTypeOf(e.staticType, t)) return true;
+ element.returnType = oldReturnT;
+ return false;
+ }
+
bool _inferListLiteral(ListLiteral e, DartType t) {
var dyn = rules.provider.dynamicType;
var listT = rules.provider.listType.substitute4([dyn]);
« no previous file with comments | « lib/runtime/dart/collection.js ('k') | lib/src/info.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698