From ef1528aa78c646f786717ad6174b521699ece1a2 Mon Sep 17 00:00:00 2001 From: Stephen Adams Date: Thu, 30 Apr 2020 01:41:02 +0000 Subject: [PATCH] [js_runtime] Never is a bottom in legacy mode Opt-in code can have Never types even with legacy subtyping. Bug: 41675 Change-Id: I6dbdc064dceeedf0774d10faaca336561b41b7d5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/145561 Commit-Queue: Stephen Adams Reviewed-by: Mayank Patke --- sdk/lib/_internal/js_runtime/lib/rti.dart | 9 ++++----- sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart | 9 ++++----- tests/compiler/dart2js_extra/rti/subtype_test.dart | 6 ++++++ 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/sdk/lib/_internal/js_runtime/lib/rti.dart b/sdk/lib/_internal/js_runtime/lib/rti.dart index 06ddaff5197..d89ededc408 100644 --- a/sdk/lib/_internal/js_runtime/lib/rti.dart +++ b/sdk/lib/_internal/js_runtime/lib/rti.dart @@ -2559,11 +2559,7 @@ bool _isSubtype(universe, Rti s, sEnv, Rti t, tEnv) { if (isStrongTopType(s)) return false; // Left Bottom: - if (isLegacy) { - if (isNullType(s)) return true; - } else { - if (sKind == Rti.kindNever) return true; - } + if (isBottomType(s)) return true; // Left Type Variable Bound 1: bool leftTypeVariable = sKind == Rti.kindGenericFunctionParameter; @@ -2897,6 +2893,9 @@ bool isStrongTopType(Rti t) { isNullableObjectType(t); } +bool isBottomType(Rti t) => + Rti._getKind(t) == Rti.kindNever || JS_GET_FLAG('LEGACY') && isNullType(t); + bool isObjectType(Rti t) => _Utils.isIdentical(t, TYPE_REF()); bool isLegacyObjectType(Rti t) => _Utils.isIdentical(t, LEGACY_TYPE_REF()); diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart index 685e8f245dd..05e37102ca4 100644 --- a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart +++ b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart @@ -2653,11 +2653,7 @@ bool _isSubtype(Object? universe, Rti s, Object? sEnv, Rti t, Object? tEnv) { if (isStrongTopType(s)) return false; // Left Bottom: - if (isLegacy) { - if (isNullType(s)) return true; - } else { - if (sKind == Rti.kindNever) return true; - } + if (isBottomType(s)) return true; // Left Type Variable Bound 1: bool leftTypeVariable = sKind == Rti.kindGenericFunctionParameter; @@ -2993,6 +2989,9 @@ bool isStrongTopType(Rti t) { isNullableObjectType(t); } +bool isBottomType(Rti t) => + Rti._getKind(t) == Rti.kindNever || JS_GET_FLAG('LEGACY') && isNullType(t); + bool isObjectType(Rti t) => _Utils.isIdentical(t, TYPE_REF()); bool isLegacyObjectType(Rti t) => _Utils.isIdentical(t, LEGACY_TYPE_REF()); diff --git a/tests/compiler/dart2js_extra/rti/subtype_test.dart b/tests/compiler/dart2js_extra/rti/subtype_test.dart index 0d34f3f84ae..3ffea44656c 100644 --- a/tests/compiler/dart2js_extra/rti/subtype_test.dart +++ b/tests/compiler/dart2js_extra/rti/subtype_test.dart @@ -39,6 +39,7 @@ void runTests() { testInterfaces(); testTopTypes(); testNull(); + testBottom(); testFutureOr(); testFunctions(); testGenericFunctions(); @@ -80,6 +81,11 @@ void testNull() { equivalent(nullName, nullName); } +void testBottom() { + String never = '0&'; + equivalent(nullName, never); // This test is run with legacy subtyping +} + void testFutureOr() { strictSubtype('$futureName', '$futureName'); strictSubtype('int', 'int/');