diff --git a/pkg/compiler/lib/src/kernel/transformations/global/js_get_flag_lowering.dart b/pkg/compiler/lib/src/kernel/transformations/global/js_get_flag_lowering.dart index ceade37d48a..ddd46f1a072 100644 --- a/pkg/compiler/lib/src/kernel/transformations/global/js_get_flag_lowering.dart +++ b/pkg/compiler/lib/src/kernel/transformations/global/js_get_flag_lowering.dart @@ -58,7 +58,6 @@ class JsGetFlagLowering { 'USE_CONTENT_SECURITY_POLICY' => _options.features.useContentSecurityPolicy.isEnabled, 'VARIANCE' => _options.enableVariance, - 'LEGACY' => _options.useLegacySubtyping, _ => null, }; diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart index 138e76629eb..3aaf53c6bdd 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart @@ -776,7 +776,6 @@ class ProgramCompiler extends ComputeOnceConstantVisitor if (_isBuildingSdk) { var prerequisiteRtiTypes = [ _coreTypes.objectNullableRawType, - NeverType.legacy() ]; prerequisiteRtiTypes.forEach((type) { var recipe = _typeRecipeGenerator @@ -6152,9 +6151,6 @@ class ProgramCompiler extends ComputeOnceConstantVisitor var value = flag.value; return switch (value) { 'DEV_COMPILER' => js.boolean(true), - // TODO(nshahan): Delete 'LEGACY' after uses are deleted from - // dart:_rti. - 'LEGACY' => js.boolean(false), 'MINIFIED' => js.boolean(false), 'VARIANCE' => // Variance is turned on by default, but only interfaces that have diff --git a/pkg/dev_compiler/lib/src/kernel/compiler_new.dart b/pkg/dev_compiler/lib/src/kernel/compiler_new.dart index fc3be58e4fb..af160165757 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler_new.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler_new.dart @@ -953,7 +953,6 @@ class LibraryCompiler extends ComputeOnceConstantVisitor if (_isSdkInternalRuntime(_currentLibrary!)) { var prerequisiteRtiTypes = [ _coreTypes.objectNullableRawType, - NeverType.legacy() ]; prerequisiteRtiTypes.forEach((type) { var recipe = _typeRecipeGenerator @@ -6600,9 +6599,6 @@ class LibraryCompiler extends ComputeOnceConstantVisitor var value = flag.value; return switch (value) { 'DEV_COMPILER' => js.boolean(true), - // TODO(nshahan): Delete 'LEGACY' after uses are deleted from - // dart:_rti. - 'LEGACY' => js.boolean(false), 'MINIFIED' => js.boolean(false), 'VARIANCE' => // Variance is turned on by default, but only interfaces that have diff --git a/pkg/dev_compiler/lib/src/kernel/type_recipe_generator.dart b/pkg/dev_compiler/lib/src/kernel/type_recipe_generator.dart index 8f87b3b11a7..7745ae11eb1 100644 --- a/pkg/dev_compiler/lib/src/kernel/type_recipe_generator.dart +++ b/pkg/dev_compiler/lib/src/kernel/type_recipe_generator.dart @@ -565,7 +565,7 @@ class _TypeRecipeVisitor extends DartTypeVisitor { case Nullability.nonNullable: return ''; case Nullability.legacy: - return Recipe.wrapStarString; + throw UnsupportedError('Legacy nullability.'); } } diff --git a/pkg/js_shared/lib/synced/recipe_syntax.dart b/pkg/js_shared/lib/synced/recipe_syntax.dart index 64d91cd3f90..58cf39c7f8f 100644 --- a/pkg/js_shared/lib/synced/recipe_syntax.dart +++ b/pkg/js_shared/lib/synced/recipe_syntax.dart @@ -28,8 +28,6 @@ abstract class Recipe { static const int pushVoid = _tilde; static const String pushVoidString = _tildeString; - static const int wrapStar = _asterisk; - static const String wrapStarString = _asteriskString; static const int wrapQuestion = _question; static const String wrapQuestionString = _questionString; static const int wrapFutureOr = _slash; @@ -187,7 +185,6 @@ abstract class Recipe { test("pushErased", pushErased, pushErasedString); test("pushDynamic", pushDynamic, pushDynamicString); test("pushVoid", pushVoid, pushVoidString); - test("wrapStar", wrapStar, wrapStarString); test("wrapQuestion", wrapQuestion, wrapQuestionString); test("wrapFutureOr", wrapFutureOr, wrapFutureOrString); test("startTypeArguments", startTypeArguments, startTypeArgumentsString); diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart index 7ff8f2362c5..bdb3f6309e2 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart @@ -604,7 +604,7 @@ _checkAndCall(f, ftype, obj, typeArgs, args, named, displayName) { for (var i = 0; i < typeParameterCount; i++) { var bound = JS('!', '#[#]', typeParameterBounds, i); var typeArg = JS('!', '#[#]', typeArgs, i); - if (bound != typeArg && !rti.isSoundTopType(bound)) { + if (bound != typeArg && !rti.isTopType(bound)) { var instantiatedBound = rti.substitute(bound, typeArgs); var validSubtype = rti.isSubtype( JS_EMBEDDED_GLOBAL('', RTI_UNIVERSE), diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart index 1eab37a5a17..0a906a3943b 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/runtime.dart @@ -66,8 +66,8 @@ import 'dart:_rti' interfaceTypeRecipePropertyName, isGenericFunctionType, isRecordType, - isSoundTopType, isSubtype, + isTopType, Rti, rtiToString, substitute; diff --git a/sdk/lib/_internal/js_runtime/lib/internal_patch.dart b/sdk/lib/_internal/js_runtime/lib/internal_patch.dart index 7433cc8ac01..5eb42ac4be0 100644 --- a/sdk/lib/_internal/js_runtime/lib/internal_patch.dart +++ b/sdk/lib/_internal/js_runtime/lib/internal_patch.dart @@ -13,10 +13,7 @@ import 'dart:typed_data' show Uint8List; @patch @pragma('dart2js:tryInline') -bool typeAcceptsNull() { - bool isLegacySubtyping = JS_GET_FLAG('LEGACY'); - return isLegacySubtyping || null is T; -} +bool typeAcceptsNull() => null is T; @patch class Symbol implements core.Symbol { diff --git a/sdk/lib/_internal/js_runtime/lib/js_array.dart b/sdk/lib/_internal/js_runtime/lib/js_array.dart index 1ca055c0ca9..746a1e09808 100644 --- a/sdk/lib/_internal/js_runtime/lib/js_array.dart +++ b/sdk/lib/_internal/js_runtime/lib/js_array.dart @@ -121,13 +121,19 @@ class JSArray extends JavaScriptObject implements List, JSIndexable { @pragma('dart2js:prefer-inline') static List markFixedList(List list) { return JS( - 'JSFixedArray', '#', HArrayFlagsSet(list, ArrayFlags.fixedLength)); + 'JSFixedArray', + '#', + HArrayFlagsSet(list, ArrayFlags.fixedLength), + ); } @pragma('dart2js:prefer-inline') static List markUnmodifiableList(List list) { - return JS('JSUnmodifiableArray', '#', - HArrayFlagsSet(list, ArrayFlags.unmodifiable)); + return JS( + 'JSUnmodifiableArray', + '#', + HArrayFlagsSet(list, ArrayFlags.unmodifiable), + ); } static bool isFixedLength(JSArray a) { @@ -149,7 +155,12 @@ class JSArray extends JavaScriptObject implements List, JSIndexable { checkMutable(String operation, String verb) { final int flags = HArrayFlagsGet(this); HArrayFlagsCheck( - this, flags, ArrayFlags.unmodifiableCheck, operation, verb); + this, + flags, + ArrayFlags.unmodifiableCheck, + operation, + verb, + ); } checkGrowable(String operation, String verb) { @@ -623,9 +634,8 @@ class JSArray extends JavaScriptObject implements List, JSIndexable { // with an assignment like `a[i] = a[j]`. int undefineds = 0; - // The element type might exclude the possibility of there being `null`s, - // but only in sound null safety mode. - if (JS_GET_FLAG('LEGACY') || null is E) { + // The element type might exclude the possibility of there being `null`s. + if (null is E) { for (int i = 0; i < length; i++) { final E element = JS('', '#[#]', this, i); if (JS('', '# === void 0', element)) { @@ -726,9 +736,10 @@ class JSArray extends JavaScriptObject implements List, JSIndexable { List toList({bool growable = true}) => growable ? _toListGrowable() : _toListFixed(); - List _toListGrowable() => - // slice(0) is slightly faster than slice() - JSArray.markGrowable(JS('', '#.slice(0)', this)); + List _toListGrowable() { + // slice(0) is slightly faster than slice() + return JSArray.markGrowable(JS('', '#.slice(0)', this)); + } List _toListFixed() => JSArray.markFixed(JS('', '#.slice(0)', this)); @@ -768,8 +779,10 @@ class JSArray extends JavaScriptObject implements List, JSIndexable { void _setLengthUnsafe(int newLength) { assert(newLength is int, throw ArgumentError.value(newLength, 'newLength')); - assert(newLength >= 0, - throw RangeError.range(newLength, 0, null, 'newLength')); + assert( + newLength >= 0, + throw RangeError.range(newLength, 0, null, 'newLength'), + ); // JavaScript with throw a RangeError for numbers that are too big. The // message does not contain the value. @@ -785,8 +798,12 @@ class JSArray extends JavaScriptObject implements List, JSIndexable { void operator []=(int index, E value) { final int flags = HArrayFlagsGet(this); - final checked = - HArrayFlagsCheck(this, flags, ArrayFlags.unmodifiableCheck, '[]='); + final checked = HArrayFlagsCheck( + this, + flags, + ArrayFlags.unmodifiableCheck, + '[]=', + ); if (index is! int) throw diagnoseIndexError(this, index); // This form of the range test correctly rejects NaN. @@ -864,9 +881,9 @@ class ArrayIterator implements Iterator { E? _current; ArrayIterator(JSArray iterable) - : _iterable = iterable, - _length = iterable.length, - _index = 0; + : _iterable = iterable, + _length = iterable.length, + _index = 0; E get current => _current as E; diff --git a/sdk/lib/_internal/js_shared/lib/rti.dart b/sdk/lib/_internal/js_shared/lib/rti.dart index 75ce58e770d..dbb0175e580 100644 --- a/sdk/lib/_internal/js_shared/lib/rti.dart +++ b/sdk/lib/_internal/js_shared/lib/rti.dart @@ -124,8 +124,6 @@ class Rti { /// If kind == kindInterface, holds the first type argument (if any). /// If kind == kindFutureOr, holds Future where T is the base type. /// - This case is lazily initialized during subtype checks. - /// If kind == kindStar, holds T? where T is the base type. - /// - This case is lazily initialized during subtype checks. @pragma('dart2js:noElision') Object? _precomputed1; @@ -135,23 +133,6 @@ class Rti { rti._precomputed1 = precomputed; } - static Rti _unstar(Rti rti) => - _getKind(rti) == kindStar ? _getStarArgument(rti) : rti; - - static Rti _getQuestionFromStar(Object? universe, Rti rti) { - assert(_getKind(rti) == kindStar); - Rti? question = _Utils.asRtiOrNull(_getPrecomputed1(rti)); - if (question == null) { - question = _Universe._lookupQuestionRti( - universe, - _getStarArgument(rti), - true, - ); - Rti._setPrecomputed1(rti, question); - } - return question; - } - static Rti _getFutureFromFutureOr(Object? universe, Rti rti) { assert(_getKind(rti) == kindFutureOr); Rti? future = _Utils.asRtiOrNull(_getPrecomputed1(rti)); @@ -222,21 +203,20 @@ class Rti { static const int kindAny = 4; // Dart1-style 'dynamic' for JS-interop. static const int kindErased = 5; // Unary terms. - static const int kindStar = 6; - static const int kindQuestion = 7; - static const int kindFutureOr = 8; + static const int kindQuestion = 6; + static const int kindFutureOr = 7; // More complex terms. - static const int kindInterface = 9; + static const int kindInterface = 8; // A vector of type parameters from enclosing functions and closures. - static const int kindBinding = 10; - static const int kindRecord = 11; - static const int kindFunction = 12; - static const int kindGenericFunction = 13; - static const int kindGenericFunctionParameter = 14; + static const int kindBinding = 9; + static const int kindRecord = 10; + static const int kindFunction = 11; + static const int kindGenericFunction = 12; + static const int kindGenericFunctionParameter = 13; static bool _isUnionOfFunctionType(Rti rti) { int kind = Rti._getKind(rti); - if (kind == kindStar || kind == kindQuestion || kind == kindFutureOr) { + if (kind == kindQuestion || kind == kindFutureOr) { return _isUnionOfFunctionType(_Utils.asRti(_getPrimary(rti))); } return kind == kindFunction || kind == kindGenericFunction; @@ -307,11 +287,6 @@ class Rti { return JS('JSUnmodifiableArray', '#', _getRest(rti)); } - static Rti _getStarArgument(Rti rti) { - assert(_getKind(rti) == kindStar); - return _Utils.asRti(_getPrimary(rti)); - } - static Rti _getQuestionArgument(Rti rti) { assert(_getKind(rti) == kindQuestion); return _Utils.asRti(_getPrimary(rti)); @@ -398,21 +373,6 @@ class Rti { static void _setCanonicalRecipe(Rti rti, String s) { rti._canonicalRecipe = s; } - - /// Returns the canonical recipe for [rti] with the all legacy type markers - /// (* stars) erased. - static String getLegacyErasedRecipe(Rti rti) { - var s = _getCanonicalRecipe(rti); - return JS('String', '#.replace(/\\*/g, "")', s); - } -} - -// TODO(nshahan): Make private and change the argument type to rti once this -// method is no longer called from outside the library. -Rti getLegacyErasedRti(Object? rti) { - var originalType = _Utils.asRti(rti); - return Rti._getCachedRuntimeType(originalType)?._rti ?? - _createAndCacheRuntimeType(originalType)._rti; } @pragma('dart2js:types:trust') @@ -652,16 +612,6 @@ Rti _substitute(Object? universe, Rti rti, Object? typeArguments, int depth) { case Rti.kindVoid: case Rti.kindAny: return rti; - case Rti.kindStar: - Rti baseType = _Utils.asRti(Rti._getPrimary(rti)); - Rti substitutedBaseType = _substitute( - universe, - baseType, - typeArguments, - depth, - ); - if (_Utils.isIdentical(substitutedBaseType, baseType)) return rti; - return _Universe._lookupStarRti(universe, substitutedBaseType, true); case Rti.kindQuestion: Rti baseType = _Utils.asRti(Rti._getPrimary(rti)); Rti substitutedBaseType = _substitute( @@ -1172,22 +1122,11 @@ Type createRuntimeType(Rti rti) { } _Type _createAndCacheRuntimeType(Rti rti) { - final type = _createRuntimeType(rti); + final type = _Type(rti); Rti._setCachedRuntimeType(rti, type); return type; } -_Type _createRuntimeType(Rti rti) { - String recipe = Rti._getCanonicalRecipe(rti); - String starErasedRecipe = Rti.getLegacyErasedRecipe(rti); - if (starErasedRecipe == recipe) { - return _Type(rti); - } - Rti starErasedRti = _Universe.eval(_theUniverse(), starErasedRecipe, true); - return Rti._getCachedRuntimeType(starErasedRti) ?? - _createAndCacheRuntimeType(starErasedRti); -} - Rti evaluateRtiForRecord(String recordRecipe, List valuesList) { JSArray values = JS('', '#', valuesList); final length = values.length; @@ -1274,10 +1213,13 @@ bool _installSpecializedIsTest(Object? object) { if (isObjectType(testRti)) { return _finishIsFn(testRti, object, RAW_DART_FUNCTION_REF(_isObject)); } - if (isDefinitelyTopType(testRti)) { + if (isTopType(testRti)) { return _finishIsFn(testRti, object, RAW_DART_FUNCTION_REF(_isTop)); } - if (Rti._getKind(testRti) == Rti.kindQuestion) { + + int kind = Rti._getKind(testRti); + + if (kind == Rti.kindQuestion) { return _finishIsFn( testRti, object, @@ -1285,40 +1227,27 @@ bool _installSpecializedIsTest(Object? object) { ); } - // `o is T*` generally behaves like `o is T`. - // The exceptions are `Object*` (handled above) and `Never*` - // - // `null is Never` --> `false` - // `null is Never*` --> `true` - if (Rti._getKind(testRti) == Rti.kindNever) { + if (kind == Rti.kindNever) { return _finishIsFn(testRti, object, RAW_DART_FUNCTION_REF(_isNever)); } - Rti unstarred = Rti._unstar(testRti); - int unstarredKind = Rti._getKind(unstarred); - - if (unstarredKind == Rti.kindFutureOr) { + if (kind == Rti.kindFutureOr) { return _finishIsFn(testRti, object, RAW_DART_FUNCTION_REF(_isFutureOr)); } - var isFn = _simpleSpecializedIsTest(unstarred); + var isFn = _simpleSpecializedIsTest(testRti); if (isFn != null) { return _finishIsFn(testRti, object, isFn); } - if (unstarredKind == Rti.kindInterface) { - String name = Rti._getInterfaceName(unstarred); - var arguments = Rti._getInterfaceTypeArguments(unstarred); + if (kind == Rti.kindInterface) { + String name = Rti._getInterfaceName(testRti); + var arguments = Rti._getInterfaceTypeArguments(testRti); // This recognizes interface types instantiated with Top, which includes the // common case of interfaces that have no type parameters. // TODO(sra): Can we easily recognize other interface types instantiated to // bounds? - if (JS( - 'bool', - '#.every(#)', - arguments, - RAW_DART_FUNCTION_REF(isDefinitelyTopType), - )) { + if (JS('bool', '#.every(#)', arguments, RAW_DART_FUNCTION_REF(isTopType))) { Object propertyName = JS_GET_FLAG('DEV_COMPILER') // DDC uses a JavaScript symbol when tagging the type to hide them @@ -1340,8 +1269,8 @@ bool _installSpecializedIsTest(Object? object) { ); } // fall through to general implementation. - } else if (unstarredKind == Rti.kindRecord) { - isFn = _recordSpecializedIsTest(unstarred); + } else if (kind == Rti.kindRecord) { + isFn = _recordSpecializedIsTest(testRti); return _finishIsFn(testRti, object, isFn); } return _finishIsFn( @@ -1393,56 +1322,45 @@ Object? _installSpecializedAsCheck(Object? object) { Rti testRti = _Utils.asRti(JS('', 'this')); var asFn = RAW_DART_FUNCTION_REF(_generalAsCheckImplementation); - if (isDefinitelyTopType(testRti)) { + if (isTopType(testRti)) { asFn = RAW_DART_FUNCTION_REF(_asTop); } else if (isObjectType(testRti)) { asFn = RAW_DART_FUNCTION_REF(_asObject); - } else if (JS_GET_FLAG('LEGACY') || isNullable(testRti)) { + } else if (isNullable(testRti)) { asFn = RAW_DART_FUNCTION_REF(_generalNullableAsCheckImplementation); } - if (!JS_GET_FLAG('LEGACY')) { - if (_Utils.isIdentical(testRti, TYPE_REF())) { - asFn = RAW_DART_FUNCTION_REF(_asInt); - } else if (_Utils.isIdentical(testRti, TYPE_REF())) { - asFn = RAW_DART_FUNCTION_REF(_asIntQ); - } else if (_Utils.isIdentical(testRti, TYPE_REF())) { - asFn = RAW_DART_FUNCTION_REF(_asString); - } else if (_Utils.isIdentical(testRti, TYPE_REF())) { - asFn = RAW_DART_FUNCTION_REF(_asStringQ); - } else if (_Utils.isIdentical(testRti, TYPE_REF())) { - asFn = RAW_DART_FUNCTION_REF(_asBool); - } else if (_Utils.isIdentical(testRti, TYPE_REF())) { - asFn = RAW_DART_FUNCTION_REF(_asBoolQ); - } else if (_Utils.isIdentical(testRti, TYPE_REF())) { - asFn = RAW_DART_FUNCTION_REF(_asNum); - } else if (_Utils.isIdentical(testRti, TYPE_REF())) { - asFn = RAW_DART_FUNCTION_REF(_asNumQ); - } else if (_Utils.isIdentical(testRti, TYPE_REF())) { - asFn = RAW_DART_FUNCTION_REF(_asDouble); - } else if (_Utils.isIdentical(testRti, TYPE_REF())) { - asFn = RAW_DART_FUNCTION_REF(_asDoubleQ); - } + if (_Utils.isIdentical(testRti, TYPE_REF())) { + asFn = RAW_DART_FUNCTION_REF(_asInt); + } else if (_Utils.isIdentical(testRti, TYPE_REF())) { + asFn = RAW_DART_FUNCTION_REF(_asIntQ); + } else if (_Utils.isIdentical(testRti, TYPE_REF())) { + asFn = RAW_DART_FUNCTION_REF(_asString); + } else if (_Utils.isIdentical(testRti, TYPE_REF())) { + asFn = RAW_DART_FUNCTION_REF(_asStringQ); + } else if (_Utils.isIdentical(testRti, TYPE_REF())) { + asFn = RAW_DART_FUNCTION_REF(_asBool); + } else if (_Utils.isIdentical(testRti, TYPE_REF())) { + asFn = RAW_DART_FUNCTION_REF(_asBoolQ); + } else if (_Utils.isIdentical(testRti, TYPE_REF())) { + asFn = RAW_DART_FUNCTION_REF(_asNum); + } else if (_Utils.isIdentical(testRti, TYPE_REF())) { + asFn = RAW_DART_FUNCTION_REF(_asNumQ); + } else if (_Utils.isIdentical(testRti, TYPE_REF())) { + asFn = RAW_DART_FUNCTION_REF(_asDouble); + } else if (_Utils.isIdentical(testRti, TYPE_REF())) { + asFn = RAW_DART_FUNCTION_REF(_asDoubleQ); } Rti._setAsCheckFunction(testRti, asFn); return Rti._asCheck(testRti, object); } -bool _nullIs(Rti testRti) { - int kind = Rti._getKind(testRti); - return isSoundTopType(testRti) || - kind == Rti.kindQuestion || - kind == Rti.kindStar && _nullIs(Rti._getStarArgument(testRti)) || - kind == Rti.kindFutureOr && _nullIs(Rti._getFutureOrArgument(testRti)) || - isNullType(testRti); -} - /// Called from generated code. bool _generalIsTestImplementation(Object? object) { // This static method is installed on an Rti object as a JavaScript instance // method. The Rti object is 'this'. Rti testRti = _Utils.asRti(JS('', 'this')); - if (object == null) return _nullIs(testRti); + if (object == null) return isNullable(testRti); Rti objectRti = instanceOrFunctionType(object, testRti); return isSubtype(_theUniverse(), objectRti, testRti); } @@ -1467,7 +1385,7 @@ bool _isTestViaProperty(Object? object) { // This static method is installed on an Rti object as a JavaScript instance // method. The Rti object is 'this'. Rti testRti = _Utils.asRti(JS('', 'this')); - if (object == null) return _nullIs(testRti); + if (object == null) return isNullable(testRti); var tag = Rti._getSpecializedTestResource(testRti); // This test is redundant with getInterceptor below, but getInterceptor does @@ -1487,7 +1405,7 @@ bool _isListTestViaProperty(Object? object) { // This static method is installed on an Rti object as a JavaScript instance // method. The Rti object is 'this'. Rti testRti = _Utils.asRti(JS('', 'this')); - if (object == null) return _nullIs(testRti); + if (object == null) return isNullable(testRti); // Only JavaScript values with `typeof x == "object"` are Dart Lists. Other // typeof results (undefined/string/number/boolean/function/symbol/bigint) are @@ -1521,9 +1439,6 @@ Object? _generalAsCheckImplementation(Object? object) { if (isNullable(testRti)) { return object; } - if (JS_GET_FLAG('LEGACY')) { - return object; - } } else if (Rti._isCheck(testRti, object)) return object; throw _errorForAsCheck(object, testRti); @@ -1603,12 +1518,8 @@ class _TypeError extends _Error implements TypeError { /// Called from generated code via Rti `_is` method. bool _isFutureOr(Object? object) { Rti testRti = _Utils.asRti(JS('', 'this')); - Rti unstarred = Rti._unstar(testRti); - return Rti._isCheck(Rti._getFutureOrArgument(unstarred), object) || - Rti._isCheck( - Rti._getFutureFromFutureOr(_theUniverse(), unstarred), - object, - ); + return Rti._isCheck(Rti._getFutureOrArgument(testRti), object) || + Rti._isCheck(Rti._getFutureFromFutureOr(_theUniverse(), testRti), object); } /// Specialization for 'is Object'. @@ -1622,9 +1533,6 @@ bool _isObject(Object? object) { @pragma('dart2js:stack-starts-at-throw') Object? _asObject(Object? object) { if (object != null) return object; - if (JS_GET_FLAG('LEGACY')) { - return object; - } throw _TypeError.forType(object, 'Object'); } @@ -1884,7 +1792,7 @@ String _functionRtiToString( typeParametersText += typeSep; typeParametersText += genericContext[genericContext.length - 1 - i]; Rti boundRti = _Utils.asRti(_Utils.arrayAt(bounds, i)); - if (!isDefinitelyTopType(boundRti)) { + if (!isTopType(boundRti)) { typeParametersText += ' extends ' + _rtiToString(boundRti, genericContext); } @@ -1970,12 +1878,9 @@ String _functionRtiToString( /// Returns a human readable version of [rti]. /// -/// The result only differs from `createRuntimeType(rti).toString()` in that -/// this version does preserve legacy (*) information that can be printed if the -/// option is enabled. +/// The result is equivalent to `createRuntimeType(rti).toString()`. /// -/// Called by the DDC runtime library for type error messages in code that -/// supports unsound null safety features. +/// Called by the DDC runtime library for type error messages. String rtiToString(Object rti) => _rtiToString(_Utils.asRti(rti), null); String _rtiToString(Rti rti, List? genericContext) { @@ -1987,12 +1892,6 @@ String _rtiToString(Rti rti, List? genericContext) { if (kind == Rti.kindNever) return 'Never'; if (kind == Rti.kindAny) return 'any'; - if (kind == Rti.kindStar) { - Rti starArgument = Rti._getStarArgument(rti); - String s = _rtiToString(starArgument, genericContext); - return s; - } - if (kind == Rti.kindQuestion) { Rti questionArgument = Rti._getQuestionArgument(rti); String s = _rtiToString(questionArgument, genericContext); @@ -2132,11 +2031,6 @@ String _rtiToDebugString(Rti rti) { if (kind == Rti.kindNever) return 'Never'; if (kind == Rti.kindAny) return 'any'; - if (kind == Rti.kindStar) { - Rti starArgument = Rti._getStarArgument(rti); - return 'star(${_rtiToDebugString(starArgument)})'; - } - if (kind == Rti.kindQuestion) { Rti questionArgument = Rti._getQuestionArgument(rti); return 'question(${_rtiToDebugString(questionArgument)})'; @@ -2464,8 +2358,6 @@ class _Universe { static String _canonicalRecipeOfAny() => _recipeJoin(Recipe.pushAnyExtensionString, Recipe.extensionOpString); - static String _canonicalRecipeOfStar(Rti baseType) => - _recipeJoin(Rti._getCanonicalRecipe(baseType), Recipe.wrapStarString); static String _canonicalRecipeOfQuestion(Rti baseType) => _recipeJoin(Rti._getCanonicalRecipe(baseType), Recipe.wrapQuestionString); static String _canonicalRecipeOfFutureOr(Rti baseType) => @@ -2523,40 +2415,6 @@ class _Universe { return _installTypeTests(universe, rti); } - static Rti _lookupStarRti(Object? universe, Rti baseType, bool normalize) { - String key = _canonicalRecipeOfStar(baseType); - var cache = evalCache(universe); - var probe = _Utils.mapGet(cache, key); - if (probe != null) return _Utils.asRti(probe); - return _installRti( - universe, - key, - _createStarRti(universe, baseType, key, normalize), - ); - } - - static Rti _createStarRti( - Object? universe, - Rti baseType, - String key, - bool normalize, - ) { - if (normalize) { - int baseKind = Rti._getKind(baseType); - if (isSoundTopType(baseType) || - isNullType(baseType) || - baseKind == Rti.kindQuestion || - baseKind == Rti.kindStar) { - return baseType; - } - } - Rti rti = Rti.allocate(); - Rti._setKind(rti, Rti.kindStar); - Rti._setPrimary(rti, baseType); - Rti._setCanonicalRecipe(rti, key); - return _installTypeTests(universe, rti); - } - static Rti _lookupQuestionRti( Object? universe, Rti baseType, @@ -2581,7 +2439,7 @@ class _Universe { ) { if (normalize) { int baseKind = Rti._getKind(baseType); - if (isSoundTopType(baseType) || + if (isTopType(baseType) || isNullType(baseType) || baseKind == Rti.kindQuestion || baseKind == Rti.kindFutureOr && @@ -2589,15 +2447,6 @@ class _Universe { return baseType; } else if (baseKind == Rti.kindNever) { return TYPE_REF(); - } else if (baseKind == Rti.kindStar) { - Rti starArgument = Rti._getStarArgument(baseType); - int starArgumentKind = Rti._getKind(starArgument); - if (starArgumentKind == Rti.kindFutureOr && - isNullable(Rti._getFutureOrArgument(starArgument))) { - return starArgument; - } else { - return Rti._getQuestionFromStar(universe, baseType); - } } } Rti rti = Rti.allocate(); @@ -2631,7 +2480,7 @@ class _Universe { ) { if (normalize) { int baseKind = Rti._getKind(baseType); - if (isSoundTopType(baseType) || isObjectType(baseType)) { + if (isTopType(baseType) || isObjectType(baseType)) { return baseType; } else if (baseKind == Rti.kindNever) { return _lookupFutureRti(universe, baseType); @@ -3239,18 +3088,6 @@ class _Parser { handleExtendedOperations(parser, stack); break; - case Recipe.wrapStar: - var u = universe(parser); - push( - stack, - _Universe._lookupStarRti( - u, - toType(u, environment(parser), pop(stack)), - normalize(parser), - ), - ); - break; - case Recipe.wrapQuestion: var u = universe(parser); push( @@ -3643,7 +3480,7 @@ bool isSubtype(Object? universe, Rti s, Rti t) { var sCache = Rti._getIsSubtypeCache(s); var result = _Utils.asBoolOrNull(_Utils.mapGet(sCache, t)); if (result == null) { - result = _isSubtype(universe, s, null, t, null, JS_GET_FLAG('LEGACY')); + result = _isSubtype(universe, s, null, t, null); _Utils.mapSet(sCache, t, result); } return result; @@ -3664,43 +3501,28 @@ bool isSubtype(Object? universe, Rti s, Rti t) { /// check performed at the usual place in order to completely eliminate the /// case. /// - Function type rules are applied before interface type rules. -/// -/// [s] is considered a legacy subtype of [t] if [s] would be a subtype of [t] -/// in a modification of the NNBD rules in which `?` on types were ignored, `*` -/// were added to each type, and `required` parameters were treated as -/// optional. In effect, `Never` is equivalent to `Null`, `Null` is restored to -/// the bottom of the type hierarchy, `Object` is treated as nullable, and -/// `required` is ignored on named parameters. This should provide the same -/// subtyping results as pre-NNBD Dart. -bool _isSubtype( - Object? universe, - Rti s, - Object? sEnv, - Rti t, - Object? tEnv, - bool isLegacy, -) { +bool _isSubtype(Object? universe, Rti s, Object? sEnv, Rti t, Object? tEnv) { // Reflexivity: if (_Utils.isIdentical(s, t)) return true; // Right Top: - if (isTopType(t, isLegacy)) return true; + if (isTopType(t)) return true; int sKind = Rti._getKind(s); if (sKind == Rti.kindAny) return true; // Left Top: - if (isSoundTopType(s)) return false; + if (isTopType(s)) return false; // Left Bottom: - if (isBottomType(s, isLegacy)) return true; + if (isBottomType(s)) return true; // Left Type Variable Bound 1: bool leftTypeVariable = sKind == Rti.kindGenericFunctionParameter; if (leftTypeVariable) { int index = Rti._getGenericFunctionParameterIndex(s); Rti bound = _Utils.asRti(_Utils.arrayAt(sEnv, index)); - if (_isSubtype(universe, bound, sEnv, t, tEnv, isLegacy)) return true; + if (_isSubtype(universe, bound, sEnv, t, tEnv)) return true; } int tKind = Rti._getKind(t); @@ -3708,81 +3530,24 @@ bool _isSubtype( // Left Null: // Note: Interchanging the Left Null and Right Object rules allows us to // reduce casework. - if (!isLegacy && isNullType(s)) { + if (isNullType(s)) { if (tKind == Rti.kindFutureOr) { - return _isSubtype( - universe, - s, - sEnv, - Rti._getFutureOrArgument(t), - tEnv, - isLegacy, - ); + return _isSubtype(universe, s, sEnv, Rti._getFutureOrArgument(t), tEnv); } - return isNullType(t) || tKind == Rti.kindQuestion || tKind == Rti.kindStar; + return isNullType(t) || tKind == Rti.kindQuestion; } // Right Object: - if (!isLegacy && isObjectType(t)) { + if (isObjectType(t)) { if (sKind == Rti.kindFutureOr) { - return _isSubtype( - universe, - Rti._getFutureOrArgument(s), - sEnv, - t, - tEnv, - isLegacy, - ); - } - if (sKind == Rti.kindStar) { - return _isSubtype( - universe, - Rti._getStarArgument(s), - sEnv, - t, - tEnv, - isLegacy, - ); + return _isSubtype(universe, Rti._getFutureOrArgument(s), sEnv, t, tEnv); } return sKind != Rti.kindQuestion; } - // Left Legacy: - if (sKind == Rti.kindStar) { - return _isSubtype( - universe, - Rti._getStarArgument(s), - sEnv, - t, - tEnv, - isLegacy, - ); - } - - // Right Legacy: - if (tKind == Rti.kindStar) { - return _isSubtype( - universe, - s, - sEnv, - isLegacy - ? Rti._getStarArgument(t) - : Rti._getQuestionFromStar(universe, t), - tEnv, - isLegacy, - ); - } - // Left FutureOr: if (sKind == Rti.kindFutureOr) { - if (!_isSubtype( - universe, - Rti._getFutureOrArgument(s), - sEnv, - t, - tEnv, - isLegacy, - )) { + if (!_isSubtype(universe, Rti._getFutureOrArgument(s), sEnv, t, tEnv)) { return false; } return _isSubtype( @@ -3791,22 +3556,13 @@ bool _isSubtype( sEnv, t, tEnv, - isLegacy, ); } // Left Nullable: if (sKind == Rti.kindQuestion) { - return (isLegacy || - _isSubtype(universe, TYPE_REF(), sEnv, t, tEnv, isLegacy)) && - _isSubtype( - universe, - Rti._getQuestionArgument(s), - sEnv, - t, - tEnv, - isLegacy, - ); + return (_isSubtype(universe, TYPE_REF(), sEnv, t, tEnv)) && + _isSubtype(universe, Rti._getQuestionArgument(s), sEnv, t, tEnv); } // Type Variable Reflexivity 1 is subsumed by Reflexivity and therefore @@ -3816,14 +3572,7 @@ bool _isSubtype( // Right FutureOr: if (tKind == Rti.kindFutureOr) { - if (_isSubtype( - universe, - s, - sEnv, - Rti._getFutureOrArgument(t), - tEnv, - isLegacy, - )) { + if (_isSubtype(universe, s, sEnv, Rti._getFutureOrArgument(t), tEnv)) { return true; } return _isSubtype( @@ -3832,22 +3581,13 @@ bool _isSubtype( sEnv, Rti._getFutureFromFutureOr(universe, t), tEnv, - isLegacy, ); } // Right Nullable: if (tKind == Rti.kindQuestion) { - return (!isLegacy && - _isSubtype(universe, s, sEnv, TYPE_REF(), tEnv, isLegacy)) || - _isSubtype( - universe, - s, - sEnv, - Rti._getQuestionArgument(t), - tEnv, - isLegacy, - ); + return (_isSubtype(universe, s, sEnv, TYPE_REF(), tEnv)) || + _isSubtype(universe, s, sEnv, Rti._getQuestionArgument(t), tEnv); } // Left Promoted Variable does not apply at runtime. @@ -3883,8 +3623,8 @@ bool _isSubtype( for (int i = 0; i < sLength; i++) { var sBound = _Utils.asRti(_Utils.arrayAt(sBounds, i)); var tBound = _Utils.asRti(_Utils.arrayAt(tBounds, i)); - if (!_isSubtype(universe, sBound, sEnv, tBound, tEnv, isLegacy) || - !_isSubtype(universe, tBound, tEnv, sBound, sEnv, isLegacy)) { + if (!_isSubtype(universe, sBound, sEnv, tBound, tEnv) || + !_isSubtype(universe, tBound, tEnv, sBound, sEnv)) { return false; } } @@ -3895,24 +3635,23 @@ bool _isSubtype( sEnv, Rti._getGenericFunctionBase(t), tEnv, - isLegacy, ); } if (tKind == Rti.kindFunction) { if (isJsFunctionType(s)) return true; if (sKind != Rti.kindFunction) return false; - return _isFunctionSubtype(universe, s, sEnv, t, tEnv, isLegacy); + return _isFunctionSubtype(universe, s, sEnv, t, tEnv); } // Interface Compositionality + Super-Interface: if (sKind == Rti.kindInterface) { if (tKind != Rti.kindInterface) return false; - return _isInterfaceSubtype(universe, s, sEnv, t, tEnv, isLegacy); + return _isInterfaceSubtype(universe, s, sEnv, t, tEnv); } // Record Types: if (sKind == Rti.kindRecord && tKind == Rti.kindRecord) { - return _isRecordSubtype(universe, s, sEnv, t, tEnv, isLegacy); + return _isRecordSubtype(universe, s, sEnv, t, tEnv); } return false; @@ -3924,14 +3663,13 @@ bool _isFunctionSubtype( Object? sEnv, Rti t, Object? tEnv, - bool isLegacy, ) { assert(Rti._getKind(s) == Rti.kindFunction); assert(Rti._getKind(t) == Rti.kindFunction); Rti sReturnType = Rti._getReturnType(s); Rti tReturnType = Rti._getReturnType(t); - if (!_isSubtype(universe, sReturnType, sEnv, tReturnType, tEnv, isLegacy)) { + if (!_isSubtype(universe, sReturnType, sEnv, tReturnType, tEnv)) { return false; } @@ -3965,7 +3703,7 @@ bool _isFunctionSubtype( for (int i = 0; i < sRequiredPositionalLength; i++) { Rti sParameter = _Utils.asRti(_Utils.arrayAt(sRequiredPositional, i)); Rti tParameter = _Utils.asRti(_Utils.arrayAt(tRequiredPositional, i)); - if (!_isSubtype(universe, tParameter, tEnv, sParameter, sEnv, isLegacy)) { + if (!_isSubtype(universe, tParameter, tEnv, sParameter, sEnv)) { return false; } } @@ -3975,7 +3713,7 @@ bool _isFunctionSubtype( Rti tParameter = _Utils.asRti( _Utils.arrayAt(tRequiredPositional, sRequiredPositionalLength + i), ); - if (!_isSubtype(universe, tParameter, tEnv, sParameter, sEnv, isLegacy)) { + if (!_isSubtype(universe, tParameter, tEnv, sParameter, sEnv)) { return false; } } @@ -3985,7 +3723,7 @@ bool _isFunctionSubtype( _Utils.arrayAt(sOptionalPositional, requiredPositionalDelta + i), ); Rti tParameter = _Utils.asRti(_Utils.arrayAt(tOptionalPositional, i)); - if (!_isSubtype(universe, tParameter, tEnv, sParameter, sEnv, isLegacy)) { + if (!_isSubtype(universe, tParameter, tEnv, sParameter, sEnv)) { return false; } } @@ -4003,27 +3741,22 @@ bool _isFunctionSubtype( String sName = _Utils.asString(_Utils.arrayAt(sNamed, sIndex)); sIndex += 3; if (_Utils.stringLessThan(tName, sName)) return false; - bool sIsRequired = - !isLegacy && _Utils.asBool(_Utils.arrayAt(sNamed, sIndex - 2)); + bool sIsRequired = _Utils.asBool(_Utils.arrayAt(sNamed, sIndex - 2)); if (_Utils.stringLessThan(sName, tName)) { if (sIsRequired) return false; continue; } - bool tIsRequired = - !isLegacy && _Utils.asBool(_Utils.arrayAt(tNamed, tIndex + 1)); + bool tIsRequired = _Utils.asBool(_Utils.arrayAt(tNamed, tIndex + 1)); if (sIsRequired && !tIsRequired) return false; Rti sType = _Utils.asRti(_Utils.arrayAt(sNamed, sIndex - 1)); Rti tType = _Utils.asRti(_Utils.arrayAt(tNamed, tIndex + 2)); - if (!_isSubtype(universe, tType, tEnv, sType, sEnv, isLegacy)) - return false; + if (!_isSubtype(universe, tType, tEnv, sType, sEnv)) return false; break; } } - if (!isLegacy) { - while (sIndex < sNamedLength) { - if (_Utils.asBool(_Utils.arrayAt(sNamed, sIndex + 1))) return false; - sIndex += 3; - } + while (sIndex < sNamedLength) { + if (_Utils.asBool(_Utils.arrayAt(sNamed, sIndex + 1))) return false; + sIndex += 3; } return true; } @@ -4034,7 +3767,6 @@ bool _isInterfaceSubtype( Object? sEnv, Rti t, Object? tEnv, - bool isLegacy, ) { String sName = Rti._getInterfaceName(s); String tName = Rti._getInterfaceName(t); @@ -4075,7 +3807,6 @@ bool _isInterfaceSubtype( sEnv, tArgs, tEnv, - isLegacy, ); } @@ -4087,15 +3818,7 @@ bool _isInterfaceSubtype( if (JS_GET_FLAG("VARIANCE")) { sVariances = _Universe.findTypeParameterVariances(universe, sName); } - return _areArgumentsSubtypes( - universe, - sArgs, - sVariances, - sEnv, - tArgs, - tEnv, - isLegacy, - ); + return _areArgumentsSubtypes(universe, sArgs, sVariances, sEnv, tArgs, tEnv); } bool _areArgumentsSubtypes( @@ -4105,7 +3828,6 @@ bool _areArgumentsSubtypes( Object? sEnv, Object? tArgs, Object? tEnv, - bool isLegacy, ) { int length = _Utils.arrayLength(sArgs); assert(length == _Utils.arrayLength(tArgs)); @@ -4127,18 +3849,18 @@ bool _areArgumentsSubtypes( switch (sVariance) { case Variance.legacyCovariant: case Variance.covariant: - if (!_isSubtype(universe, sArg, sEnv, tArg, tEnv, isLegacy)) { + if (!_isSubtype(universe, sArg, sEnv, tArg, tEnv)) { return false; } break; case Variance.contravariant: - if (!_isSubtype(universe, tArg, tEnv, sArg, sEnv, isLegacy)) { + if (!_isSubtype(universe, tArg, tEnv, sArg, sEnv)) { return false; } break; case Variance.invariant: - if (!_isSubtype(universe, sArg, sEnv, tArg, tEnv, isLegacy) || - !_isSubtype(universe, tArg, tEnv, sArg, sEnv, isLegacy)) { + if (!_isSubtype(universe, sArg, sEnv, tArg, tEnv) || + !_isSubtype(universe, tArg, tEnv, sArg, sEnv)) { return false; } break; @@ -4148,7 +3870,7 @@ bool _areArgumentsSubtypes( ); } } else { - if (!_isSubtype(universe, sArg, sEnv, tArg, tEnv, isLegacy)) { + if (!_isSubtype(universe, sArg, sEnv, tArg, tEnv)) { return false; } } @@ -4162,7 +3884,6 @@ bool _isRecordSubtype( Object? sEnv, Rti t, Object? tEnv, - bool isLegacy, ) { // `s` is a subtype of `t` if `s` and `t` have the same shape and the fields // of `s` are pairwise subtypes of the fields of `t`. @@ -4178,7 +3899,7 @@ bool _isRecordSubtype( for (int i = 0; i < sCount; i++) { Rti sField = _Utils.asRti(_Utils.arrayAt(sFields, i)); Rti tField = _Utils.asRti(_Utils.arrayAt(tFields, i)); - if (!_isSubtype(universe, sField, sEnv, tField, tEnv, isLegacy)) { + if (!_isSubtype(universe, sField, sEnv, tField, tEnv)) { return false; } } @@ -4188,28 +3909,13 @@ bool _isRecordSubtype( bool isNullable(Rti t) { int kind = Rti._getKind(t); return isNullType(t) || - isSoundTopType(t) || + isTopType(t) || kind == Rti.kindQuestion || - kind == Rti.kindStar && isNullable(Rti._getStarArgument(t)) || kind == Rti.kindFutureOr && isNullable(Rti._getFutureOrArgument(t)); } -/// A wrapper for [isTopType] which only returns `true` if [t] is a top type for -/// all null safety modes that may be used. -/// -/// In particular, when extra runtime null safety checks are disabled, this -/// function simply passes the usual null safety mode. When extra checks are -/// enabled - i.e. both unsound and sound semantics may be used - this function -/// only returns `true` for sound top types. This means this function can be -/// used to detect top types in order to optimize type tests. @pragma('dart2js:parameter:trust') -bool isDefinitelyTopType(Rti t) => isTopType(t, JS_GET_FLAG('LEGACY')); - -@pragma('dart2js:parameter:trust') -bool isTopType(Rti t, bool isLegacy) => - isSoundTopType(t) || isLegacy && isObjectType(t); - -bool isSoundTopType(Rti t) { +bool isTopType(Rti t) { int kind = Rti._getKind(t); return kind == Rti.kindDynamic || kind == Rti.kindVoid || @@ -4218,8 +3924,7 @@ bool isSoundTopType(Rti t) { isNullableObjectType(t); } -bool isBottomType(Rti t, bool isLegacy) => - Rti._getKind(t) == Rti.kindNever || isLegacy && isNullType(t); +bool isBottomType(Rti t) => Rti._getKind(t) == Rti.kindNever; bool isObjectType(Rti t) => _Utils.isIdentical(t, TYPE_REF()); bool isNullableObjectType(Rti t) => _Utils.isIdentical(t, TYPE_REF()); diff --git a/sdk/lib/_internal/js_shared/lib/synced/recipe_syntax.dart b/sdk/lib/_internal/js_shared/lib/synced/recipe_syntax.dart index 64d91cd3f90..58cf39c7f8f 100644 --- a/sdk/lib/_internal/js_shared/lib/synced/recipe_syntax.dart +++ b/sdk/lib/_internal/js_shared/lib/synced/recipe_syntax.dart @@ -28,8 +28,6 @@ abstract class Recipe { static const int pushVoid = _tilde; static const String pushVoidString = _tildeString; - static const int wrapStar = _asterisk; - static const String wrapStarString = _asteriskString; static const int wrapQuestion = _question; static const String wrapQuestionString = _questionString; static const int wrapFutureOr = _slash; @@ -187,7 +185,6 @@ abstract class Recipe { test("pushErased", pushErased, pushErasedString); test("pushDynamic", pushDynamic, pushDynamicString); test("pushVoid", pushVoid, pushVoidString); - test("wrapStar", wrapStar, wrapStarString); test("wrapQuestion", wrapQuestion, wrapQuestionString); test("wrapFutureOr", wrapFutureOr, wrapFutureOrString); test("startTypeArguments", startTypeArguments, startTypeArgumentsString);