Chromium Code Reviews| Index: lib/src/checker/rules.dart |
| diff --git a/lib/src/checker/rules.dart b/lib/src/checker/rules.dart |
| index 5fe33e6f811ca1fba3e9cb48f4be27fde31d851c..cfa9d74ed93b8b5ff62e644257c3f751128a8d14 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,29 @@ 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; |
|
vsm
2015/04/01 00:14:19
Why do we disallow this?
In this case,
typedef F
Leaf
2015/04/03 00:51:55
Eventually, yes. As it stands, no. I don't impro
|
| + 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. |
| + (e.element as ExecutableElementImpl).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; |
| + } |
| + return rules.isSubTypeOf(e.staticType, t); |
|
vsm
2015/04/01 00:14:19
Should we have changed e.element.returnType if the
Leaf
2015/04/03 00:51:55
Probably not. Probably doesn't matter, but still
|
| + } |
| + |
| bool _inferListLiteral(ListLiteral e, DartType t) { |
| var dyn = rules.provider.dynamicType; |
| var listT = rules.provider.listType.substitute4([dyn]); |