// Copyright (c) 2020, 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. // Requirements=nnbd-strong import 'dart:_foreign_helper' show LEGACY_TYPE_REF, TYPE_REF; import 'dart:async' show FutureOr; import 'runtime_utils.dart' show checkSubtype, checkProperSubtype, checkMutualSubtype, checkSubtypeFailure; class A {} class B extends A {} class C extends B {} class D {} class E {} class F extends E {} void main() { // Top type symmetry. // Object? <:> dynamic checkMutualSubtype(TYPE_REF(), TYPE_REF()); // Object? <:> void checkMutualSubtype(TYPE_REF(), TYPE_REF()); // void <:> dynamic checkMutualSubtype(TYPE_REF(), TYPE_REF()); // Bottom is subtype of top. // Never <: dynamic checkProperSubtype(TYPE_REF(), TYPE_REF()); // Never <: void checkProperSubtype(TYPE_REF(), TYPE_REF()); // Never <: Object? checkProperSubtype(TYPE_REF(), TYPE_REF()); // Object is between top and bottom. // Object <: Object? checkSubtype(TYPE_REF(), TYPE_REF()); // Never <: Object checkProperSubtype(TYPE_REF(), TYPE_REF()); // Null is between top and bottom. // Null <: Object? checkProperSubtype(TYPE_REF(), TYPE_REF()); // Never <: Null checkProperSubtype(TYPE_REF(), TYPE_REF()); // Class is between Object and bottom. // A <: Object checkProperSubtype(TYPE_REF(), TYPE_REF()); // Never <: A checkProperSubtype(TYPE_REF(), TYPE_REF()); // Nullable types are a union of T and Null. // A <: A? checkProperSubtype(TYPE_REF(), TYPE_REF()); // Null <: A? checkProperSubtype(TYPE_REF(), TYPE_REF()); // A? <: Object? checkProperSubtype(TYPE_REF(), TYPE_REF()); // Legacy types will eventually be migrated to T or T? but until then are // symmetric with both. // Object* <:> Object checkMutualSubtype(LEGACY_TYPE_REF(), TYPE_REF()); // Object* <:> Object? checkMutualSubtype(LEGACY_TYPE_REF(), TYPE_REF()); // Bottom Types // Null <: Object* checkSubtype(TYPE_REF(), LEGACY_TYPE_REF()); // Never <: Object* checkSubtype(TYPE_REF(), LEGACY_TYPE_REF()); // A* <:> A checkMutualSubtype(LEGACY_TYPE_REF(), TYPE_REF()); // A* <:> A? checkMutualSubtype(LEGACY_TYPE_REF(), TYPE_REF()); // A* <: Object checkProperSubtype(LEGACY_TYPE_REF(), TYPE_REF()); // A* <: Object? checkProperSubtype(LEGACY_TYPE_REF(), TYPE_REF()); // Null <: A* checkProperSubtype(TYPE_REF(), LEGACY_TYPE_REF()); // Never <: A* checkProperSubtype(TYPE_REF(), LEGACY_TYPE_REF()); // Futures. // Null <: FutureOr checkProperSubtype(TYPE_REF(), TYPE_REF>()); // Object <: FutureOr checkProperSubtype(TYPE_REF(), TYPE_REF>()); // Object? <:> FutureOr checkMutualSubtype(TYPE_REF(), TYPE_REF>()); // Object <:> FutureOr checkMutualSubtype(TYPE_REF(), TYPE_REF>()); // Object <: FutureOr checkProperSubtype(TYPE_REF(), TYPE_REF>()); // Object <: FutureOr checkProperSubtype(TYPE_REF(), TYPE_REF>()); // Future <: FutureOr checkProperSubtype(TYPE_REF>(), TYPE_REF>()); // Future <: FutureOr checkProperSubtype( TYPE_REF>(), TYPE_REF>()); // FutureOr <: Future checkSubtype(TYPE_REF>(), TYPE_REF>()); // Future <: FutureOr checkProperSubtype(TYPE_REF>(), TYPE_REF>()); // B <: <: FutureOr checkProperSubtype(TYPE_REF(), TYPE_REF>()); // Future <: Future checkProperSubtype(TYPE_REF>(), TYPE_REF>()); // Interface subtypes. // A <: A checkSubtype(TYPE_REF(), TYPE_REF()); // B <: A checkProperSubtype(TYPE_REF(), TYPE_REF()); // C <: B checkProperSubtype(TYPE_REF(), TYPE_REF()); // C <: A checkProperSubtype(TYPE_REF(), TYPE_REF()); // Functions. // A -> B <: Function checkProperSubtype(TYPE_REF(), TYPE_REF()); // A -> B <: A -> B checkSubtype(TYPE_REF(), TYPE_REF()); // A -> B <: B -> B checkProperSubtype(TYPE_REF(), TYPE_REF()); // A -> B <: A -> A checkProperSubtype(TYPE_REF(), TYPE_REF()); // Generic Function Subtypes. // Bound is a built in type. // void -> void <: void -> void checkSubtype(TYPE_REF()>(), TYPE_REF()>()); // A -> T <: B -> T checkProperSubtype(TYPE_REF(A)>(), TYPE_REF(B)>()); // T -> B <: T -> A checkProperSubtype(TYPE_REF(T)>(), TYPE_REF(T)>()); // Bound is a function type. // B> void -> void <: B> void -> void checkSubtype(TYPE_REF()>(), TYPE_REF()>()); // B> A -> T <: B> B -> T checkProperSubtype(TYPE_REF(A)>(), TYPE_REF(B)>()); // B> T -> B <: B> T -> A checkProperSubtype(TYPE_REF(T)>(), TYPE_REF(T)>()); // Bound is a user defined class. // void -> void <: void -> void checkSubtype(TYPE_REF()>(), TYPE_REF()>()); // A -> T <: B -> T checkProperSubtype(TYPE_REF(A)>(), TYPE_REF(B)>()); // // T -> B <: T -> A checkProperSubtype(TYPE_REF(T)>(), TYPE_REF(T)>()); // Bound is a Future. // > void -> void <: > void -> void checkSubtype(TYPE_REF>()>(), TYPE_REF>()>()); // > A -> T <: > B -> T checkProperSubtype(TYPE_REF>(A)>(), TYPE_REF>(B)>()); // > T -> B <: > T -> A checkProperSubtype(TYPE_REF>(T)>(), TYPE_REF>(T)>()); // Bound is a FutureOr. // > void -> void <: // > void -> void checkSubtype(TYPE_REF>()>(), TYPE_REF>()>()); // > A -> T <: > B -> T checkProperSubtype(TYPE_REF>(A)>(), TYPE_REF>(B)>()); // > T -> B <: > T -> A checkProperSubtype(TYPE_REF>(T)>(), TYPE_REF>(T)>()); // Generics. // D <:> D checkMutualSubtype(TYPE_REF(), TYPE_REF>()); // D <: D checkProperSubtype(TYPE_REF>(), TYPE_REF>()); // F <: E checkProperSubtype(TYPE_REF(), TYPE_REF()); // F <: E checkProperSubtype(TYPE_REF(), TYPE_REF>()); // E <: E checkProperSubtype(TYPE_REF>(), TYPE_REF()); // E <: E checkProperSubtype(TYPE_REF>(), TYPE_REF>()); // Nullable interface subtypes. // B <: A? checkProperSubtype(TYPE_REF(), TYPE_REF()); // C <: A? checkProperSubtype(TYPE_REF(), TYPE_REF()); // B? <: A? checkProperSubtype(TYPE_REF(), TYPE_REF()); // C? <: A? checkProperSubtype(TYPE_REF(), TYPE_REF()); // Mixed mode. // B* <: A checkProperSubtype(LEGACY_TYPE_REF(), TYPE_REF()); // B* <: A? checkProperSubtype(LEGACY_TYPE_REF(), TYPE_REF()); // A* <\: B checkSubtypeFailure(LEGACY_TYPE_REF(), TYPE_REF()); // B? <: A* checkProperSubtype(TYPE_REF(), LEGACY_TYPE_REF()); // B <: A* checkProperSubtype(TYPE_REF(), LEGACY_TYPE_REF()); // A <: B* checkSubtypeFailure(TYPE_REF(), LEGACY_TYPE_REF()); // A? <: B* checkSubtypeFailure(TYPE_REF(), LEGACY_TYPE_REF()); // Allowed in weak mode. // dynamic <\: Object checkSubtypeFailure(TYPE_REF(), TYPE_REF()); // void <\: Object checkSubtypeFailure(TYPE_REF(), TYPE_REF()); // Object? <\: Object checkSubtypeFailure(TYPE_REF(), TYPE_REF()); // A? <\: Object checkSubtypeFailure(TYPE_REF(), TYPE_REF()); // A? <\: A checkSubtypeFailure(TYPE_REF(), TYPE_REF()); // Null <\: Never checkSubtypeFailure(TYPE_REF(), TYPE_REF()); // Null <\: Object checkSubtypeFailure(TYPE_REF(), TYPE_REF()); // Null <\: A checkSubtypeFailure(TYPE_REF(), TYPE_REF()); // Null <\: FutureOr checkSubtypeFailure(TYPE_REF(), TYPE_REF>()); // Null <\: Future checkSubtypeFailure(TYPE_REF(), TYPE_REF>()); // FutureOr <\: Future checkSubtypeFailure(TYPE_REF>(), TYPE_REF>()); // Null <\: Future checkSubtypeFailure(TYPE_REF(), TYPE_REF>()); // FutureOr <\: Object checkSubtypeFailure(TYPE_REF>(), TYPE_REF()); // FutureOr <\: Object checkSubtypeFailure(TYPE_REF>(), TYPE_REF()); // FutureOr <\: Object checkSubtypeFailure(TYPE_REF>(), TYPE_REF()); }