Allow `x == null` to be a constant value whenever x is const.

This is the fix for #33408 for dart2js

Change-Id: Ifddeacb68884da308d279ce6d5cbbb6adc5385ca
Reviewed-on: https://dart-review.googlesource.com/69020
Commit-Queue: Harry Terkelsen <het@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
diff --git a/pkg/compiler/lib/src/constant_system_dart.dart b/pkg/compiler/lib/src/constant_system_dart.dart
index 4179a3b..8d9fab5 100644
--- a/pkg/compiler/lib/src/constant_system_dart.dart
+++ b/pkg/compiler/lib/src/constant_system_dart.dart
@@ -342,10 +342,14 @@
     }
 
     if (left.isConstructedObject) {
+      if (right.isNull) {
+        return DART_CONSTANT_SYSTEM.createBool(false);
+      }
       // Unless we know that the user-defined object does not implement the
       // equality operator we cannot fold here.
       return null;
     }
+
     return DART_CONSTANT_SYSTEM.createBool(left == right);
   }
 
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index b03de0b..38a4e71 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -1051,22 +1051,26 @@
       case BinaryOperatorKind.EQ:
       case BinaryOperatorKind.NOT_EQ:
         if (!leftValue.isPrimitive) {
-          environment.reportError(
-              left, MessageKind.INVALID_CONSTANT_BINARY_PRIMITIVE_TYPE, {
-            'constant': left,
-            'type': leftValue.getType(environment.commonElements),
-            'operator': operator
-          });
-          isValid = false;
+          if (!rightValue.isNull) {
+            environment.reportError(
+                left, MessageKind.INVALID_CONSTANT_BINARY_PRIMITIVE_TYPE, {
+              'constant': left,
+              'type': leftValue.getType(environment.commonElements),
+              'operator': operator
+            });
+            isValid = false;
+          }
         }
         if (!rightValue.isPrimitive) {
-          environment.reportError(
-              right, MessageKind.INVALID_CONSTANT_BINARY_PRIMITIVE_TYPE, {
-            'constant': right,
-            'type': rightValue.getType(environment.commonElements),
-            'operator': operator
-          });
-          isValid = false;
+          if (!leftValue.isNull) {
+            environment.reportError(
+                right, MessageKind.INVALID_CONSTANT_BINARY_PRIMITIVE_TYPE, {
+              'constant': right,
+              'type': rightValue.getType(environment.commonElements),
+              'operator': operator
+            });
+            isValid = false;
+          }
         }
         break;
       case BinaryOperatorKind.ADD:
diff --git a/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart b/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
index 7d8c5ac..c347ba0 100644
--- a/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
+++ b/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
@@ -164,6 +164,8 @@
     const ConstantData('identical', 'FunctionConstant(identical)'),
     const ConstantData('true ? 0 : 1', 'IntConstant(0)'),
     const ConstantData('proxy', 'ConstructedConstant(_Proxy())'),
+    const ConstantData('const [] == null', 'BoolConstant(false)'),
+    const ConstantData('proxy == null', 'BoolConstant(false)'),
     const ConstantData('Object', 'TypeConstant(Object)'),
     const ConstantData('null ?? 0', 'IntConstant(0)'),
     const ConstantData(
@@ -414,10 +416,6 @@
         expectedErrors: MessageKind.INVALID_CONSTANT_ADD_TYPES),
     const ConstantData('boolean + false', 'NonConstant',
         expectedErrors: MessageKind.INVALID_CONSTANT_ADD_TYPES),
-    const ConstantData('const [] == null', 'NonConstant',
-        expectedErrors: MessageKind.INVALID_CONSTANT_BINARY_PRIMITIVE_TYPE),
-    const ConstantData('proxy == null', 'NonConstant',
-        expectedErrors: MessageKind.INVALID_CONSTANT_BINARY_PRIMITIVE_TYPE),
     const ConstantData('0 * ""', 'NonConstant',
         expectedErrors: MessageKind.INVALID_CONSTANT_BINARY_NUM_TYPE),
     const ConstantData('0 * string', 'NonConstant',
diff --git a/tests/compiler/dart2js_extra/constant_javascript_semantics_test5.dart b/tests/compiler/dart2js_extra/constant_javascript_semantics_test5.dart
new file mode 100644
index 0000000..e2275ea
--- /dev/null
+++ b/tests/compiler/dart2js_extra/constant_javascript_semantics_test5.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Make sure we can assert(const Foo() != null) in const initializers.
+class Color {
+  const Color(this.value);
+  final int value;
+}
+
+class ColorHaver {
+  const ColorHaver({this.color = const Color(0xFF000000)})
+      : assert(color != null);
+  final Color color;
+}
+
+const c = const ColorHaver(color: const Color(0xFF00FF00));
+
+enum Enum {
+  a,
+  b,
+}
+
+class EnumHaver {
+  const EnumHaver({this.myEnum: Enum.a}) : assert(myEnum != null);
+  final Enum myEnum;
+}
+
+const e = const EnumHaver(myEnum: Enum.b);
+
+main() {
+  Expect.equals(c.value, 0xFF00FF00);
+  Expect.equals(e.myEnum, Enum.b);
+}