diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart index a9c1983d3a7..ad89572fceb 100644 --- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart +++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart @@ -439,7 +439,8 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { HType leftType = left.instructionType; HType rightType = right.instructionType; - // We don't optimize on numbers to preserve the runtime semantics. + // Intersection of int and double return conflicting, so + // we don't optimize on numbers to preserve the runtime semantics. if (!(left.isNumberOrNull() && right.isNumberOrNull()) && leftType.intersection(rightType, compiler).isConflicting()) { return graph.addConstantBool(false, constantSystem); diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types.dart b/sdk/lib/_internal/compiler/implementation/ssa/types.dart index ec73cb0e10a..f24f863b476 100644 --- a/sdk/lib/_internal/compiler/implementation/ssa/types.dart +++ b/sdk/lib/_internal/compiler/implementation/ssa/types.dart @@ -416,6 +416,7 @@ class HBooleanType extends HPrimitiveType { if (other.isUnknown()) return HType.BOOLEAN; if (other.isBooleanOrNull()) return HType.BOOLEAN; if (other.isBoolean()) return HType.BOOLEAN; + if (other.isTop(compiler)) return HType.BOOLEAN; return HType.CONFLICTING; } } @@ -453,7 +454,7 @@ class HNumberOrNullType extends HPrimitiveOrNullType { if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL; if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL; if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; - if (other.isTop(compiler)) { + if (other.canBePrimitiveNumber(compiler)) { return other.canBeNull() ? this : HType.NUMBER; } if (other.canBeNull()) return HType.NULL; @@ -493,6 +494,7 @@ class HNumberType extends HPrimitiveType { if (other.isIntegerOrNull()) return HType.INTEGER; if (other.isDoubleOrNull()) return HType.DOUBLE; if (other.isNumberOrNull()) return HType.NUMBER; + if (other.canBePrimitiveNumber(compiler)) return HType.NUMBER; return HType.CONFLICTING; } } @@ -531,7 +533,7 @@ class HIntegerOrNullType extends HNumberOrNullType { if (other.isDoubleOrNull()) return HType.NULL; if (other.isNumber()) return HType.INTEGER; if (other.isNumberOrNull()) return HType.INTEGER_OR_NULL; - if (other.isTop(compiler)) { + if (other.canBePrimitiveNumber(compiler)) { return other.canBeNull() ? this : HType.INTEGER; } if (other.canBeNull()) return HType.NULL; @@ -574,6 +576,7 @@ class HIntegerType extends HNumberType { if (other.isDoubleOrNull()) return HType.CONFLICTING; if (other.isNumber()) return HType.INTEGER; if (other.isNumberOrNull()) return HType.INTEGER; + if (other.canBePrimitiveNumber(compiler)) return HType.INTEGER; return HType.CONFLICTING; } } @@ -612,7 +615,7 @@ class HDoubleOrNullType extends HNumberOrNullType { if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL; if (other.isNumber()) return HType.DOUBLE; if (other.isNumberOrNull()) return HType.DOUBLE_OR_NULL; - if (other.isTop(compiler)) { + if (other.canBePrimitiveNumber(compiler)) { return other.canBeNull() ? this : HType.DOUBLE; } if (other.canBeNull()) return HType.NULL; @@ -655,6 +658,7 @@ class HDoubleType extends HNumberType { if (other.isDoubleOrNull()) return HType.DOUBLE; if (other.isNumber()) return HType.DOUBLE; if (other.isNumberOrNull()) return HType.DOUBLE; + if (other.canBePrimitiveNumber(compiler)) return HType.DOUBLE; return HType.CONFLICTING; } } diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status index 089101bdfb9..28cc8f8fb4c 100644 --- a/tests/corelib/corelib.status +++ b/tests/corelib/corelib.status @@ -41,9 +41,6 @@ string_base_vm_test: Fail, OK # VM specific test. string_replace_func_test: Skip # Bug 6554 - doesn't terminate. -[ $compiler == dart2js && $checked ] -string_codeunits_test: Fail # Issue 8904 - [ $compiler == dart2js && $runtime == none ] *: Fail, Pass # TODO(ahe): Triage these tests. diff --git a/tests/language/type_intersection_test.dart b/tests/language/type_intersection_test.dart new file mode 100644 index 00000000000..a6e260372cf --- /dev/null +++ b/tests/language/type_intersection_test.dart @@ -0,0 +1,18 @@ +// Copyright (c) 2013, 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. + +// Regression test for dart2js that used to consider that the +// intersection of [Comparable] and [num] is conflicting. + +class A { + foo(a, Comparable b) => a == b; + bar(a, Comparable b) => b == a; +} + +main() { + Expect.isFalse(new A().foo(1, 'foo')); + Expect.isTrue(new A().foo(1, 1)); + Expect.isFalse(new A().bar(1, 'foo')); + Expect.isTrue(new A().bar(1, 1)); +}