6cc9efe290
Change-Id: I94dfcea40566190c6bf153c108b0d0d5dbf27a4d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/400148 Commit-Queue: Bob Nystrom <rnystrom@google.com> Reviewed-by: Lasse Nielsen <lrn@google.com> Auto-Submit: Bob Nystrom <rnystrom@google.com>
221 lines
7.7 KiB
Dart
221 lines
7.7 KiB
Dart
// 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.
|
|
|
|
// 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>;
|
|
// ^
|
|
// [cfe] Type variables can't be used as constants.
|
|
// ^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS
|
|
|
|
const c04 = prefix.f2<Z>;
|
|
// ^
|
|
// [cfe] Type variables can't be used as constants.
|
|
// ^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS
|
|
|
|
const c05 = prefix.f1<Z>;
|
|
// ^
|
|
// [cfe] Type variables can't be used as constants.
|
|
// ^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS
|
|
|
|
const c06 = f2<Z>;
|
|
// ^
|
|
// [cfe] Type variables can't be used as constants.
|
|
// ^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS
|
|
|
|
const c07 = g1<int>;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
|
// [cfe] Not a constant expression.
|
|
|
|
const c08 = prefix.g2<int>;
|
|
// ^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_PREFIXED_NAME
|
|
// [cfe] Undefined name 'g2'.
|
|
|
|
const c09 = prefix.g1<int>;
|
|
// ^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_PREFIXED_NAME
|
|
// [cfe] Undefined name 'g1'.
|
|
|
|
const c10 = g2<int>;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
|
// [cfe] Not a constant expression.
|
|
|
|
const c11 = g1<Z>;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
|
// [cfe] Not a constant expression.
|
|
// ^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS
|
|
|
|
const c12 = prefix.g2<Z>;
|
|
// ^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_PREFIXED_NAME
|
|
// [cfe] Undefined name 'g2'.
|
|
// ^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS
|
|
|
|
const c13 = prefix.g1<Z>;
|
|
// ^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_PREFIXED_NAME
|
|
// [cfe] Undefined name 'g1'.
|
|
// ^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS
|
|
|
|
const c14 = g2<Z>;
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
|
// [cfe] Not a constant expression.
|
|
// ^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS
|
|
|
|
// Explicitly instantiate constant variable.
|
|
|
|
const c07 = prefix.c01<Z>;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
|
|
// [cfe] 'c07' is already declared in this scope.
|
|
// ^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS
|
|
|
|
const c08 = c02<Z>;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
|
|
// [cfe] 'c08' is already declared in this scope.
|
|
// ^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS
|
|
|
|
const c09 = c01<Z>;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
|
|
// [cfe] 'c09' is already declared in this scope.
|
|
// ^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS
|
|
|
|
const c10 = prefix.c02<Z>;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
|
|
// [cfe] 'c10' is already declared in this scope.
|
|
// ^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS
|
|
|
|
// Implicitly instantiate function declaration.
|
|
|
|
const void Function(Z) c11 = f1;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
|
|
// [cfe] 'c11' is already declared in this scope.
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS
|
|
|
|
const void Function(Z, [int, Map<int, int>]) c12 = prefix.f2;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
|
|
// [cfe] 'c12' is already declared in this scope.
|
|
|
|
// Implicitly instantiate constant variable.
|
|
|
|
const void Function(Z) c13 = prefix.c01;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
|
|
// [cfe] 'c13' is already declared in this scope.
|
|
// ^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS
|
|
|
|
const void Function(Z, [int, Map<int, int>]) c14 = c02;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
|
|
// [cfe] 'c14' is already declared in this scope.
|
|
}
|
|
|
|
// 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);
|
|
// [error column 5, length 16]
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS
|
|
// ^
|
|
// [cfe] Type argument 'V' doesn't conform to the bound 'num' of the type variable 'U' on 'A'.
|
|
// [cfe] Type variables can't be used as constants.
|
|
// ^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS
|
|
// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
|
|
|
|
const A<V>(ff);
|
|
// [error column 5, length 14]
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS
|
|
// ^
|
|
// [cfe] Type argument 'V' doesn't conform to the bound 'num' of the type variable 'U' on 'A'.
|
|
// [cfe] Type variables can't be used as constants.
|
|
// ^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS
|
|
// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
|
|
}
|
|
}
|