File tree 2 files changed +34
-4
lines changed 2 files changed +34
-4
lines changed Original file line number Diff line number Diff line change @@ -466,10 +466,19 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
466
466
node.element as ExecutableElementImpl ;
467
467
DartType computedType = _computeStaticReturnTypeOfFunctionExpression (node);
468
468
if (_strongMode) {
469
+ // In strong mode, we don't want to allow the function's return type to
470
+ // be bottom. If the surrounding context has a more precise type, we
471
+ // will push it down with inference, below. If not we want to use dynamic.
472
+ // TODO(jmesserly): should we do this for the `null` literal always in
473
+ // strong mode, instead of handling it here?
474
+ if (computedType.isBottom) {
475
+ computedType = DynamicTypeImpl .instance;
476
+ }
477
+
469
478
DartType functionType = InferenceContext .getType (node);
470
479
if (functionType is FunctionType ) {
471
480
DartType returnType = functionType.returnType;
472
- if (( computedType.isDynamic || computedType.isBottom) &&
481
+ if (computedType.isDynamic &&
473
482
! (returnType.isDynamic || returnType.isBottom)) {
474
483
computedType = returnType;
475
484
_resolver.inferenceContext.recordInference (node, functionType);
Original file line number Diff line number Diff line change @@ -1584,10 +1584,32 @@ main() {
1584
1584
'''
1585
1585
});
1586
1586
1587
+ // Regression test for https://github.com/dart-lang/dev_compiler/issues/47
1588
+ testChecker ('null literal should not infer as bottom' , {
1589
+ '/main.dart' : '''
1590
+ var h = null;
1591
+ void foo(int f(Object _)) {}
1592
+
1593
+ main() {
1594
+ var f = (x) => null;
1595
+ f = (x) => 'hello';
1596
+
1597
+ var g = null;
1598
+ g = 'hello';
1599
+ (/*info:DYNAMIC_INVOKE*/g.foo());
1600
+
1601
+ h = 'hello';
1602
+ (/*info:DYNAMIC_INVOKE*/h.foo());
1603
+
1604
+ foo(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CLOSURE*/(x) => null);
1605
+ foo(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CLOSURE*/(x) => throw "not implemented");
1606
+ }
1607
+ '''
1608
+ });
1609
+
1587
1610
// TODO(jmesserly): we should change how this inference works.
1588
1611
// For now this test will cover what we use.
1589
- testChecker (
1590
- 'infer from RHS only if it wont conflict with overridden fields 2' , {
1612
+ testChecker ('infer JS builtin' , {
1591
1613
'/main.dart' : '''
1592
1614
import 'dart:_foreign_helper' show JS;
1593
1615
main() {
@@ -1598,6 +1620,5 @@ main() {
1598
1620
}
1599
1621
'''
1600
1622
});
1601
-
1602
1623
});
1603
1624
}
You can’t perform that action at this time.
0 commit comments