Version 2.13.0-128.0.dev

Merge commit 'ab694d352de30c2a235d8560f7ed86c5e3cd256d' into 'dev'
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index 3d43b0c..e12068e 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -919,18 +919,14 @@
         node, node.variable.parent, node.arguments, selector);
   }
 
-  TypeInformation _handleEqualsNull(ir.Expression node, ir.Expression operand) {
-    _potentiallyAddNullCheck(node, operand);
-    return _types.boolType;
-  }
-
   @override
   TypeInformation visitEqualsNull(ir.EqualsNull node) {
     // TODO(johnniwinther). This triggers the computation of the mask for the
     // receiver of the call to `==`, which doesn't happen in this case. Remove
     // this when the ssa builder recognized `== null` directly.
     _typeOfReceiver(node, node.expression);
-    return _handleEqualsNull(node, node.expression);
+    _potentiallyAddNullCheck(node, node.expression);
+    return _types.boolType;
   }
 
   TypeInformation _handleMethodInvocation(
@@ -983,12 +979,20 @@
     // receiver of the call to `==`, which might not happen in this case. Remove
     // this when the ssa builder recognized `== null` directly.
     _typeOfReceiver(node, left);
-    if (_types.isNull(leftType)) {
-      // null == o
-      return _handleEqualsNull(node, right);
-    } else if (_types.isNull(rightType)) {
-      // o == null
-      return _handleEqualsNull(node, left);
+    bool leftIsNull = _types.isNull(leftType);
+    bool rightIsNull = _types.isNull(rightType);
+    if (leftIsNull) {
+      // [right] is `null` if [node] evaluates to `true`.
+      _potentiallyAddNullCheck(node, right);
+    }
+    if (rightIsNull) {
+      // [left] is `null` if [node] evaluates to `true`.
+      _potentiallyAddNullCheck(node, left);
+    }
+    if (leftIsNull || rightIsNull) {
+      // `left == right` where `left` and/or `right` is known to have type
+      // `Null` so we have no invocation to register.
+      return _types.boolType;
     }
     Selector selector = Selector.binaryOperator('==');
     ArgumentsTypes arguments = ArgumentsTypes([rightType], null);
diff --git a/pkg/compiler/test/inference/data/non_null.dart b/pkg/compiler/test/inference/data/non_null.dart
index d93cd29..96ee27e 100644
--- a/pkg/compiler/test/inference/data/non_null.dart
+++ b/pkg/compiler/test/inference/data/non_null.dart
@@ -46,8 +46,7 @@
   return new Class2(). /*invoke: [exact=Class2]*/ method();
 }
 
-// TODO(johnniwinther): We should infer that the returned value cannot be null.
-/*member: nonNullLocal:[null|exact=JSUInt31]*/
+/*member: nonNullLocal:[exact=JSUInt31]*/
 nonNullLocal() {
   var local = null;
   return local ??= 42;
diff --git a/pkg/compiler/test/inference/data/postfix.dart b/pkg/compiler/test/inference/data/postfix.dart
index 8059eac..67cf94f 100644
--- a/pkg/compiler/test/inference/data/postfix.dart
+++ b/pkg/compiler/test/inference/data/postfix.dart
@@ -26,7 +26,7 @@
   if (local == null) {
     local = 0;
   }
-  return local /*invoke: [null|exact=JSUInt31]*/ ++;
+  return local /*invoke: [exact=JSUInt31]*/ ++;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -39,7 +39,7 @@
   if (local == null) {
     local = 0;
   }
-  return local /*invoke: [null|exact=JSUInt31]*/ --;
+  return local /*invoke: [exact=JSUInt31]*/ --;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/pkg/compiler/test/inference/data/prefix.dart b/pkg/compiler/test/inference/data/prefix.dart
index bb1cfb1..a7302fc 100644
--- a/pkg/compiler/test/inference/data/prefix.dart
+++ b/pkg/compiler/test/inference/data/prefix.dart
@@ -26,7 +26,7 @@
   if (local == null) {
     local = 0;
   }
-  return /*invoke: [null|exact=JSUInt31]*/ ++local;
+  return /*invoke: [exact=JSUInt31]*/ ++local;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -39,7 +39,7 @@
   if (local == null) {
     local = 0;
   }
-  return /*invoke: [null|exact=JSUInt31]*/ --local;
+  return /*invoke: [exact=JSUInt31]*/ --local;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/tools/VERSION b/tools/VERSION
index 719303b..766282c 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 127
+PRERELEASE 128
 PRERELEASE_PATCH 0
\ No newline at end of file