mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:19:48 +00:00
e736495eb7
Change-Id: I464275799b3e7a21326d35503b776f9c1101a599 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/141764 Commit-Queue: Bob Nystrom <rnystrom@google.com> Reviewed-by: Bob Nystrom <rnystrom@google.com> Reviewed-by: Erik Ernst <eernst@google.com> Auto-Submit: Bob Nystrom <rnystrom@google.com>
141 lines
4.2 KiB
Dart
141 lines
4.2 KiB
Dart
// 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.
|
|
|
|
import "package:expect/expect.dart";
|
|
|
|
R constFunction<T, R>(T _) => throw "uncalled";
|
|
|
|
C<T> getC<T>() => const C(constFunction);
|
|
|
|
List<T> getList<T>() => const [];
|
|
|
|
Set<T> getSet<T>() => const {};
|
|
|
|
Map<K, V> getMap<K, V>() => const {};
|
|
|
|
R Function(T) getFunction<T, R>() {
|
|
List<R Function(T)> list = const [constFunction];
|
|
return list[0];
|
|
}
|
|
|
|
C<T> getImplicitConstC<T>() {
|
|
List<C<T>> list = const [C(constFunction)];
|
|
return list[0];
|
|
}
|
|
|
|
List<T> getImplicitConstList<T>() {
|
|
List<List<T>> list = const [[]];
|
|
return list[0];
|
|
}
|
|
|
|
Set<T> getImplicitConstSet<T>() {
|
|
List<Set<T>> list = const [{}];
|
|
return list[0];
|
|
}
|
|
|
|
Map<K, V> getImplicitConstMap<K, V>() {
|
|
List<Map<K, V>> list = const [{}];
|
|
return list[0];
|
|
}
|
|
|
|
class C<T> {
|
|
final Object fn;
|
|
const C(T Function(T) this.fn);
|
|
}
|
|
|
|
void expectOfType<T>(Object obj) {
|
|
// An exact type test would be better, but since `Never` is a subtype of all
|
|
// types that can be written in Dart, it should not matter in practice.
|
|
//
|
|
// (`obj.runtimeType == T` does not work for List/Map/Sets because the runtime
|
|
// type is an implementation-specific subtype of those interfaces.)
|
|
Expect.isTrue(obj is T, "`$obj` should be of type `$T`");
|
|
}
|
|
|
|
testClassInstance() {
|
|
expectOfType<C<Never>>(getC<int>());
|
|
expectOfType<C<Never>>(getC<String>());
|
|
expectOfType<C<Never>>(getC());
|
|
}
|
|
|
|
testImplicitConstClassInstance() {
|
|
expectOfType<C<Never>>(getImplicitConstC<int>());
|
|
expectOfType<C<Never>>(getImplicitConstC<String>());
|
|
expectOfType<C<Never>>(getImplicitConstC());
|
|
}
|
|
|
|
testDownwardsClassInference() {
|
|
expectOfType<Never Function(Never)>(getC<int>().fn);
|
|
expectOfType<Never Function(Never)>(getC<String>().fn);
|
|
expectOfType<Never Function(Never)>(getC().fn);
|
|
}
|
|
|
|
testList() {
|
|
expectOfType<List<Never>>(getList<int>());
|
|
expectOfType<List<Never>>(getList<String>());
|
|
expectOfType<List<Never>>(getList());
|
|
}
|
|
|
|
testImplicitConstList() {
|
|
expectOfType<List<Never>>(getImplicitConstList<int>());
|
|
expectOfType<List<Never>>(getImplicitConstList<String>());
|
|
expectOfType<List<Never>>(getImplicitConstList());
|
|
}
|
|
|
|
testImplicitConstSet() {
|
|
expectOfType<Set<Never>>(getImplicitConstSet<int>());
|
|
expectOfType<Set<Never>>(getImplicitConstSet<String>());
|
|
expectOfType<Set<Never>>(getImplicitConstSet());
|
|
}
|
|
|
|
testSet() {
|
|
expectOfType<Set<Never>>(getSet<int>());
|
|
expectOfType<Set<Never>>(getSet<String>());
|
|
expectOfType<Set<Never>>(getSet());
|
|
}
|
|
|
|
testMap() {
|
|
expectOfType<Map<Never, Never>>(getMap<int, int>());
|
|
expectOfType<Map<Never, Never>>(getMap<int, String>());
|
|
expectOfType<Map<Never, Never>>(getMap<String, int>());
|
|
expectOfType<Map<Never, Never>>(getMap<String, String>());
|
|
expectOfType<Map<Never, Never>>(getMap<Never, Never>());
|
|
expectOfType<Map<Never, Never>>(getMap());
|
|
}
|
|
|
|
testImplicitConstMap() {
|
|
expectOfType<Map<Never, Never>>(getImplicitConstMap<int, int>());
|
|
expectOfType<Map<Never, Never>>(getImplicitConstMap<int, String>());
|
|
expectOfType<Map<Never, Never>>(getImplicitConstMap<String, int>());
|
|
expectOfType<Map<Never, Never>>(getImplicitConstMap<String, String>());
|
|
expectOfType<Map<Never, Never>>(getImplicitConstMap<Never, Never>());
|
|
expectOfType<Map<Never, Never>>(getImplicitConstMap());
|
|
}
|
|
|
|
testFunction() {
|
|
expectOfType<Never Function(Object?)>(getFunction<int, int>());
|
|
expectOfType<Never Function(Object?)>(getFunction<int, String>());
|
|
expectOfType<Never Function(Object?)>(getFunction<String, int>());
|
|
expectOfType<Never Function(Object?)>(getFunction<String, String>());
|
|
expectOfType<Never Function(Object?)>(getFunction<Never, Never>());
|
|
expectOfType<Never Function(Object?)>(getFunction());
|
|
}
|
|
|
|
/// Tests that use type inference for constants do not reference the type
|
|
/// parameter. Instead, free type parameters are substituted to obtain the
|
|
/// least closure (e.g. `List<T>` becomes `List<Never>` and `R Function(T)`
|
|
/// becomes `Never Function(Object)`).
|
|
main() {
|
|
testClassInstance();
|
|
testImplicitConstClassInstance();
|
|
testDownwardsClassInference();
|
|
testList();
|
|
testImplicitConstList();
|
|
testSet();
|
|
testImplicitConstSet();
|
|
testMap();
|
|
testImplicitConstMap();
|
|
testFunction();
|
|
}
|