Files
sdk/tests/language_2/const_inference_test.dart
T
Jenny Messerly da4ccd0855 [analyzer] fix #32918, eliminate type variables during const inference
This brings Analyzer's type inference in line with the language spec.
Similar to CFE, the inference function now takes an isConst parameter,
which if set, tells it to eliminate type variables from the context
type.

Change-Id: Ied67bac39d73c9ecd7e0a482a0c8db77272637cc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/98707
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Jenny Messerly <jmesserly@google.com>
2019-04-05 19:30:54 +00:00

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 _) => null;
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 `Null` is a subtype of all
// types that can be written in Dart 2.0, 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<Null>>(getC<int>());
expectOfType<C<Null>>(getC<String>());
expectOfType<C<Null>>(getC());
}
testImplicitConstClassInstance() {
expectOfType<C<Null>>(getImplicitConstC<int>());
expectOfType<C<Null>>(getImplicitConstC<String>());
expectOfType<C<Null>>(getImplicitConstC());
}
testDownwardsClassInference() {
expectOfType<Null Function(Null)>(getC<int>().fn);
expectOfType<Null Function(Null)>(getC<String>().fn);
expectOfType<Null Function(Null)>(getC().fn);
}
testList() {
expectOfType<List<Null>>(getList<int>());
expectOfType<List<Null>>(getList<String>());
expectOfType<List<Null>>(getList());
}
testImplicitConstList() {
expectOfType<List<Null>>(getImplicitConstList<int>());
expectOfType<List<Null>>(getImplicitConstList<String>());
expectOfType<List<Null>>(getImplicitConstList());
}
testImplicitConstSet() {
expectOfType<Set<Null>>(getImplicitConstSet<int>());
expectOfType<Set<Null>>(getImplicitConstSet<String>());
expectOfType<Set<Null>>(getImplicitConstSet());
}
testSet() {
expectOfType<Set<Null>>(getSet<int>());
expectOfType<Set<Null>>(getSet<String>());
expectOfType<Set<Null>>(getSet());
}
testMap() {
expectOfType<Map<Null, Null>>(getMap<int, int>());
expectOfType<Map<Null, Null>>(getMap<int, String>());
expectOfType<Map<Null, Null>>(getMap<String, int>());
expectOfType<Map<Null, Null>>(getMap<String, String>());
expectOfType<Map<Null, Null>>(getMap<Null, Null>());
expectOfType<Map<Null, Null>>(getMap());
}
testImplicitConstMap() {
expectOfType<Map<Null, Null>>(getImplicitConstMap<int, int>());
expectOfType<Map<Null, Null>>(getImplicitConstMap<int, String>());
expectOfType<Map<Null, Null>>(getImplicitConstMap<String, int>());
expectOfType<Map<Null, Null>>(getImplicitConstMap<String, String>());
expectOfType<Map<Null, Null>>(getImplicitConstMap<Null, Null>());
expectOfType<Map<Null, Null>>(getImplicitConstMap());
}
testFunction() {
expectOfType<Null Function(Object)>(getFunction<int, int>());
expectOfType<Null Function(Object)>(getFunction<int, String>());
expectOfType<Null Function(Object)>(getFunction<String, int>());
expectOfType<Null Function(Object)>(getFunction<String, String>());
expectOfType<Null Function(Object)>(getFunction<Null, Null>());
expectOfType<Null Function(Object)>(getFunction());
}
/// Tests that type inference for constants does not reference the type
/// parameter. Instead, free type parameters should substituted to obtain the
/// least closure (e.g. `List<T>` becomes `List<Null>` and `R Function(T)`
/// becomes `Null Function(Object)`).
main() {
testClassInstance();
testImplicitConstClassInstance();
testDownwardsClassInference();
testList();
testImplicitConstList();
testSet();
testImplicitConstSet();
testMap();
testImplicitConstMap();
testFunction();
}