diff --git a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml index f89819e75b0..ddd3e3555e5 100644 --- a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml +++ b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml @@ -445,6 +445,8 @@ CompileTimeErrorCode.CONST_SPREAD_EXPECTED_LIST_OR_SET: status: noFix CompileTimeErrorCode.CONST_SPREAD_EXPECTED_MAP: status: noFix +CompileTimeErrorCode.CONST_TYPE_PARAMETER: + status: needsEvaluation CompileTimeErrorCode.CONST_WITH_NON_CONST: status: hasFix CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT: diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart index a3bf9928363..e2f040c4d97 100644 --- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart +++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart @@ -535,6 +535,7 @@ class ConstantVerifier extends RecursiveAstVisitor { // Should not be a type parameter. if (type.element is TypeParameterElement) { _errorReporter.reportErrorForNode(errorCode, type); + return; } // Check type arguments. var typeArguments = type.typeArguments; @@ -603,6 +604,11 @@ class ConstantVerifier extends RecursiveAstVisitor { CompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH) || identical(dataErrorCode, CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH) || + identical(dataErrorCode, CompileTimeErrorCode.CONST_TYPE_PARAMETER) || + identical( + dataErrorCode, + CompileTimeErrorCode + .CONST_WITH_TYPE_PARAMETERS_FUNCTION_TEAROFF) || identical( dataErrorCode, CompileTimeErrorCode.VARIABLE_TYPE_MISMATCH) || identical(dataErrorCode, CompileTimeErrorCode.NON_BOOL_CONDITION) || diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart index 29dff7968e3..b2e15bca95f 100644 --- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart +++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart @@ -836,7 +836,7 @@ class ConstantVisitor extends UnifyingAstVisitor { @override Constant visitFunctionReference(FunctionReference node) { - var functionResult = _getConstant(node.function); + final functionResult = _getConstant(node.function); if (functionResult is! DartObjectImpl) { return functionResult; } @@ -846,9 +846,9 @@ class ConstantVisitor extends UnifyingAstVisitor { // any type parameters contained therein are reported as non-constant in // [ConstantVerifier]. if (node.typeArguments == null) { - var typeArgumentTypes = node.typeArgumentTypes; + final typeArgumentTypes = node.typeArgumentTypes; if (typeArgumentTypes != null) { - var instantiatedTypeArgumentTypes = typeArgumentTypes.map((type) { + final instantiatedTypeArgumentTypes = typeArgumentTypes.map((type) { if (type is TypeParameterType) { return _lexicalTypeEnvironment?[type.element] ?? type; } else { @@ -866,26 +866,39 @@ class ConstantVisitor extends UnifyingAstVisitor { } } - var typeArgumentList = node.typeArguments; + final typeArgumentList = node.typeArguments; if (typeArgumentList == null) { return _instantiateFunctionType(node, functionResult); } - var typeArguments = []; + final typeArguments = []; for (var typeArgument in typeArgumentList.arguments) { - var object = _getConstant(typeArgument); - if (object is! DartObjectImpl) { - return object; + final typeArgumentConstant = _getConstant(typeArgument); + switch (typeArgumentConstant) { + case InvalidConstant( + errorCode: CompileTimeErrorCode.CONST_TYPE_PARAMETER + ): + // If there's a type parameter error in the evaluated constant, we + // convert the message to a more specific function reference error. + // TODO(kallentu): Don't report error here. + _errorReporter.reportErrorForNode( + CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_FUNCTION_TEAROFF, + typeArgument); + return InvalidConstant(typeArgument, + CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_FUNCTION_TEAROFF); + case InvalidConstant(): + return typeArgumentConstant; + case DartObjectImpl(): + final typeArgumentType = typeArgumentConstant.toTypeValue(); + if (typeArgumentType == null) { + return InvalidConstant( + typeArgument, CompileTimeErrorCode.INVALID_CONSTANT); + } + // TODO(srawlins): Test type alias types (`typedef i = int`) used as + // type arguments. Possibly change implementation based on + // canonicalization rules. + typeArguments.add(typeArgumentType); } - var typeArgumentType = object.toTypeValue(); - if (typeArgumentType == null) { - return InvalidConstant( - typeArgument, CompileTimeErrorCode.INVALID_CONSTANT); - } - // TODO(srawlins): Test type alias types (`typedef i = int`) used as - // type arguments. Possibly change implementation based on - // canonicalization rules. - typeArguments.add(typeArgumentType); } return _dartObjectComputer.typeInstantiate( functionResult, typeArguments, node.function); @@ -954,7 +967,8 @@ class ConstantVisitor extends UnifyingAstVisitor { if (!result.isBoolNumStringOrNull) { // TODO(kallentu): Don't report error here. - _error(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING); + _errorReporter.reportErrorForNode( + CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, node); return InvalidConstant( node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING); } @@ -1070,11 +1084,10 @@ class ConstantVisitor extends UnifyingAstVisitor { if ((!_isNonNullableByDefault || node.isTypeLiteralInConstantPattern) && hasTypeParameterReference(type)) { - // TODO(kallentu): Don't report error here and report a more specific - // diagnostic + // TODO(kallentu): Don't report error here _errorReporter.reportErrorForNode( - CompileTimeErrorCode.INVALID_CONSTANT, node); - return InvalidConstant(node, CompileTimeErrorCode.INVALID_CONSTANT); + CompileTimeErrorCode.CONST_TYPE_PARAMETER, node); + return InvalidConstant(node, CompileTimeErrorCode.CONST_TYPE_PARAMETER); } else if (node.isDeferred) { return _getDeferredLibraryError(node, node.name2) ?? InvalidConstant(node, CompileTimeErrorCode.INVALID_CONSTANT); @@ -1129,10 +1142,10 @@ class ConstantVisitor extends UnifyingAstVisitor { // String.length if (prefixElement is! InterfaceElement) { - final stringLengthResult = - _evaluateStringLength(prefixResult, node.identifier, node); - if (stringLengthResult != null) { - return stringLengthResult; + final propertyAccessResult = + _evaluatePropertyAccess(prefixResult, node.identifier, node); + if (propertyAccessResult != null) { + return propertyAccessResult; } } } @@ -1182,10 +1195,10 @@ class ConstantVisitor extends UnifyingAstVisitor { return prefixResult; } - final stringLengthResult = - _evaluateStringLength(prefixResult, node.propertyName, node); - if (stringLengthResult != null) { - return stringLengthResult; + final propertyAccessResult = + _evaluatePropertyAccess(prefixResult, node.propertyName, node); + if (propertyAccessResult != null) { + return propertyAccessResult; } } return _getConstantValue( @@ -1380,7 +1393,8 @@ class ConstantVisitor extends UnifyingAstVisitor { return null; } case MapLiteralEntry(): - return InvalidConstant(element, CompileTimeErrorCode.INVALID_CONSTANT); + return InvalidConstant( + element, CompileTimeErrorCode.MAP_ENTRY_NOT_IN_MAP); case SpreadElement(): var spread = _getConstant(element.expression); switch (spread) { @@ -1405,7 +1419,7 @@ class ConstantVisitor extends UnifyingAstVisitor { Map map, CollectionElement element) { switch (element) { case Expression(): - return InvalidConstant(element, CompileTimeErrorCode.INVALID_CONSTANT); + return InvalidConstant(element, CompileTimeErrorCode.EXPRESSION_IN_MAP); case ForElement(): // TODO(kallentu): Don't report error here. _errorReporter.reportErrorForNode( @@ -1508,7 +1522,8 @@ class ConstantVisitor extends UnifyingAstVisitor { return null; } case MapLiteralEntry(): - return InvalidConstant(element, CompileTimeErrorCode.INVALID_CONSTANT); + return InvalidConstant( + element, CompileTimeErrorCode.MAP_ENTRY_NOT_IN_MAP); case SpreadElement(): var spread = _getConstant(element.expression); switch (spread) { @@ -1578,12 +1593,12 @@ class ConstantVisitor extends UnifyingAstVisitor { _errorReporter.reportErrorForNode(code, node); } - /// Attempt to evaluate a constant that reads the length of a `String`. + /// Attempt to evaluate a constant property access. /// /// Return a valid [DartObjectImpl] if the given [targetResult] represents a /// `String` and the [identifier] is `length`, an [InvalidConstant] if there's /// an error, and `null` otherwise. - Constant? _evaluateStringLength(DartObjectImpl targetResult, + Constant? _evaluatePropertyAccess(DartObjectImpl targetResult, SimpleIdentifier identifier, AstNode errorNode) { if (identifier.staticElement?.enclosingElement is ExtensionElement) { _errorReporter.reportErrorForNode( @@ -1592,23 +1607,33 @@ class ConstantVisitor extends UnifyingAstVisitor { errorNode, CompileTimeErrorCode.CONST_EVAL_EXTENSION_METHOD); } - if (identifier.name == 'length') { - final targetType = targetResult.type; - if (!(targetType is InterfaceType && targetType.isDartCoreString)) { - _errorReporter.reportErrorForNode( - CompileTimeErrorCode.CONST_EVAL_PROPERTY_ACCESS, - errorNode, - [identifier.name, targetType]); - return InvalidConstant( - errorNode, CompileTimeErrorCode.CONST_EVAL_PROPERTY_ACCESS, - arguments: [identifier.name, targetType]); - } + final targetType = targetResult.type; + + // Evaluate a constant that reads the length of a `String`. + if (identifier.name == 'length' && + targetType is InterfaceType && + targetType.isDartCoreString) { return _dartObjectComputer.stringLength(errorNode, targetResult); } - // TODO(kallentu): Make a more specific error here if we aren't accessing - // the '.length' property. - return null; + final element = identifier.staticElement; + if (element != null && element is ExecutableElement && element.isStatic) { + return null; + } + + // No other property access is allowed except for `.length` of a `String`. + // TODO(kallentu): Don't report error here. + _errorReporter.reportErrorForNode( + CompileTimeErrorCode.CONST_EVAL_PROPERTY_ACCESS, errorNode, [ + identifier.name, + targetType.getDisplayString(withNullability: _isNonNullableByDefault) + ]); + return InvalidConstant( + errorNode, CompileTimeErrorCode.CONST_EVAL_PROPERTY_ACCESS, + arguments: [ + identifier.name, + targetType.getDisplayString(withNullability: _isNonNullableByDefault) + ]); } /// Return a [Constant], evaluated by the [ConstantVisitor]. @@ -1650,8 +1675,10 @@ class ConstantVisitor extends UnifyingAstVisitor { (expression.tearOffTypeArgumentTypes?.any(hasTypeParameterReference) ?? false)) { // TODO(kallentu): Don't report error here. - _error(expression, null); - return InvalidConstant.genericError(expression); + _errorReporter.reportErrorForNode( + CompileTimeErrorCode.CONST_TYPE_PARAMETER, expression); + return InvalidConstant( + expression, CompileTimeErrorCode.CONST_TYPE_PARAMETER); } if (variableElement is VariableElementImpl) { @@ -1748,7 +1775,7 @@ class ConstantVisitor extends UnifyingAstVisitor { // Constants may refer to type parameters only if the constructor-tearoffs // feature is enabled. if (_library.featureSet.isEnabled(Feature.constructor_tearoffs)) { - var typeArgument = _lexicalTypeEnvironment?[variableElement]; + final typeArgument = _lexicalTypeEnvironment?[variableElement]; if (typeArgument != null) { return DartObjectImpl( typeSystem, @@ -1756,6 +1783,10 @@ class ConstantVisitor extends UnifyingAstVisitor { TypeState(typeArgument), ); } + _errorReporter.reportErrorForNode( + CompileTimeErrorCode.CONST_TYPE_PARAMETER, errorNode2); + return InvalidConstant( + errorNode2, CompileTimeErrorCode.CONST_TYPE_PARAMETER); } } diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart index f616fde7b89..463347f1d56 100644 --- a/pkg/analyzer/lib/src/error/codes.g.dart +++ b/pkg/analyzer/lib/src/error/codes.g.dart @@ -1027,6 +1027,14 @@ class CompileTimeErrorCode extends AnalyzerErrorCode { hasPublishedDocs: true, ); + /// No parameters. + static const CompileTimeErrorCode CONST_TYPE_PARAMETER = CompileTimeErrorCode( + 'CONST_TYPE_PARAMETER', + "Type parameters can't be used in a constant expression.", + correctionMessage: + "Try replacing the type parameter with a different type.", + ); + /// No parameters. static const CompileTimeErrorCode CONST_WITH_NON_CONST = CompileTimeErrorCode( 'CONST_WITH_NON_CONST', diff --git a/pkg/analyzer/lib/src/error/error_code_values.g.dart b/pkg/analyzer/lib/src/error/error_code_values.g.dart index 2d27d5fe5fc..92b23d15c60 100644 --- a/pkg/analyzer/lib/src/error/error_code_values.g.dart +++ b/pkg/analyzer/lib/src/error/error_code_values.g.dart @@ -138,6 +138,7 @@ const List errorCodeValues = [ CompileTimeErrorCode.CONST_SET_ELEMENT_NOT_PRIMITIVE_EQUALITY, CompileTimeErrorCode.CONST_SPREAD_EXPECTED_LIST_OR_SET, CompileTimeErrorCode.CONST_SPREAD_EXPECTED_MAP, + CompileTimeErrorCode.CONST_TYPE_PARAMETER, CompileTimeErrorCode.CONST_WITH_NON_CONST, CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, CompileTimeErrorCode.CONST_WITH_NON_TYPE, diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart index 5376e341df7..2c38d596bdf 100644 --- a/pkg/analyzer/lib/src/lint/linter.dart +++ b/pkg/analyzer/lib/src/lint/linter.dart @@ -986,6 +986,7 @@ class _ConstantAnalysisErrorListener extends AnalysisErrorListener { case CompileTimeErrorCode.CONST_EVAL_FOR_ELEMENT: case CompileTimeErrorCode.CONST_MAP_KEY_NOT_PRIMITIVE_EQUALITY: case CompileTimeErrorCode.CONST_SET_ELEMENT_NOT_PRIMITIVE_EQUALITY: + case CompileTimeErrorCode.CONST_TYPE_PARAMETER: case CompileTimeErrorCode.CONST_WITH_NON_CONST: case CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT: case CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS: diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml index bee0cc304c1..d7e10448266 100644 --- a/pkg/analyzer/messages.yaml +++ b/pkg/analyzer/messages.yaml @@ -3034,6 +3034,10 @@ CompileTimeErrorCode: const Map map1 = {}; const Map map2 = {...map1}; ``` + CONST_TYPE_PARAMETER: + problemMessage: "Type parameters can't be used in a constant expression." + correctionMessage: Try replacing the type parameter with a different type. + comment: No parameters. CONST_WITH_NON_CONST: problemMessage: "The constructor being called isn't a const constructor." correctionMessage: "Try removing 'const' from the constructor invocation." diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart index c664a932fa9..8ee32c12727 100644 --- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart +++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart @@ -542,6 +542,22 @@ void f(Object? x) { '''); } + test_typeParameter() async { + await assertErrorsInCode(''' +class A { + const A(); + void m() { + const x = X; + } +} +''', [ + error(WarningCode.UNUSED_LOCAL_VARIABLE, 49, 1), + error(CompileTimeErrorCode.CONST_TYPE_PARAMETER, 53, 1), + ]); + final result = _localVar('x'); + _assertNull(result); + } + test_visitBinaryExpression_extensionMethod() async { await assertErrorsInCode(''' extension on Object { @@ -1102,7 +1118,8 @@ class C { const C({this.p = f}); } ''', [ - error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 83, 1), + error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_FUNCTION_TEAROFF, + 83, 1), ]); } @@ -1223,8 +1240,7 @@ class C { error(WarningCode.UNUSED_LOCAL_VARIABLE, 55, 1), error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_FUNCTION_TEAROFF, 61, 1), - error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 61, - 1), + error(CompileTimeErrorCode.CONST_TYPE_PARAMETER, 61, 1), ]); } @@ -1668,8 +1684,7 @@ void f(Object? x) { if (x case const (T)) {} } ''', [ - error(CompileTimeErrorCode.CONSTANT_PATTERN_WITH_NON_CONSTANT_EXPRESSION, - 43, 1), + error(CompileTimeErrorCode.CONST_TYPE_PARAMETER, 43, 1), ]); } @@ -1679,8 +1694,7 @@ void f(Object? x) { if (x case const (List)) {} } ''', [ - error(CompileTimeErrorCode.CONSTANT_PATTERN_WITH_NON_CONSTANT_EXPRESSION, - 43, 7), + error(CompileTimeErrorCode.CONST_TYPE_PARAMETER, 43, 7), ]); } @@ -2265,23 +2279,6 @@ const c = {1, ...{2, 3}, 4}; expect(result.toSetValue()!.map((e) => e.toIntValue()), [1, 2, 3, 4]); } - test_typeParameter() async { - await assertErrorsInCode(''' -class A { - const A(); - void m() { - const x = X; - } -} -''', [ - error(WarningCode.UNUSED_LOCAL_VARIABLE, 49, 1), - error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 53, - 1), - ]); - final result = _localVar('x'); - _assertNull(result); - } - test_visitAsExpression_instanceOfSameClass() async { await resolveTestCode(''' const a = const A(); diff --git a/pkg/analyzer/test/src/diagnostics/const_eval_property_access_test.dart b/pkg/analyzer/test/src/diagnostics/const_eval_property_access_test.dart index 7842960568c..2b194265ee5 100644 --- a/pkg/analyzer/test/src/diagnostics/const_eval_property_access_test.dart +++ b/pkg/analyzer/test/src/diagnostics/const_eval_property_access_test.dart @@ -16,6 +16,33 @@ main() { @reflectiveTest class ConstEvalPropertyAccessTest extends PubPackageResolutionTest { + test_constructorFieldInitializer_fromSeparateLibrary() async { + newFile('$testPackageLibPath/lib.dart', r''' +class A { + final int f; + const A() : f = T.foo; +} +'''); + await assertErrorsInCode(r''' +import 'lib.dart'; +const a = const A(); +''', [ + error( + CompileTimeErrorCode.CONST_EVAL_PROPERTY_ACCESS, + 29, + 9, + contextMessages: [ + ExpectedContextMessage( + convertPath('$testPackageLibPath/lib.dart'), 46, 5, + text: + "The error is in the field initializer of 'A', and occurs here."), + ], + ), + error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 29, + 9), + ]); + } + test_length_invalidTarget() async { await assertErrorsInCode(''' void main() { diff --git a/pkg/analyzer/test/src/diagnostics/const_type_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/const_type_parameter_test.dart new file mode 100644 index 00000000000..3d57f146348 --- /dev/null +++ b/pkg/analyzer/test/src/diagnostics/const_type_parameter_test.dart @@ -0,0 +1,47 @@ +// Copyright (c) 2023, 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:analyzer/src/error/codes.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import '../dart/resolution/context_collection_resolution.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(ConstTypeParameterTest); + }); +} + +@reflectiveTest +class ConstTypeParameterTest extends PubPackageResolutionTest { + test_constantPattern_typeParameter() async { + await assertErrorsInCode(r''' +void f(x) { + if (x case T) {} +} +''', [ + error(CompileTimeErrorCode.CONST_TYPE_PARAMETER, 28, 1), + ]); + } + + test_constantPattern_typeParameter_nested() async { + await assertErrorsInCode(r''' +void f(Object? x) { + if (x case const (T)) {} +} +''', [ + error(CompileTimeErrorCode.CONST_TYPE_PARAMETER, 43, 1), + ]); + } + + test_constantPattern_typeParameter_nested2() async { + await assertErrorsInCode(r''' +void f(Object? x) { + if (x case const (List)) {} +} +''', [ + error(CompileTimeErrorCode.CONST_TYPE_PARAMETER, 43, 7), + ]); + } +} diff --git a/pkg/analyzer/test/src/diagnostics/const_with_type_parameters_test.dart b/pkg/analyzer/test/src/diagnostics/const_with_type_parameters_test.dart index de1515dc153..8a46a5a2653 100644 --- a/pkg/analyzer/test/src/diagnostics/const_with_type_parameters_test.dart +++ b/pkg/analyzer/test/src/diagnostics/const_with_type_parameters_test.dart @@ -135,6 +135,66 @@ class A { @reflectiveTest class ConstWithTypeParametersFunctionTearoffTest extends PubPackageResolutionTest { + test_appliedTypeParameter_defaultConstructorValue() async { + await assertErrorsInCode(r''' +void f(T t) => t; + +class C { + final void Function(T) p; + const C({this.p = f}); +} +''', [ + error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_FUNCTION_TEAROFF, + 83, 1), + ]); + } + + test_appliedTypeParameter_defaultFunctionValue() async { + await assertErrorsInCode(r''' +void f(T t) => t; + +void bar([void Function(T) p = f]) {} +''', [ + error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_FUNCTION_TEAROFF, + 56, 1), + ]); + } + + test_appliedTypeParameter_defaultMethodValue() async { + await assertErrorsInCode(r''' +void f(T t) => t; + +class C { + void foo([void Function(T) p = f]) {} +} +''', [ + error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_FUNCTION_TEAROFF, + 68, 1), + ]); + } + + test_appliedTypeParameter_nested() async { + await assertErrorsInCode(r''' +void f(T t) => t; + +void bar([void Function(List) p = f]) {} +''', [ + error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_FUNCTION_TEAROFF, + 62, 1), + ]); + } + + test_appliedTypeParameter_nestedFunction() async { + await assertErrorsInCode(r''' +void f(T t) => t; + +void bar([void Function(T Function()) p = f]) {} +''', [ + error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_FUNCTION_TEAROFF, + 67, 1) + ]); + } + test_defaultValue() async { await assertErrorsInCode(''' void f(T a) {} @@ -144,7 +204,7 @@ class A { ''', [ error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_FUNCTION_TEAROFF, 65, 1), - error(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 65, 1), + error(CompileTimeErrorCode.CONST_TYPE_PARAMETER, 65, 1), ]); } @@ -160,8 +220,7 @@ class A { error(HintCode.UNUSED_LOCAL_VARIABLE, 54, 1), error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_FUNCTION_TEAROFF, 60, 1), - error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 60, - 1), + error(CompileTimeErrorCode.CONST_TYPE_PARAMETER, 60, 1), ]); } @@ -180,6 +239,7 @@ class A { 5), error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_FUNCTION_TEAROFF, 58, 1), + error(CompileTimeErrorCode.CONST_TYPE_PARAMETER, 58, 1), ]); } diff --git a/pkg/analyzer/test/src/diagnostics/constant_pattern_with_non_constant_expression_test.dart b/pkg/analyzer/test/src/diagnostics/constant_pattern_with_non_constant_expression_test.dart index 6c9326b04e4..c82f043c13f 100644 --- a/pkg/analyzer/test/src/diagnostics/constant_pattern_with_non_constant_expression_test.dart +++ b/pkg/analyzer/test/src/diagnostics/constant_pattern_with_non_constant_expression_test.dart @@ -557,39 +557,6 @@ GuardedPattern '''); } - test_typeLiteral_typeParameter() async { - await assertErrorsInCode(r''' -void f(x) { - if (x case T) {} -} -''', [ - error(CompileTimeErrorCode.CONSTANT_PATTERN_WITH_NON_CONSTANT_EXPRESSION, - 28, 1), - ]); - } - - test_typeLiteral_typeParameter_nested() async { - await assertErrorsInCode(r''' -void f(Object? x) { - if (x case const (T)) {} -} -''', [ - error(CompileTimeErrorCode.CONSTANT_PATTERN_WITH_NON_CONSTANT_EXPRESSION, - 43, 1), - ]); - } - - test_typeLiteral_typeParameter_nested2() async { - await assertErrorsInCode(r''' -void f(Object? x) { - if (x case const (List)) {} -} -''', [ - error(CompileTimeErrorCode.CONSTANT_PATTERN_WITH_NON_CONSTANT_EXPRESSION, - 43, 7), - ]); - } - test_unresolvedIdentifier() async { await assertErrorsInCode(r''' void f(Object? x) { diff --git a/pkg/analyzer/test/src/diagnostics/invalid_constant_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_constant_test.dart index 19cf6efe0b6..7bdec69259e 100644 --- a/pkg/analyzer/test/src/diagnostics/invalid_constant_test.dart +++ b/pkg/analyzer/test/src/diagnostics/invalid_constant_test.dart @@ -49,33 +49,6 @@ class A { ]); } - test_constructorFieldInitializer_fromSeparateLibrary() async { - newFile('$testPackageLibPath/lib.dart', r''' -class A { - final int f; - const A() : f = T.foo; -} -'''); - await assertErrorsInCode(r''' -import 'lib.dart'; -const a = const A(); -''', [ - error( - CompileTimeErrorCode.INVALID_CONSTANT, - 29, - 9, - contextMessages: [ - ExpectedContextMessage( - convertPath('$testPackageLibPath/lib.dart'), 46, 5, - text: - "The error is in the field initializer of 'A', and occurs here."), - ], - ), - error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 29, - 9), - ]); - } - test_in_initializer_field_as() async { await assertNoErrorsInCode(''' class C { diff --git a/pkg/analyzer/test/src/diagnostics/non_constant_default_value_test.dart b/pkg/analyzer/test/src/diagnostics/non_constant_default_value_test.dart index f035b8fd86f..ca6d62fd6b3 100644 --- a/pkg/analyzer/test/src/diagnostics/non_constant_default_value_test.dart +++ b/pkg/analyzer/test/src/diagnostics/non_constant_default_value_test.dart @@ -5,7 +5,6 @@ import 'package:analyzer/src/error/codes.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; -import '../../generated/test_support.dart'; import '../dart/resolution/context_collection_resolution.dart'; main() { @@ -16,51 +15,6 @@ main() { @reflectiveTest class NonConstantDefaultValueTest extends PubPackageResolutionTest { - test_appliedTypeParameter_defaultConstructorValue() async { - await assertErrorsInCode(r''' -void f(T t) => t; - -class C { - final void Function(T) p; - const C({this.p = f}); -} -''', [ExpectedError(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 83, 1)]); - } - - test_appliedTypeParameter_defaultFunctionValue() async { - await assertErrorsInCode(r''' -void f(T t) => t; - -void bar([void Function(T) p = f]) {} -''', [ExpectedError(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 56, 1)]); - } - - test_appliedTypeParameter_defaultMethodValue() async { - await assertErrorsInCode(r''' -void f(T t) => t; - -class C { - void foo([void Function(T) p = f]) {} -} -''', [ExpectedError(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 68, 1)]); - } - - test_appliedTypeParameter_nested() async { - await assertErrorsInCode(r''' -void f(T t) => t; - -void bar([void Function(List) p = f]) {} -''', [ExpectedError(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 62, 1)]); - } - - test_appliedTypeParameter_nestedFunction() async { - await assertErrorsInCode(r''' -void f(T t) => t; - -void bar([void Function(T Function()) p = f]) {} -''', [ExpectedError(CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE, 67, 1)]); - } - test_constructor_named() async { await assertErrorsInCode(r''' class A { diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart index 14d31c6fe88..d6caea869df 100644 --- a/pkg/analyzer/test/src/diagnostics/test_all.dart +++ b/pkg/analyzer/test/src/diagnostics/test_all.dart @@ -132,6 +132,7 @@ import 'const_set_element_not_primitive_equality_test.dart' import 'const_spread_expected_list_or_set_test.dart' as const_spread_expected_list_or_set; import 'const_spread_expected_map_test.dart' as const_spread_expected_map; +import 'const_type_parameter_test.dart' as const_type_parameter; import 'const_with_non_const_test.dart' as const_with_non_const; import 'const_with_non_constant_argument_test.dart' as const_with_non_constant_argument; @@ -986,6 +987,7 @@ main() { const_set_element_not_primitive_equality.main(); const_spread_expected_list_or_set.main(); const_spread_expected_map.main(); + const_type_parameter.main(); const_with_non_const.main(); const_with_non_constant_argument.main(); const_with_non_type.main(); diff --git a/tests/language/metadata/type_parameter_scope_other_test.dart b/tests/language/metadata/type_parameter_scope_other_test.dart index a393588d4d3..f2aa95c0d7a 100644 --- a/tests/language/metadata/type_parameter_scope_other_test.dart +++ b/tests/language/metadata/type_parameter_scope_other_test.dart @@ -15,37 +15,37 @@ class Annotation { class Class {} // ^ -// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT +// [analyzer] COMPILE_TIME_ERROR.CONST_TYPE_PARAMETER // [cfe] Type variables can't be used as constants. void function() {} // ^ -// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT +// [analyzer] COMPILE_TIME_ERROR.CONST_TYPE_PARAMETER // [cfe] Type variables can't be used as constants. extension Extension on Map {} // ^ -// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT +// [analyzer] COMPILE_TIME_ERROR.CONST_TYPE_PARAMETER // [cfe] Type variables can't be used as constants. class C { void method() {} // ^ - // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT + // [analyzer] COMPILE_TIME_ERROR.CONST_TYPE_PARAMETER // [cfe] Type variables can't be used as constants. } mixin Mixin {} // ^ -// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT +// [analyzer] COMPILE_TIME_ERROR.CONST_TYPE_PARAMETER // [cfe] Type variables can't be used as constants. typedef void Typedef1(T t, U u); // ^ -// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT +// [analyzer] COMPILE_TIME_ERROR.CONST_TYPE_PARAMETER // [cfe] Type variables can't be used as constants. typedef Typedef2 = void Function(T t, U u); // ^ -// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT +// [analyzer] COMPILE_TIME_ERROR.CONST_TYPE_PARAMETER // [cfe] Type variables can't be used as constants. diff --git a/tests/language/type_object/constant_type_literal_test.dart b/tests/language/type_object/constant_type_literal_test.dart index 91e07f4678d..83222bf061a 100644 --- a/tests/language/type_object/constant_type_literal_test.dart +++ b/tests/language/type_object/constant_type_literal_test.dart @@ -9,10 +9,8 @@ class C { const List lst = const [ T // ^ -// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE +// [analyzer] COMPILE_TIME_ERROR.CONST_TYPE_PARAMETER // [cfe] Type variables can't be used as constants. -// ^ -// [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_LIST_ELEMENT ]; } } diff --git a/tests/language_2/metadata/type_parameter_scope_other_test.dart b/tests/language_2/metadata/type_parameter_scope_other_test.dart index a393588d4d3..f2aa95c0d7a 100644 --- a/tests/language_2/metadata/type_parameter_scope_other_test.dart +++ b/tests/language_2/metadata/type_parameter_scope_other_test.dart @@ -15,37 +15,37 @@ class Annotation { class Class {} // ^ -// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT +// [analyzer] COMPILE_TIME_ERROR.CONST_TYPE_PARAMETER // [cfe] Type variables can't be used as constants. void function() {} // ^ -// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT +// [analyzer] COMPILE_TIME_ERROR.CONST_TYPE_PARAMETER // [cfe] Type variables can't be used as constants. extension Extension on Map {} // ^ -// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT +// [analyzer] COMPILE_TIME_ERROR.CONST_TYPE_PARAMETER // [cfe] Type variables can't be used as constants. class C { void method() {} // ^ - // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT + // [analyzer] COMPILE_TIME_ERROR.CONST_TYPE_PARAMETER // [cfe] Type variables can't be used as constants. } mixin Mixin {} // ^ -// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT +// [analyzer] COMPILE_TIME_ERROR.CONST_TYPE_PARAMETER // [cfe] Type variables can't be used as constants. typedef void Typedef1(T t, U u); // ^ -// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT +// [analyzer] COMPILE_TIME_ERROR.CONST_TYPE_PARAMETER // [cfe] Type variables can't be used as constants. typedef Typedef2 = void Function(T t, U u); // ^ -// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT +// [analyzer] COMPILE_TIME_ERROR.CONST_TYPE_PARAMETER // [cfe] Type variables can't be used as constants.