Add tests dealing with instantiated function constants

Change-Id: Ie8cb03a7f7bb14eebc7c2e14bb1c38c04e2e7995
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/213047
Reviewed-by: Nate Bosch <nbosch@google.com>
Commit-Queue: Erik Ernst <eernst@google.com>
This commit is contained in:
Erik Ernst 2021-09-14 18:36:11 +00:00 committed by commit-bot@chromium.org
parent 5da6490b1b
commit 60d878137d
2 changed files with 265 additions and 0 deletions

View file

@ -0,0 +1,180 @@
// Copyright (c) 2021, 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.
// SharedOptions=--enable-experiment=constructor-tearoffs
// Test the support for error detection with generic function instantiation
// expressions that are constant or potentially constant. Include both some
// explicit generic function instantiations, and some implicit ones (for the
// latter, the type arguments are derived by type inference based on the
// context type). The main goal is to test the new feature where the underlying
// function is given as an existing function object, which also implies that
// there are several new possible syntactic forms, e.g., `(b ? f1 : f2)<int>`.
// The errors generally arise because one or more subexpressions are not
// constant.
import 'instantiated_function_constant_test.dart' as prefix;
void f1<X extends num>(X x, [num n = 0, List<X> xList = const []]) {}
void f2<Y extends num>(Y y, [int i = 1, Map<Y, Y> yMap = const {}]) {}
const b = true;
const c01 = f1;
const c02 = f2;
void test<Z extends num>() {
void g1<X extends num>(X x, [num n = 0, List<X> xList = const []]) {}
void g2<Y extends num>(Y y, [int i = 1, Map<Y, Y> yMap = const {}]) {}
// Explicitly instantiate function declaration.
const c03 = f1<Z>;
//^
// [analyzer] unspecified
// [cfe] unspecified
const c04 = prefix.f2<Z>;
//^
// [analyzer] unspecified
// [cfe] unspecified
const c05 = prefix.f1<Z>;
//^
// [analyzer] unspecified
// [cfe] unspecified
const c06 = f2<Z>;
//^
// [analyzer] unspecified
// [cfe] unspecified
const c07 = g1<int>;
//^
// [analyzer] unspecified
// [cfe] unspecified
const c08 = prefix.g2<int>;
//^
// [analyzer] unspecified
// [cfe] unspecified
const c09 = prefix.g1<int>;
//^
// [analyzer] unspecified
// [cfe] unspecified
const c10 = g2<int>;
//^
// [analyzer] unspecified
// [cfe] unspecified
const c11 = g1<Z>;
//^
// [analyzer] unspecified
// [cfe] unspecified
const c12 = prefix.g2<Z>;
//^
// [analyzer] unspecified
// [cfe] unspecified
const c13 = prefix.g1<Z>;
//^
// [analyzer] unspecified
// [cfe] unspecified
const c14 = g2<Z>;
//^
// [analyzer] unspecified
// [cfe] unspecified
// Explicitly instantiate constant variable.
const c07 = prefix.c01<Z>;
//^
// [analyzer] unspecified
// [cfe] unspecified
const c08 = c02<Z>;
//^
// [analyzer] unspecified
// [cfe] unspecified
const c09 = c01<Z>;
//^
// [analyzer] unspecified
// [cfe] unspecified
const c10 = prefix.c02<Z>;
//^
// [analyzer] unspecified
// [cfe] unspecified
// Implicitly instantiate function declaration.
const void Function(Z) c11 = f1;
//^
// [analyzer] unspecified
// [cfe] unspecified
const void Function(Z, [int, Map<int, int>]) c12 = prefix.f2;
//^
// [analyzer] unspecified
// [cfe] unspecified
// Implicitly instantiate constant variable.
const void Function(Z) c13 = prefix.c01;
//^
// [analyzer] unspecified
// [cfe] unspecified
const void Function(Z, [int, Map<int, int>]) c14 = c02;
//^
// [analyzer] unspecified
// [cfe] unspecified
}
// Test new potentially constant expressions. A type variable is a potentially
// constant type expression, so there are no errors in the initializer list.
class A<U extends num> {
final x1, x2, x3, x4, x5, x6;
final void Function(U) x7;
final void Function(U) x8;
final void Function(U, [int, Map<num, Never>]) x9;
final void Function(U) x10;
const A(bool b)
: x1 = (b ? f1 : prefix.f2)<U>,
x2 = (b ? prefix.c01 : c02)<U>,
x3 = ((b ? prefix.f1 : f2))<U>,
x4 = ((b ? c01 : prefix.c02))<U>,
x5 = (null ?? f1)<U>,
x6 = ((c01 as dynamic) as void Function<X extends num>(X,
[num, List<X>]))<U>,
x7 = b ? f1 : f2,
x8 = b ? c01 : c02,
x9 = null ?? c02,
x10 =
(c01 as dynamic) as void Function<X extends num>(X, [int, List<X>]);
}
void main() {
const ff = false;
const A<double>(true);
const A<num>(ff);
void h<V>() {
const A<V>(true);
//^
// [analyzer] unspecified
// [cfe] unspecified
const A<V>(ff);
//^
// [analyzer] unspecified
// [cfe] unspecified
}
}

View file

@ -0,0 +1,85 @@
// Copyright (c) 2021, 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.
// SharedOptions=--enable-experiment=constructor-tearoffs
// Test the support for generic function instantiation with constant and
// potentially constant expressions. Include both some explicit generic
// function instantiations, and some implicit ones (for the latter, the type
// arguments are derived by type inference based on the context type). The
// main goal is to test the new feature where the underlying function is
// given as an existing function object, which also implies that there are
// several new possible syntactic forms, e.g., `(b ? f1 : f2)<int>`.
import 'instantiated_function_constant_test.dart' as prefix;
void f1<X extends num>(X x, [num n = 0, List<X> xList = const []]) {}
void f2<Y extends num>(Y y, [int i = 1, Map<Y, Y> yMap = const {}]) {}
const b = true;
const c01 = f1;
const c02 = f2;
// Explicitly instantiate function declaration.
const c03 = f1<int>;
const c04 = prefix.f2<int>;
const c05 = prefix.f1<int>;
const c06 = f2<int>;
// Explicitly instantiate constant variable.
const c07 = prefix.c01<int>;
const c08 = c02<int>;
const c09 = c01<int>;
const c10 = prefix.c02<int>;
// Implicitly instantiate function declaration.
const void Function(double) c11 = f1;
const void Function(Never, [int, Map<int, int>]) c12 = prefix.f2;
// Implicitly instantiate constant variable.
const void Function(double) c13 = prefix.c01;
const void Function(Never, [int, Map<int, int>]) c14 = c02;
// Test new potentially constant expressions. A type variable is a potentially
// constant type expression, so there are no errors in the initializer list.
class A<U extends num> {
final x1, x2, x3, x4, x5, x6;
final void Function(U) x7;
final void Function(U) x8;
final void Function(U, [int, Map<num, Never>]) x9;
final void Function(U) x10;
final void Function(num) x11;
final void Function(double) x12;
final void Function(num, [int, Map<num, Never>]) x13;
final void Function(int) x14;
const A(bool b)
: x1 = b ? (b ? f1 : prefix.f2)<U> : (b ? f1 : prefix.f2)<int>,
x2 = b ? (b ? prefix.c01 : c02)<U> : (b ? prefix.c01 : c02)<int>,
x3 = b ? ((b ? prefix.f1 : f2))<U> : ((b ? prefix.f1 : f2))<int>,
x4 = b ? ((b ? c01 : prefix.c02))<U> : ((b ? c01 : prefix.c02))<int>,
x5 = b ? (null ?? f1)<U> : (null ?? f1)<int>,
x6 = b
? ((c01 as dynamic) as void Function<X extends num>(X,
[num, List<X>]))<U>
: ((c01 as dynamic) as void Function<X extends num>(X,
[num, List<X>]))<int>,
x7 = b ? f1 : f2,
x8 = b ? c01 : c02,
x9 = null ?? c02,
x10 =
(c01 as dynamic) as void Function<X extends num>(X, [int, List<X>]),
x11 = b ? f1 : f2,
x12 = b ? c01 : c02,
x13 = null ?? c02,
x14 =
(c01 as dynamic) as void Function<X extends num>(X, [int, List<X>]);
}
void main() {
const ff = false;
const A<double>(true);
const A<num>(ff);
}