| // 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.UNDEFINED_PREFIXED_NAME_READ | |
| // [cfe] Undefined name 'g2'. | |
| const c09 = prefix.g1<int>; | |
| // ^^ | |
| // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_PREFIXED_NAME_READ | |
| // [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.UNDEFINED_PREFIXED_NAME_READ | |
| // [cfe] Undefined name 'g2'. | |
| // ^ | |
| // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_TYPE_PARAMETERS | |
| const c13 = prefix.g1<Z>; | |
| // ^^ | |
| // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_PREFIXED_NAME_READ | |
| // [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 | |
| } | |
| } |