blob: 51e0c755ff82f355b57c2b0cfed8214fd7086b6e [file] [log] [blame]
// Copyright (c) 2019, 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.
// @dart = 2.6
import 'dart:_runtime' show typeRep;
import 'dart:async' show FutureOr;
import 'runtime_utils.dart';
class A {}
class B extends A {}
class C extends B {}
class D<T extends B> {}
class E<T, S> {}
class F extends E<B, B> {}
void main() {
// A <: dynamic
checkProperSubtype(typeRep<A>(), typeRep<dynamic>());
// A <: Object
checkProperSubtype(typeRep<A>(), typeRep<Object>());
// A <: Object
checkProperSubtype(typeRep<A>(), typeRep<void>());
// Null <: A
checkProperSubtype(typeRep<Null>(), typeRep<A>());
// FutureOr<Null> <: Future<Null>
checkSubtype(typeRep<FutureOr<Null>>(), typeRep<Future<Null>>());
// Future<Null> <: FutureOr<Null>
checkSubtype(typeRep<Future<Null>>(), typeRep<FutureOr<Null>>());
// Future<B> <: FutureOr<A>
checkProperSubtype(typeRep<Future<B>>(), typeRep<FutureOr<A>>());
// B <: <: FutureOr<A>
checkProperSubtype(typeRep<B>(), typeRep<FutureOr<A>>());
// Future<B> <: Future<A>
checkProperSubtype(typeRep<Future<B>>(), typeRep<Future<A>>());
// B <: A
checkProperSubtype(typeRep<B>(), typeRep<A>());
// A <: A
checkSubtype(typeRep<A>(), typeRep<A>());
// C <: B
checkProperSubtype(typeRep<C>(), typeRep<B>());
// C <: A
checkProperSubtype(typeRep<C>(), typeRep<A>());
// A -> B <: Function
checkProperSubtype(typeRep<B Function(A)>(), typeRep<Function>());
// A -> B <: A -> B
checkSubtype(typeRep<B Function(A)>(), typeRep<B Function(A)>());
// A -> B <: B -> B
checkProperSubtype(typeRep<B Function(A)>(), typeRep<B Function(B)>());
// A -> B <: A -> A
checkSubtype(typeRep<B Function(A)>(), typeRep<A Function(A)>());
// Generic Function Subtypes.
// Bound is a built in type.
// <T extends int> void -> void <: <T extends int> void -> void
checkSubtype(
genericFunction(typeRep<int>()), genericFunction(typeRep<int>()));
// <T extends String> A -> T <: <T extends String> B -> T
checkProperSubtype(functionGenericReturn(typeRep<String>(), typeRep<A>()),
functionGenericReturn(typeRep<String>(), typeRep<B>()));
// <T extends double> T -> B <: <T extends double> T -> A
checkProperSubtype(functionGenericArg(typeRep<double>(), typeRep<B>()),
functionGenericArg(typeRep<double>(), typeRep<A>()));
// Bound is a function type.
// <T extends A -> B> void -> void <: <T extends A -> B> void -> void
checkSubtype(genericFunction(typeRep<B Function(A)>()),
genericFunction(typeRep<B Function(A)>()));
// <T extends A -> B> A -> T <: <T extends A -> B> B -> T
checkProperSubtype(
functionGenericReturn(typeRep<B Function(A)>(), typeRep<A>()),
functionGenericReturn(typeRep<B Function(A)>(), typeRep<B>()));
// <T extends A -> B> T -> B <: <T extends A -> B> T -> A
checkProperSubtype(functionGenericArg(typeRep<B Function(A)>(), typeRep<B>()),
functionGenericArg(typeRep<B Function(A)>(), typeRep<A>()));
// Bound is a user defined class.
// <T extends B> void -> void <: <T extends B> void -> void
checkSubtype(genericFunction(typeRep<B>()), genericFunction(typeRep<B>()));
// <T extends B> A -> T <: <T extends B> B -> T
checkProperSubtype(functionGenericReturn(typeRep<B>(), typeRep<A>()),
functionGenericReturn(typeRep<B>(), typeRep<B>()));
// <T extends B> T -> B <: <T extends B> T -> A
checkProperSubtype(functionGenericArg(typeRep<B>(), typeRep<B>()),
functionGenericArg(typeRep<B>(), typeRep<A>()));
// Bound is a Future.
// <T extends Future<B>> void -> void <: <T extends Future<B>> void -> void
checkSubtype(genericFunction(typeRep<Future<B>>()),
genericFunction(typeRep<Future<B>>()));
// <T extends Future<B>> A -> T <: <T extends Future<B>> B -> T
checkProperSubtype(functionGenericReturn(typeRep<Future<B>>(), typeRep<A>()),
functionGenericReturn(typeRep<Future<B>>(), typeRep<B>()));
// <T extends Future<B>> T -> B <: <T extends Future<B>> T -> A
checkProperSubtype(functionGenericArg(typeRep<Future<B>>(), typeRep<B>()),
functionGenericArg(typeRep<Future<B>>(), typeRep<A>()));
// Bound is a FutureOr.
// <T extends FutureOr<B>> void -> void <:
// <T extends FutureOr<B>> void -> void
checkSubtype(genericFunction(typeRep<FutureOr<B>>()),
genericFunction(typeRep<FutureOr<B>>()));
// <T extends FutureOr<B>> A -> T <: <T extends FutureOr<B>> B -> T
checkProperSubtype(
functionGenericReturn(typeRep<FutureOr<B>>(), typeRep<A>()),
functionGenericReturn(typeRep<FutureOr<B>>(), typeRep<B>()));
// <T extends FutureOr<B>> T -> B <: <T extends FutureOr<B>> T -> A
checkProperSubtype(functionGenericArg(typeRep<FutureOr<B>>(), typeRep<B>()),
functionGenericArg(typeRep<FutureOr<B>>(), typeRep<A>()));
// D <: D<B>
checkSubtype(typeRep<D>(), typeRep<D<B>>());
// D<B> <: D
checkSubtype(typeRep<D<B>>(), typeRep<D>());
// D<C> <: D<B>
checkSubtype(typeRep<D<C>>(), typeRep<D<B>>());
// F <: E
checkProperSubtype(typeRep<F>(), typeRep<E>());
// F <: E<A, A>
checkProperSubtype(typeRep<F>(), typeRep<E<A, A>>());
// E<B, B> <: E
checkProperSubtype(typeRep<E<B, B>>(), typeRep<E>());
// // E<B, B> <: E<A, A>
checkProperSubtype(typeRep<E<B, B>>(), typeRep<E<A, A>>());
}