From ae4543fcb9ef604fc5ef1003a3d6f1703e1fd19e Mon Sep 17 00:00:00 2001 From: Johnni Winther Date: Tue, 24 Aug 2021 11:42:53 +0000 Subject: [PATCH] [cfe] Report all compile-time errors found during constant evaluation Closes #46925 Change-Id: I81e97cae05c39c24b24dae82a222f857d4730ac7 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/210465 Reviewed-by: Jens Johansen Commit-Queue: Johnni Winther --- .../lib/src/messages/codes_generated.dart | 20 + pkg/compiler/lib/src/ir/constants.dart | 7 +- .../lib/src/fasta/kernel/body_builder.dart | 8 +- .../kernel/constant_collection_builders.dart | 20 +- .../src/fasta/kernel/constant_evaluator.dart | 438 +++++++++--------- .../src/fasta/kernel/constant_int_folder.dart | 38 +- .../fasta/kernel/expression_generator.dart | 8 +- .../src/fasta/kernel/kernel_constants.dart | 20 +- .../lib/src/testing/id_extractor.dart | 5 +- pkg/front_end/messages.status | 2 + pkg/front_end/messages.yaml | 3 + .../test/constant_evaluator_benchmark.dart | 7 +- pkg/front_end/test/fasta/testing/suite.dart | 7 +- .../test/spell_checking_list_tests.txt | 1 + .../non_function_invocation.dart | 8 + ...non_function_invocation.dart.strong.expect | 23 + ..._invocation.dart.strong.transformed.expect | 23 + ...ion_invocation.dart.textual_outline.expect | 3 + ...ation.dart.textual_outline_modelled.expect | 3 + .../non_function_invocation.dart.weak.expect | 23 + ...nction_invocation.dart.weak.outline.expect | 12 + ...on_invocation.dart.weak.transformed.expect | 23 + .../constructor_tearoffs/issue46925.dart | 26 ++ .../issue46925.dart.strong.expect | 49 ++ .../issue46925.dart.strong.transformed.expect | 49 ++ .../issue46925.dart.textual_outline.expect | 8 + ...46925.dart.textual_outline_modelled.expect | 8 + .../issue46925.dart.weak.expect | 49 ++ .../issue46925.dart.weak.outline.expect | 17 + .../issue46925.dart.weak.transformed.expect | 49 ++ .../general/const_redirect_to_nonconst.dart | 2 +- ...ct_to_nonconst.dart.textual_outline.expect | 1 - ...const.dart.textual_outline_modelled.expect | 1 - ...onst_redirect_to_nonconst.dart.weak.expect | 23 +- ...irect_to_nonconst.dart.weak.outline.expect | 18 +- ...t_to_nonconst.dart.weak.transformed.expect | 23 +- .../constants/function_invocation.dart | 9 + ...ion_invocation.dart.textual_outline.expect | 4 + ...ation.dart.textual_outline_modelled.expect | 4 + .../function_invocation.dart.weak.expect | 20 + ...nction_invocation.dart.weak.outline.expect | 23 + ...on_invocation.dart.weak.transformed.expect | 20 + .../general/constants/issue46925.dart | 26 ++ .../issue46925.dart.textual_outline.expect | 8 + ...46925.dart.textual_outline_modelled.expect | 8 + .../constants/issue46925.dart.weak.expect | 95 ++++ .../issue46925.dart.weak.outline.expect | 17 + .../issue46925.dart.weak.transformed.expect | 95 ++++ .../general/constants/issue_43431.dart | 2 + .../constants/issue_43431.dart.weak.expect | 14 +- .../issue_43431.dart.weak.outline.expect | 2 +- .../issue_43431.dart.weak.transformed.expect | 14 +- .../constants/non_const_constructor.dart | 16 + ...st_constructor.dart.textual_outline.expect | 7 + .../non_const_constructor.dart.weak.expect | 40 ++ ...const_constructor.dart.weak.outline.expect | 38 ++ ...t_constructor.dart.weak.transformed.expect | 40 ++ .../general/constants/non_const_variable.dart | 10 + ...const_variable.dart.textual_outline.expect | 2 + ...iable.dart.textual_outline_modelled.expect | 2 + .../non_const_variable.dart.weak.expect | 18 + ...on_const_variable.dart.weak.outline.expect | 7 + ...onst_variable.dart.weak.transformed.expect | 18 + .../constants/various.dart.weak.expect | 16 +- .../various.dart.weak.transformed.expect | 16 +- .../general/magic_const.dart.weak.expect | 6 +- .../magic_const.dart.weak.transformed.expect | 6 +- ...ory_parameter_initializer.dart.weak.expect | 6 +- ...r_initializer.dart.weak.transformed.expect | 6 +- .../testcases/textual_outline.status | 1 + pkg/kernel/lib/ast.dart | 2 +- .../const_locals_constant_locals_test.dart | 4 +- .../const/constructor_syntax_test.dart | 2 +- .../const/factory_with_body_test.dart | 2 + tests/language/const/optional_args_test.dart | 1 + tests/language/const/syntax_test.dart | 11 +- ...functions_const_factory_disabled_test.dart | 2 + .../const_locals_constant_locals_test.dart | 4 +- .../const/constructor_syntax_test.dart | 2 +- .../const/factory_with_body_test.dart | 2 + .../language_2/const/optional_args_test.dart | 1 + tests/language_2/const/syntax_test.dart | 10 +- 82 files changed, 1319 insertions(+), 365 deletions(-) create mode 100644 pkg/front_end/testcases/const_functions/non_function_invocation.dart create mode 100644 pkg/front_end/testcases/const_functions/non_function_invocation.dart.strong.expect create mode 100644 pkg/front_end/testcases/const_functions/non_function_invocation.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/const_functions/non_function_invocation.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/const_functions/non_function_invocation.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/const_functions/non_function_invocation.dart.weak.expect create mode 100644 pkg/front_end/testcases/const_functions/non_function_invocation.dart.weak.outline.expect create mode 100644 pkg/front_end/testcases/const_functions/non_function_invocation.dart.weak.transformed.expect create mode 100644 pkg/front_end/testcases/constructor_tearoffs/issue46925.dart create mode 100644 pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.strong.expect create mode 100644 pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.weak.expect create mode 100644 pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.weak.outline.expect create mode 100644 pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.weak.transformed.expect create mode 100644 pkg/front_end/testcases/general/constants/function_invocation.dart create mode 100644 pkg/front_end/testcases/general/constants/function_invocation.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/general/constants/function_invocation.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/general/constants/function_invocation.dart.weak.expect create mode 100644 pkg/front_end/testcases/general/constants/function_invocation.dart.weak.outline.expect create mode 100644 pkg/front_end/testcases/general/constants/function_invocation.dart.weak.transformed.expect create mode 100644 pkg/front_end/testcases/general/constants/issue46925.dart create mode 100644 pkg/front_end/testcases/general/constants/issue46925.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/general/constants/issue46925.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/general/constants/issue46925.dart.weak.expect create mode 100644 pkg/front_end/testcases/general/constants/issue46925.dart.weak.outline.expect create mode 100644 pkg/front_end/testcases/general/constants/issue46925.dart.weak.transformed.expect create mode 100644 pkg/front_end/testcases/general/constants/non_const_constructor.dart create mode 100644 pkg/front_end/testcases/general/constants/non_const_constructor.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/general/constants/non_const_constructor.dart.weak.expect create mode 100644 pkg/front_end/testcases/general/constants/non_const_constructor.dart.weak.outline.expect create mode 100644 pkg/front_end/testcases/general/constants/non_const_constructor.dart.weak.transformed.expect create mode 100644 pkg/front_end/testcases/general/constants/non_const_variable.dart create mode 100644 pkg/front_end/testcases/general/constants/non_const_variable.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/general/constants/non_const_variable.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/general/constants/non_const_variable.dart.weak.expect create mode 100644 pkg/front_end/testcases/general/constants/non_const_variable.dart.weak.outline.expect create mode 100644 pkg/front_end/testcases/general/constants/non_const_variable.dart.weak.transformed.expect diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart index a2806c1539b..2e1545f9ef4 100644 --- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart +++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart @@ -1317,6 +1317,26 @@ Message _withArgumentsConstEvalDeferredLibrary(String nameOKEmpty) { arguments: {'nameOKEmpty': nameOKEmpty}); } +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Template templateConstEvalError = + const Template( + messageTemplate: r"""Error evaluating constant expression: #string""", + withArguments: _withArgumentsConstEvalError); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Code codeConstEvalError = + const Code( + "ConstEvalError", +); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +Message _withArgumentsConstEvalError(String string) { + if (string.isEmpty) throw 'No string provided'; + return new Message(codeConstEvalError, + message: """Error evaluating constant expression: ${string}""", + arguments: {'string': string}); +} + // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const Code codeConstEvalExtension = messageConstEvalExtension; diff --git a/pkg/compiler/lib/src/ir/constants.dart b/pkg/compiler/lib/src/ir/constants.dart index 4a936f642d7..50cc0a63806 100644 --- a/pkg/compiler/lib/src/ir/constants.dart +++ b/pkg/compiler/lib/src/ir/constants.dart @@ -100,12 +100,7 @@ class ErrorReporter implements ir.ErrorReporter { ErrorReporter(this._reportError); @override - void reportInvalidExpression(ir.InvalidExpression node) { - // Ignore. - } - - @override - void report(ir.LocatedMessage message, List context) { + void report(ir.LocatedMessage message, [List context]) { if (requiresConstant) { _reportError(message, context); } diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart index c90bb311149..2b6b569c0b5 100644 --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart @@ -6404,8 +6404,12 @@ class BodyBuilder extends ScopeListener allowPotentiallyConstantType: allowPotentiallyConstantType); if (message == null) return unresolved; return new UnresolvedType( - new NamedTypeBuilder(typeParameter.name!, builder.nullabilityBuilder, - /* arguments = */ null, unresolved.fileUri, unresolved.charOffset) + new NamedTypeBuilder( + typeParameter.name!, + builder.nullabilityBuilder, + /* arguments = */ null, + unresolved.fileUri, + unresolved.charOffset) ..bind(new InvalidTypeDeclarationBuilder( typeParameter.name!, message)), unresolved.charOffset, diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart b/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart index 2649c47c8d9..37ab5722fe5 100644 --- a/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart +++ b/pkg/front_end/lib/src/fasta/kernel/constant_collection_builders.dart @@ -44,7 +44,7 @@ abstract class _ListOrSetConstantBuilder { parts.add(spread); } else if (spread == evaluator.nullConstant) { // Null spread - return evaluator.createErrorConstant( + return evaluator.createEvaluationErrorConstant( spreadExpression, messageConstEvalNullValue); } else { // Fully evaluated spread @@ -67,7 +67,7 @@ abstract class _ListOrSetConstantBuilder { }); } else { // Not list or set in spread - return evaluator.createErrorConstant( + return evaluator.createEvaluationErrorConstant( spreadExpression, messageConstEvalNotListOrSetInSpread); } for (Constant entry in entries) { @@ -159,14 +159,14 @@ class SetConstantBuilder extends _ListOrSetConstantBuilder { @override AbortConstant? addConstant(Constant constant, TreeNode context) { if (!evaluator.hasPrimitiveEqual(constant)) { - return evaluator.createErrorConstant( + return evaluator.createEvaluationErrorConstant( context, templateConstEvalElementImplementsEqual.withArguments( constant, evaluator.isNonNullableByDefault)); } bool unseen = seen.add(constant); if (!unseen) { - return evaluator.createErrorConstant( + return evaluator.createEvaluationErrorConstant( context, templateConstEvalDuplicateElement.withArguments( constant, evaluator.isNonNullableByDefault)); @@ -176,7 +176,7 @@ class SetConstantBuilder extends _ListOrSetConstantBuilder { evaluator._weakener.visitConstant(constant) ?? constant; bool weakUnseen = weakSeen.add(weakConstant); if (unseen != weakUnseen) { - return evaluator.createErrorConstant( + return evaluator.createEvaluationErrorConstant( context, messageNonAgnosticConstant); } } @@ -267,7 +267,7 @@ class MapConstantBuilder { parts.add(spread); } else if (spread == evaluator.nullConstant) { // Null spread - return evaluator.createErrorConstant( + return evaluator.createEvaluationErrorConstant( spreadExpression, messageConstEvalNullValue); } else { // Fully evaluated spread @@ -286,7 +286,7 @@ class MapConstantBuilder { if (error != null) return error; } else { // Not map in spread - return evaluator.createErrorConstant( + return evaluator.createEvaluationErrorConstant( spreadExpression, messageConstEvalNotMapInSpread); } } @@ -305,14 +305,14 @@ class MapConstantBuilder { parts.add(lastPart = []); } if (!evaluator.hasPrimitiveEqual(key)) { - return evaluator.createErrorConstant( + return evaluator.createEvaluationErrorConstant( keyContext, templateConstEvalKeyImplementsEqual.withArguments( key, evaluator.isNonNullableByDefault)); } bool unseenKey = seenKeys.add(key); if (!unseenKey) { - return evaluator.createErrorConstant( + return evaluator.createEvaluationErrorConstant( keyContext, templateConstEvalDuplicateKey.withArguments( key, evaluator.isNonNullableByDefault)); @@ -321,7 +321,7 @@ class MapConstantBuilder { Constant weakKey = evaluator._weakener.visitConstant(key) ?? key; bool weakUnseenKey = weakSeenKeys.add(weakKey); if (unseenKey != weakUnseenKey) { - return evaluator.createErrorConstant( + return evaluator.createEvaluationErrorConstant( keyContext, messageNonAgnosticConstant); } } diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart index 23286b55470..0f336e23e20 100644 --- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart +++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart @@ -20,7 +20,6 @@ library fasta.constant_evaluator; import 'dart:io' as io; -import 'package:front_end/src/fasta/kernel/constructor_tearoff_lowering.dart'; import 'package:kernel/ast.dart'; import 'package:kernel/class_hierarchy.dart'; import 'package:kernel/clone.dart'; @@ -34,48 +33,10 @@ import 'package:kernel/type_algebra.dart'; import 'package:kernel/type_environment.dart'; import 'package:kernel/target/targets.dart'; -import '../fasta_codes.dart' - show - LocatedMessage, - Message, - messageConstEvalCircularity, - messageConstEvalContext, - messageConstEvalExtension, - messageConstEvalExternalConstructor, - messageConstEvalExternalFactory, - messageConstEvalFailedAssertion, - messageConstEvalNotListOrSetInSpread, - messageConstEvalNotMapInSpread, - messageConstEvalNonNull, - messageConstEvalNullValue, - messageConstEvalStartingPoint, - messageConstEvalUnevaluated, - messageNonAgnosticConstant, - messageNotAConstantExpression, - noLength, - templateConstEvalCaseImplementsEqual, - templateConstEvalDeferredLibrary, - templateConstEvalDuplicateElement, - templateConstEvalDuplicateKey, - templateConstEvalElementImplementsEqual, - templateConstEvalFailedAssertionWithMessage, - templateConstEvalFreeTypeParameter, - templateConstEvalGetterNotFound, - templateConstEvalInvalidType, - templateConstEvalInvalidBinaryOperandType, - templateConstEvalInvalidEqualsOperandType, - templateConstEvalInvalidMethodInvocation, - templateConstEvalInvalidPropertyGet, - templateConstEvalInvalidStaticInvocation, - templateConstEvalInvalidStringInterpolationOperand, - templateConstEvalInvalidSymbolName, - templateConstEvalKeyImplementsEqual, - templateConstEvalNonConstantVariableGet, - templateConstEvalUnhandledCoreException, - templateConstEvalUnhandledException, - templateConstEvalZeroDivisor; +import '../fasta_codes.dart'; import 'constant_int_folder.dart'; +import 'constructor_tearoff_lowering.dart'; part 'constant_collection_builders.dart'; @@ -1070,29 +1031,28 @@ class ConstantEvaluator implements ExpressionVisitor { if (result is _AbortDueToErrorConstant) { final LocatedMessage locatedMessageActualError = createLocatedMessage(result.node, result.message); - final List contextMessages = [ - locatedMessageActualError - ]; - if (result.context != null) contextMessages.addAll(result.context!); - if (contextNode != null && contextNode != result.node) { - contextMessages - .add(createLocatedMessage(contextNode, messageConstEvalContext)); - } + if (result.isEvaluationError) { + final List contextMessages = [ + locatedMessageActualError + ]; + if (result.context != null) contextMessages.addAll(result.context!); + if (contextNode != null && contextNode != result.node) { + contextMessages.add( + createLocatedMessage(contextNode, messageConstEvalContext)); + } - { - final LocatedMessage locatedMessage = - createLocatedMessage(node, messageConstEvalStartingPoint); - errorReporter.report(locatedMessage, contextMessages); + { + final LocatedMessage locatedMessage = + createLocatedMessage(node, messageConstEvalStartingPoint); + errorReporter.report(locatedMessage, contextMessages); + } + } else { + errorReporter.report(locatedMessageActualError); } return new UnevaluatedConstant( new InvalidExpression(result.message.message)); } - if (result is _AbortDueToInvalidExpressionConstant) { - InvalidExpression invalid = new InvalidExpression(result.message) - ..fileOffset = node.fileOffset; - errorReporter.reportInvalidExpression(invalid); - return new UnevaluatedConstant(invalid); - } else if (result is _AbortDueToThrowConstant) { + if (result is _AbortDueToThrowConstant) { final Object value = result.throwValue; Message? message; if (value is Constant) { @@ -1116,11 +1076,18 @@ class ConstantEvaluator implements ExpressionVisitor { } return new UnevaluatedConstant(new InvalidExpression(message.message)); } + if (result is _AbortDueToInvalidExpressionConstant) { + return new UnevaluatedConstant( + // Create a new [InvalidExpression] without the expression, which + // might now have lost the needed context. For instance references + // to variables no longer in scope. + new InvalidExpression(result.node.message)); + } throw "Unexpected error constant"; } if (result is UnevaluatedConstant) { if (errorOnUnevaluatedConstant) { - return createErrorConstant(node, messageConstEvalUnevaluated); + return createEvaluationErrorConstant(node, messageConstEvalUnevaluated); } return canonicalize(new UnevaluatedConstant( removeRedundantFileUriExpressions(result.expression))); @@ -1146,8 +1113,11 @@ class ConstantEvaluator implements ExpressionVisitor { // No return statement in function body with void return type. return new NullConstant(); } - return createInvalidExpressionConstant(statement, - 'No valid constant returned from the execution of $statement.'); + return createEvaluationErrorConstant( + statement, + templateConstEvalError.withArguments( + 'No valid constant returned from the execution of the ' + 'statement.')); } /// Returns [null] on success and an error-"constant" on failure, as such the @@ -1162,27 +1132,33 @@ class ConstantEvaluator implements ExpressionVisitor { } else if (status is ReturnStatus) { if (status.value == null) return null; // Should not be reachable. - return createInvalidExpressionConstant( - constructor, "Constructors can't have a return value."); + return createEvaluationErrorConstant( + constructor, + templateConstEvalError + .withArguments("Constructors can't have a return value.")); } else if (status is! ProceedStatus) { - return createInvalidExpressionConstant( - constructor, "Invalid execution status of constructor body."); + return createEvaluationErrorConstant( + constructor, + templateConstEvalError + .withArguments("Invalid execution status of constructor body.")); } return null; } /// Create an error-constant indicating that an error has been detected during /// constant evaluation. - AbortConstant createErrorConstant(TreeNode node, Message message, + AbortConstant createEvaluationErrorConstant(TreeNode node, Message message, {List? context}) { - return new _AbortDueToErrorConstant(node, message, context: context); + return new _AbortDueToErrorConstant(node, message, + context: context, isEvaluationError: true); } - /// Create an error-constant indicating a construct that should not occur - /// inside a potentially constant expression. - /// It is assumed that an error has already been reported. - AbortConstant createInvalidExpressionConstant(TreeNode node, String message) { - return new _AbortDueToInvalidExpressionConstant(node, message); + /// Create an error-constant indicating that an non-constant expression has + /// been found. + AbortConstant createExpressionErrorConstant(TreeNode node, Message message, + {List? context}) { + return new _AbortDueToErrorConstant(node, message, + context: context, isEvaluationError: false); } /// Produce an unevaluated constant node for an expression. @@ -1298,7 +1274,8 @@ class ConstantEvaluator implements ExpressionVisitor { if (cachedResult == null) { // [null] is a sentinel value only used when still evaluating the same // node. - return createErrorConstant(node, messageConstEvalCircularity); + return createEvaluationErrorConstant( + node, messageConstEvalCircularity); } result = cachedResult; } else { @@ -1322,7 +1299,8 @@ class ConstantEvaluator implements ExpressionVisitor { if (nodeCache[node] == null && !(enableConstFunctions && isRecursiveFunctionCall)) { // recursive call - return createErrorConstant(node, messageConstEvalCircularity); + return createEvaluationErrorConstant( + node, messageConstEvalCircularity); } // else we've seen the node before and come to a result -> we won't // go into an infinite loop here either. @@ -1349,12 +1327,12 @@ class ConstantEvaluator implements ExpressionVisitor { return _evaluateSubexpression(node); } + // TODO(johnniwinther): Remove this and handle each expression directly. @override Constant defaultExpression(Expression node) { // Only a subset of the expression language is valid for constant // evaluation. - return createInvalidExpressionConstant( - node, 'Constant evaluation has no support for ${node.runtimeType}!'); + return createExpressionErrorConstant(node, messageNotAConstantExpression); } @override @@ -1427,7 +1405,10 @@ class ConstantEvaluator implements ExpressionVisitor { @override Constant visitListLiteral(ListLiteral node) { if (!node.isConst && !enableConstFunctions) { - return createInvalidExpressionConstant(node, "Non-constant list literal"); + return createExpressionErrorConstant( + node, + templateNotConstantExpression + .withArguments('Non-constant list literal')); } final ListConstantBuilder builder = new ListConstantBuilder( node, convertType(node.typeArgument), this, @@ -1461,7 +1442,10 @@ class ConstantEvaluator implements ExpressionVisitor { @override Constant visitSetLiteral(SetLiteral node) { if (!node.isConst) { - return createInvalidExpressionConstant(node, "Non-constant set literal"); + return createExpressionErrorConstant( + node, + templateNotConstantExpression + .withArguments('Non-constant set literal')); } final SetConstantBuilder builder = new SetConstantBuilder(node, convertType(node.typeArgument), this); @@ -1494,7 +1478,10 @@ class ConstantEvaluator implements ExpressionVisitor { @override Constant visitMapLiteral(MapLiteral node) { if (!node.isConst) { - return createInvalidExpressionConstant(node, "Non-constant map literal"); + return createExpressionErrorConstant( + node, + templateNotConstantExpression + .withArguments('Non-constant map literal')); } final MapConstantBuilder builder = new MapConstantBuilder( node, convertType(node.keyType), convertType(node.valueType), this); @@ -1529,25 +1516,27 @@ class ConstantEvaluator implements ExpressionVisitor { if (enableConstFunctions) { return new FunctionValue(node.function, env); } - return createInvalidExpressionConstant(node, "Function literal"); + return createExpressionErrorConstant(node, + templateNotConstantExpression.withArguments('Function expression')); } @override Constant visitConstructorInvocation(ConstructorInvocation node) { if (!node.isConst && !enableConstFunctions) { - return createInvalidExpressionConstant( - node, 'Non-constant constructor invocation "$node".'); + return createExpressionErrorConstant( + node, templateNotConstantExpression.withArguments('New expression')); } final Constructor constructor = node.target; - AbortConstant? error = checkConstructorConst(node, constructor); + AbortConstant? error = + checkConstructorConst(node, constructor, messageNonConstConstructor); if (error != null) return error; final Class klass = constructor.enclosingClass; if (klass.isAbstract) { // Probably unreachable. - return createInvalidExpressionConstant( - node, 'Constructor "$node" belongs to abstract class "${klass}".'); + return createExpressionErrorConstant( + node, templateAbstractClassInstantiation.withArguments(klass.name)); } final List? positionals = @@ -1592,7 +1581,7 @@ class ConstantEvaluator implements ExpressionVisitor { (isNonNullableByDefault || isValidSymbolName(nameValue.value))) { return canonicalize(new SymbolConstant(nameValue.value, null)); } - return createErrorConstant( + return createEvaluationErrorConstant( node.arguments.positional.first, templateConstEvalInvalidSymbolName.withArguments( nameValue, isNonNullableByDefault)); @@ -1640,21 +1629,20 @@ class ConstantEvaluator implements ExpressionVisitor { /// Returns [null] on success and an error-"constant" on failure, as such the /// return value should be checked. - AbortConstant? checkConstructorConst(TreeNode node, Constructor constructor) { + AbortConstant? checkConstructorConst( + TreeNode node, Constructor constructor, Message messageIfNonConst) { if (!constructor.isConst) { - return createInvalidExpressionConstant( - node, 'Non-const constructor invocation.'); + return createExpressionErrorConstant(node, messageIfNonConst); } if (constructor.function.body != null && constructor.function.body is! EmptyStatement && !enableConstFunctions) { // Probably unreachable. - return createInvalidExpressionConstant( - node, - 'Constructor "$node" has non-trivial body ' - '"${constructor.function.body.runtimeType}".'); + return createExpressionErrorConstant( + node, messageConstConstructorWithBody); } else if (constructor.isExternal) { - return createErrorConstant(node, messageConstEvalExternalConstructor); + return createEvaluationErrorConstant( + node, messageConstEvalExternalConstructor); } return null; } @@ -1884,7 +1872,8 @@ class ConstantEvaluator implements ExpressionVisitor { if (constant is AbortConstant) return constant; env.addVariableValue(variable, constant); } else if (init is SuperInitializer) { - AbortConstant? error = checkConstructorConst(init, constructor); + AbortConstant? error = checkConstructorConst( + init, init.target, messageConstConstructorWithNonConstSuper); if (error != null) return error; List? types = _evaluateSuperTypeArguments( init, constructor.enclosingClass.supertype!); @@ -1923,7 +1912,9 @@ class ConstantEvaluator implements ExpressionVisitor { } else if (init is RedirectingInitializer) { // Since a redirecting constructor targets a constructor of the same // class, we pass the same [typeArguments]. - AbortConstant? error = checkConstructorConst(init, constructor); + + AbortConstant? error = checkConstructorConst( + init, init.target, messageConstConstructorRedirectionToNonConst); if (error != null) return error; List? positionalArguments = _evaluatePositionalArguments(init.arguments); @@ -1960,10 +1951,12 @@ class ConstantEvaluator implements ExpressionVisitor { // super that takes no arguments. It thus cannot be const. // Explicit constructors with incorrect super calls will get a // ShadowInvalidInitializer which is actually a LocalInitializer. - return createInvalidExpressionConstant( - constructor, + assert( + false, 'No support for handling initializer of type ' '"${init.runtimeType}".'); + return createEvaluationErrorConstant( + init, messageNotAConstantExpression); } } @@ -2003,7 +1996,7 @@ class ConstantEvaluator implements ExpressionVisitor { } else if (condition is BoolConstant) { if (!condition.value) { if (statement.message == null) { - return createErrorConstant( + return createEvaluationErrorConstant( statement.condition, messageConstEvalFailedAssertion); } final Constant message = _evaluateSubexpression(statement.message!); @@ -2014,12 +2007,12 @@ class ConstantEvaluator implements ExpressionVisitor { conditionStartOffset: statement.conditionStartOffset, conditionEndOffset: statement.conditionEndOffset)); } else if (message is StringConstant) { - return createErrorConstant( + return createEvaluationErrorConstant( statement.condition, templateConstEvalFailedAssertionWithMessage .withArguments(message.value)); } else { - return createErrorConstant( + return createEvaluationErrorConstant( statement.message!, templateConstEvalInvalidType.withArguments( message, @@ -2029,7 +2022,7 @@ class ConstantEvaluator implements ExpressionVisitor { } } } else { - return createErrorConstant( + return createEvaluationErrorConstant( statement.condition, templateConstEvalInvalidType.withArguments( condition, @@ -2043,21 +2036,22 @@ class ConstantEvaluator implements ExpressionVisitor { @override Constant visitInvalidExpression(InvalidExpression node) { - return createInvalidExpressionConstant(node, node.message ?? ''); + return new _AbortDueToInvalidExpressionConstant(node); } @override Constant visitDynamicInvocation(DynamicInvocation node) { // We have no support for generic method invocation at the moment. if (node.arguments.types.isNotEmpty) { - return createInvalidExpressionConstant(node, "generic method invocation"); + return createExpressionErrorConstant(node, + templateNotConstantExpression.withArguments("Dynamic invocation")); } // We have no support for method invocation with named arguments at the // moment. if (node.arguments.named.isNotEmpty) { - return createInvalidExpressionConstant( - node, "method invocation with named arguments"); + return createExpressionErrorConstant(node, + templateNotConstantExpression.withArguments("Dynamic invocation")); } final Constant receiver = _evaluateSubexpression(node.receiver); @@ -2094,14 +2088,15 @@ class ConstantEvaluator implements ExpressionVisitor { Constant visitInstanceInvocation(InstanceInvocation node) { // We have no support for generic method invocation at the moment. if (node.arguments.types.isNotEmpty) { - return createInvalidExpressionConstant(node, "generic method invocation"); + return createExpressionErrorConstant(node, + templateNotConstantExpression.withArguments("Instance invocation")); } // We have no support for method invocation with named arguments at the // moment. if (node.arguments.named.isNotEmpty) { - return createInvalidExpressionConstant( - node, "method invocation with named arguments"); + return createExpressionErrorConstant(node, + templateNotConstantExpression.withArguments("Instance invocation")); } final Constant receiver = _evaluateSubexpression(node.receiver); @@ -2140,7 +2135,8 @@ class ConstantEvaluator implements ExpressionVisitor { @override Constant visitFunctionInvocation(FunctionInvocation node) { if (!enableConstFunctions) { - return createInvalidExpressionConstant(node, "function invocation"); + return createExpressionErrorConstant(node, + templateNotConstantExpression.withArguments('Function invocation')); } final Constant receiver = _evaluateSubexpression(node.receiver); @@ -2152,7 +2148,10 @@ class ConstantEvaluator implements ExpressionVisitor { @override Constant visitLocalFunctionInvocation(LocalFunctionInvocation node) { if (!enableConstFunctions) { - return createInvalidExpressionConstant(node, "local function invocation"); + return createExpressionErrorConstant( + node, + templateNotConstantExpression + .withArguments('Local function invocation')); } final Constant receiver = env.lookupVariable(node.variable)!; @@ -2204,8 +2203,10 @@ class ConstantEvaluator implements ExpressionVisitor { receiver.function, types, arguments, named, functionEnvironment: receiver.environment); } else { - return createInvalidExpressionConstant( - node, "function invocation with invalid receiver"); + return createEvaluationErrorConstant( + node, + templateConstEvalError + .withArguments('Function invocation with invalid receiver.')); } } @@ -2252,7 +2253,7 @@ class ConstantEvaluator implements ExpressionVisitor { // to take the special cases into account. return doubleSpecialCases(left, right) ?? makeBoolConstant(left == right); } else { - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidEqualsOperandType.withArguments( left, left.getType(_staticTypeContext!), isNonNullableByDefault)); @@ -2288,7 +2289,7 @@ class ConstantEvaluator implements ExpressionVisitor { return canonicalize( new StringConstant(receiver.value + other.value)); } - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidBinaryOperandType.withArguments( '+', @@ -2306,7 +2307,7 @@ class ConstantEvaluator implements ExpressionVisitor { } return canonicalize(new StringConstant(receiver.value[index])); } - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidBinaryOperandType.withArguments( '[]', @@ -2328,7 +2329,7 @@ class ConstantEvaluator implements ExpressionVisitor { } else if (other is DoubleConstant) { if ((op == '|' || op == '&' || op == '^') || (op == '<<' || op == '>>' || op == '>>>')) { - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidBinaryOperandType.withArguments( op, @@ -2341,7 +2342,7 @@ class ConstantEvaluator implements ExpressionVisitor { return canonicalize(evaluateBinaryNumericOperation( op, receiverValue, other.value, node)); } - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidBinaryOperandType.withArguments( op, @@ -2353,7 +2354,7 @@ class ConstantEvaluator implements ExpressionVisitor { } else if (receiver is DoubleConstant) { if ((op == '|' || op == '&' || op == '^') || (op == '<<' || op == '>>' || op == '>>>')) { - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidBinaryOperandType.withArguments( op, @@ -2375,7 +2376,7 @@ class ConstantEvaluator implements ExpressionVisitor { return canonicalize( evaluateBinaryNumericOperation(op, receiver.value, value, node)); } - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidBinaryOperandType.withArguments( op, @@ -2402,7 +2403,7 @@ class ConstantEvaluator implements ExpressionVisitor { } } } else if (receiver is NullConstant) { - return createErrorConstant(node, messageConstEvalNullValue); + return createEvaluationErrorConstant(node, messageConstEvalNullValue); } else if (receiver is ListConstant && enableConstFunctions) { if (positionalArguments.length == 1) { final Constant other = positionalArguments[0]; @@ -2416,7 +2417,7 @@ class ConstantEvaluator implements ExpressionVisitor { } return receiver.entries[index]; } - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidBinaryOperandType.withArguments( '[]', @@ -2512,7 +2513,7 @@ class ConstantEvaluator implements ExpressionVisitor { } } - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidMethodInvocation.withArguments( op, receiver, isNonNullableByDefault)); @@ -2543,7 +2544,7 @@ class ConstantEvaluator implements ExpressionVisitor { return right; } - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidBinaryOperandType.withArguments( logicalExpressionOperatorToString(node.operatorEnum), @@ -2552,7 +2553,7 @@ class ConstantEvaluator implements ExpressionVisitor { right.getType(_staticTypeContext!), isNonNullableByDefault)); } - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidMethodInvocation.withArguments( logicalExpressionOperatorToString(node.operatorEnum), @@ -2568,7 +2569,7 @@ class ConstantEvaluator implements ExpressionVisitor { return right; } - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidBinaryOperandType.withArguments( logicalExpressionOperatorToString(node.operatorEnum), @@ -2577,7 +2578,7 @@ class ConstantEvaluator implements ExpressionVisitor { right.getType(_staticTypeContext!), isNonNullableByDefault)); } - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidMethodInvocation.withArguments( logicalExpressionOperatorToString(node.operatorEnum), @@ -2585,7 +2586,7 @@ class ConstantEvaluator implements ExpressionVisitor { isNonNullableByDefault)); default: // Probably unreachable. - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidMethodInvocation.withArguments( logicalExpressionOperatorToString(node.operatorEnum), @@ -2614,7 +2615,7 @@ class ConstantEvaluator implements ExpressionVisitor { new ConditionalExpression(extract(condition), extract(then), extract(otherwise), node.staticType)); } else { - return createErrorConstant( + return createEvaluationErrorConstant( node.condition, templateConstEvalInvalidType.withArguments( condition, @@ -2631,7 +2632,8 @@ class ConstantEvaluator implements ExpressionVisitor { // const. // Access "this" during instance creation. if (instanceBuilder == null) { - return createErrorConstant(node, messageNotAConstantExpression); + return createEvaluationErrorConstant( + node, messageNotAConstantExpression); } for (final MapEntry entry @@ -2645,8 +2647,11 @@ class ConstantEvaluator implements ExpressionVisitor { // Meant as a "stable backstop for situations where Fasta fails to // rewrite various erroneous constructs into invalid expressions". // Probably unreachable. - return createInvalidExpressionConstant(node, - 'Could not evaluate field get ${node.name} on incomplete instance'); + return createEvaluationErrorConstant( + node, + templateConstEvalError.withArguments( + 'Could not evaluate field get ${node.name} on incomplete ' + 'instance')); } final Constant receiver = _evaluateSubexpression(node.receiver); @@ -2660,7 +2665,7 @@ class ConstantEvaluator implements ExpressionVisitor { resultType: node.resultType, interfaceTarget: node.interfaceTarget)); } else if (receiver is NullConstant) { - return createErrorConstant(node, messageConstEvalNullValue); + return createEvaluationErrorConstant(node, messageConstEvalNullValue); } else if (receiver is ListConstant && enableConstFunctions) { switch (node.name.text) { case 'first': @@ -2702,7 +2707,7 @@ class ConstantEvaluator implements ExpressionVisitor { } } } - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidPropertyGet.withArguments( node.name.text, receiver, isNonNullableByDefault)); @@ -2718,9 +2723,9 @@ class ConstantEvaluator implements ExpressionVisitor { return unevaluated( node, new DynamicGet(node.kind, extract(receiver), node.name)); } else if (receiver is NullConstant) { - return createErrorConstant(node, messageConstEvalNullValue); + return createEvaluationErrorConstant(node, messageConstEvalNullValue); } - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidPropertyGet.withArguments( node.name.text, receiver, isNonNullableByDefault)); @@ -2730,7 +2735,7 @@ class ConstantEvaluator implements ExpressionVisitor { Constant visitInstanceTearOff(InstanceTearOff node) { final Constant receiver = _evaluateSubexpression(node.receiver); if (receiver is AbortConstant) return receiver; - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidPropertyGet.withArguments( node.name.text, receiver, isNonNullableByDefault)); @@ -2740,7 +2745,7 @@ class ConstantEvaluator implements ExpressionVisitor { Constant visitFunctionTearOff(FunctionTearOff node) { final Constant receiver = _evaluateSubexpression(node.receiver); if (receiver is AbortConstant) return receiver; - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidPropertyGet.withArguments( Name.callName.text, receiver, isNonNullableByDefault)); @@ -2765,14 +2770,14 @@ class ConstantEvaluator implements ExpressionVisitor { final VariableDeclaration variable = node.variable; if (enableConstFunctions) { return env.lookupVariable(variable) ?? - createErrorConstant( + createEvaluationErrorConstant( node, templateConstEvalGetterNotFound .withArguments(variable.name ?? '')); } else { if (variable.parent is Let || _isFormalParameter(variable)) { return env.lookupVariable(node.variable) ?? - createErrorConstant( + createEvaluationErrorConstant( node, templateConstEvalNonConstantVariableGet .withArguments(variable.name ?? '')); @@ -2781,8 +2786,10 @@ class ConstantEvaluator implements ExpressionVisitor { return _evaluateSubexpression(variable.initializer!); } } - return createInvalidExpressionConstant( - node, 'Variable get of a non-const variable.'); + return createExpressionErrorConstant( + node, + templateNotConstantExpression + .withArguments('Read of a non-const variable')); } @override @@ -2791,9 +2798,14 @@ class ConstantEvaluator implements ExpressionVisitor { final VariableDeclaration variable = node.variable; Constant value = _evaluateSubexpression(node.value); if (value is AbortConstant) return value; - return env.updateVariableValue(variable, value) ?? - createInvalidExpressionConstant( - node, 'Variable set of an unknown value.'); + Constant? result = env.updateVariableValue(variable, value); + if (result != null) { + return result; + } + return createEvaluationErrorConstant( + node, + templateConstEvalError + .withArguments('Variable set of an unknown value.')); } return defaultExpression(node); } @@ -2826,21 +2838,18 @@ class ConstantEvaluator implements ExpressionVisitor { if (target.isConst) { return _evaluateExpressionInContext(target, target.initializer!); } - return createErrorConstant( - node, - templateConstEvalInvalidStaticInvocation - .withArguments(target.name.text)); - } else if (target is Procedure) { - if (target.kind == ProcedureKind.Method) { - return canonicalize(new StaticTearOffConstant(target)); - } - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidStaticInvocation .withArguments(target.name.text)); + } else if (target is Procedure && target.kind == ProcedureKind.Method) { + // TODO(johnniwinther): Remove this. This should never occur. + return canonicalize(new StaticTearOffConstant(target)); } else { - return createInvalidExpressionConstant( - node, 'No support for ${target.runtimeType} in a static-get.'); + return createEvaluationErrorConstant( + node, + templateConstEvalInvalidStaticInvocation + .withArguments(target.name.text)); } }); } @@ -2875,7 +2884,7 @@ class ConstantEvaluator implements ExpressionVisitor { // error reporting till later. concatenated.add(constant); } else { - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidStringInterpolationOperand.withArguments( constant, isNonNullableByDefault)); @@ -3030,7 +3039,8 @@ class ConstantEvaluator implements ExpressionVisitor { return _handleHasEnvironment(name); } } else if (name is NullConstant) { - return createErrorConstant(node, messageConstEvalNullValue); + return createEvaluationErrorConstant( + node, messageConstEvalNullValue); } } else { // Leave environment constant unevaluated. @@ -3041,7 +3051,29 @@ class ConstantEvaluator implements ExpressionVisitor { isConst: true)); } } else if (target.isExternal) { - return createErrorConstant(node, messageConstEvalExternalFactory); + return createEvaluationErrorConstant( + node, messageConstEvalExternalFactory); + } else if (enableConstFunctions) { + return _handleFunctionInvocation( + node.target.function, typeArguments, positionals, named); + } else { + return createExpressionErrorConstant( + node, + templateNotConstantExpression + .withArguments('Non-redirecting const factory invocation')); + } + } else { + if (enableConstFunctions) { + return _handleFunctionInvocation( + node.target.function, typeArguments, positionals, named); + } else if (!node.isConst) { + return createExpressionErrorConstant(node, + templateNotConstantExpression.withArguments('New expression')); + } else { + return createEvaluationErrorConstant( + node, + templateNotConstantExpression + .withArguments('Non-const factory invocation')); } } } else if (target.name.text == 'identical') { @@ -3062,7 +3094,8 @@ class ConstantEvaluator implements ExpressionVisitor { Constant weakResult = makeBoolConstant( identical(weakLeft ?? left, weakRight ?? right)); if (!identical(result, weakResult)) { - return createErrorConstant(node, messageNonAgnosticConstant); + return createEvaluationErrorConstant( + node, messageNonAgnosticConstant); } } } @@ -3077,26 +3110,14 @@ class ConstantEvaluator implements ExpressionVisitor { return evaluateIdentical(); } } else if (target.isExtensionMember) { - return createErrorConstant(node, messageConstEvalExtension); + return createEvaluationErrorConstant(node, messageConstEvalExtension); } else if (enableConstFunctions && target.kind == ProcedureKind.Method) { return _handleFunctionInvocation( node.target.function, typeArguments, positionals, named); } - String name = target.name.text; - if (target.isFactory) { - if (name.isEmpty) { - name = target.enclosingClass!.name; - } else { - name = '${target.enclosingClass!.name}.${name}'; - } - - if (enableConstFunctions) { - return _handleFunctionInvocation( - node.target.function, typeArguments, positionals, named); - } - } - return createInvalidExpressionConstant(node, "Invocation of $name"); + return createExpressionErrorConstant( + node, templateNotConstantExpression.withArguments('Static invocation')); } Constant _handleFunctionInvocation( @@ -3132,7 +3153,7 @@ class ConstantEvaluator implements ExpressionVisitor { function.returnType.nullability == Nullability.nonNullable) { // Ensure that the evaluated constant returned is not null if the // function has a non-nullable return type. - return createErrorConstant( + return createEvaluationErrorConstant( function, templateConstEvalInvalidType.withArguments( result, @@ -3234,7 +3255,8 @@ class ConstantEvaluator implements ExpressionVisitor { Constant weakConstant = _weakener.visitConstant(constant) ?? constant; bool weakResult = performIs(weakConstant, strongMode: false); if (strongResult != weakResult) { - return createErrorConstant(node, messageNonAgnosticConstant); + return createEvaluationErrorConstant( + node, messageNonAgnosticConstant); } return makeBoolConstant(strongResult); case EvaluationMode.weak: @@ -3252,7 +3274,7 @@ class ConstantEvaluator implements ExpressionVisitor { if (shouldBeUnevaluated) { return unevaluated(node, new Not(extract(constant))); } - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidType.withArguments( constant, @@ -3266,7 +3288,7 @@ class ConstantEvaluator implements ExpressionVisitor { final Constant constant = _evaluateSubexpression(node.operand); if (constant is AbortConstant) return constant; if (constant is NullConstant) { - return createErrorConstant(node, messageConstEvalNonNull); + return createEvaluationErrorConstant(node, messageConstEvalNonNull); } if (shouldBeUnevaluated) { return unevaluated(node, new NullCheck(extract(constant))); @@ -3349,18 +3371,21 @@ class ConstantEvaluator implements ExpressionVisitor { new InstantiationConstant(constant, convertTypes(typeArguments))); } else { // Probably unreachable. - return createInvalidExpressionConstant( + return createEvaluationErrorConstant( node, - 'The number of type arguments supplied in the partial ' - 'instantiation does not match the number of type arguments ' - 'of the $constant.'); + templateConstEvalError.withArguments( + 'The number of type arguments supplied in the partial ' + 'instantiation does not match the number of type arguments ' + 'of the $constant.')); } } // The inner expression in an instantiation can never be null, since // instantiations are only inferred on direct references to declarations. // Probably unreachable. - return createInvalidExpressionConstant( - node, 'Only tear-off constants can be partially instantiated.'); + return createEvaluationErrorConstant( + node, + templateConstEvalError.withArguments( + 'Only tear-off constants can be partially instantiated.')); } @override @@ -3389,14 +3414,16 @@ class ConstantEvaluator implements ExpressionVisitor { new TypedefTearOffConstant(typeParameters, constant, typeArguments)); } else { // Probably unreachable. - return createInvalidExpressionConstant( - node, "Unexpected typedef tearoff target: ${constant}."); + return createEvaluationErrorConstant( + node, + templateConstEvalError.withArguments( + "Unsupported typedef tearoff target: ${constant}.")); } } @override Constant visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) { - return createErrorConstant(node, + return createEvaluationErrorConstant(node, templateConstEvalDeferredLibrary.withArguments(node.import.name!)); } @@ -3489,7 +3516,8 @@ class ConstantEvaluator implements ExpressionVisitor { bool weakResult = isSubtype( weakConstant, type, SubtypeCheckMode.ignoringNullabilities); if (strongResult != weakResult) { - return createErrorConstant(node, messageNonAgnosticConstant); + return createEvaluationErrorConstant( + node, messageNonAgnosticConstant); } result = strongResult; break; @@ -3499,7 +3527,7 @@ class ConstantEvaluator implements ExpressionVisitor { break; } if (!result) { - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalInvalidType.withArguments(constant, type, constant.getType(_staticTypeContext!), isNonNullableByDefault)); @@ -3552,7 +3580,7 @@ class ConstantEvaluator implements ExpressionVisitor { final DartType result = env.substituteType(type); if (!isInstantiated(result)) { - _gotError = createErrorConstant( + _gotError = createEvaluationErrorConstant( node, templateConstEvalFreeTypeParameter.withArguments( type, isNonNullableByDefault)); @@ -3663,7 +3691,7 @@ class ConstantEvaluator implements ExpressionVisitor { return new DoubleConstant(a / b); case '~/': if (b == 0) { - return createErrorConstant( + return createEvaluationErrorConstant( node, templateConstEvalZeroDivisor.withArguments(op, '$a')); } return intFolder.truncatingDivide(node, a, b); @@ -3683,8 +3711,8 @@ class ConstantEvaluator implements ExpressionVisitor { } // Probably unreachable. - return createInvalidExpressionConstant( - node, "Unexpected binary numeric operation '$op'."); + return createExpressionErrorConstant(node, + templateNotConstantExpression.withArguments("Binary '$op' operation")); } // TODO(johnniwinther): Remove the need for this by adding a current library @@ -4262,8 +4290,10 @@ class _AbortDueToErrorConstant extends AbortConstant { final TreeNode node; final Message message; final List? context; + final bool isEvaluationError; - _AbortDueToErrorConstant(this.node, this.message, {this.context}); + _AbortDueToErrorConstant(this.node, this.message, + {this.context, required this.isEvaluationError}); @override R accept(ConstantVisitor v) { @@ -4327,10 +4357,9 @@ class _AbortDueToErrorConstant extends AbortConstant { } class _AbortDueToInvalidExpressionConstant extends AbortConstant { - final TreeNode node; - final String message; + final InvalidExpression node; - _AbortDueToInvalidExpressionConstant(this.node, this.message); + _AbortDueToInvalidExpressionConstant(this.node); @override R accept(ConstantVisitor v) { @@ -4463,16 +4492,14 @@ class _AbortDueToThrowConstant extends AbortConstant { abstract class ErrorReporter { const ErrorReporter(); - void report(LocatedMessage message, List? context); - - void reportInvalidExpression(InvalidExpression node); + void report(LocatedMessage message, [List? context]); } class SimpleErrorReporter implements ErrorReporter { const SimpleErrorReporter(); @override - void report(LocatedMessage message, List? context) { + void report(LocatedMessage message, [List? context]) { _report(message); if (context != null) { for (LocatedMessage contextMessage in context) { @@ -4481,11 +4508,6 @@ class SimpleErrorReporter implements ErrorReporter { } } - @override - void reportInvalidExpression(InvalidExpression node) { - // Ignored - } - void _report(LocatedMessage message) { reportMessage(message.uri, message.charOffset, message.message); } diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_int_folder.dart b/pkg/front_end/lib/src/fasta/kernel/constant_int_folder.dart index 8ffd6f54873..452ad531171 100644 --- a/pkg/front_end/lib/src/fasta/kernel/constant_int_folder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/constant_int_folder.dart @@ -7,11 +7,7 @@ import 'package:kernel/target/targets.dart'; import 'constant_evaluator.dart'; -import '../fasta_codes.dart' - show - templateConstEvalNegativeShift, - templateConstEvalTruncateError, - templateConstEvalZeroDivisor; +import '../fasta_codes.dart'; abstract class ConstantIntFolder { final ConstantEvaluator evaluator; @@ -52,11 +48,11 @@ abstract class ConstantIntFolder { AbortConstant? _checkOperands( Expression node, String op, num left, num right) { if ((op == '<<' || op == '>>' || op == '>>>') && right < 0) { - return evaluator.createErrorConstant(node, + return evaluator.createEvaluationErrorConstant(node, templateConstEvalNegativeShift.withArguments(op, '$left', '$right')); } if ((op == '%' || op == '~/') && right == 0) { - return evaluator.createErrorConstant( + return evaluator.createEvaluationErrorConstant( node, templateConstEvalZeroDivisor.withArguments(op, '$left')); } return null; @@ -91,8 +87,10 @@ class VmConstantIntFolder extends ConstantIntFolder { return new IntConstant(~operand.value); default: // Probably unreachable. - return evaluator.createInvalidExpressionConstant( - node, "Invalid unary operator $op"); + return evaluator.createExpressionErrorConstant( + node, + templateNotConstantExpression + .withArguments("Unary '$op' operation")); } } @@ -140,8 +138,10 @@ class VmConstantIntFolder extends ConstantIntFolder { return evaluator.makeBoolConstant(a > b); default: // Probably unreachable. - return evaluator.createInvalidExpressionConstant( - node, "Invalid binary operator $op"); + return evaluator.createExpressionErrorConstant( + node, + templateNotConstantExpression + .withArguments("Binary '$op' operation")); } } @@ -150,7 +150,7 @@ class VmConstantIntFolder extends ConstantIntFolder { try { return new IntConstant(left ~/ right); } catch (e) { - return evaluator.createErrorConstant(node, + return evaluator.createEvaluationErrorConstant(node, templateConstEvalTruncateError.withArguments('$left', '$right')); } } @@ -204,8 +204,10 @@ class JsConstantIntFolder extends ConstantIntFolder { return new DoubleConstant(_truncate32(~intValue).toDouble()); default: // Probably unreachable. - return evaluator.createInvalidExpressionConstant( - node, "Invalid unary operator $op"); + return evaluator.createExpressionErrorConstant( + node, + templateNotConstantExpression + .withArguments("Unary '$op' operation")); } } @@ -259,8 +261,10 @@ class JsConstantIntFolder extends ConstantIntFolder { return evaluator.makeBoolConstant(a > b); default: // Probably unreachable. - return evaluator.createInvalidExpressionConstant( - node, "Invalid binary operator $op"); + return evaluator.createExpressionErrorConstant( + node, + templateNotConstantExpression + .withArguments("Binary '$op' operation")); } } @@ -268,7 +272,7 @@ class JsConstantIntFolder extends ConstantIntFolder { Constant truncatingDivide(Expression node, num left, num right) { double division = (left / right); if (division.isNaN || division.isInfinite) { - return evaluator.createErrorConstant(node, + return evaluator.createEvaluationErrorConstant(node, templateConstEvalTruncateError.withArguments('$left', '${right}')); } double result = division.truncateToDouble(); diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart index 0ae336de957..44e0227742e 100644 --- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart +++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart @@ -2898,8 +2898,12 @@ class DeferredAccessGenerator extends Generator { _uri, charOffset, lengthOfSpan(prefixGenerator.token, token)); } // TODO(johnniwinther): Could we use a FixedTypeBuilder(InvalidType()) here? - NamedTypeBuilder result = new NamedTypeBuilder(name, nullabilityBuilder, - /* arguments = */ null, /* fileUri = */ null, /* charOffset = */ null); + NamedTypeBuilder result = new NamedTypeBuilder( + name, + nullabilityBuilder, + /* arguments = */ null, + /* fileUri = */ null, + /* charOffset = */ null); _helper.libraryBuilder.addProblem( message.messageObject, message.charOffset, message.length, message.uri); result.bind(result.buildInvalidTypeDeclarationBuilder(message)); diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart index d0033faf0b3..f17d67e6ed3 100644 --- a/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart +++ b/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart @@ -4,8 +4,6 @@ library fasta.kernel_constants; -import 'package:kernel/ast.dart' show InvalidExpression; - import '../builder/library_builder.dart'; import '../fasta_codes.dart' show LocatedMessage; @@ -20,7 +18,7 @@ class KernelConstantErrorReporter extends ErrorReporter { KernelConstantErrorReporter(this.loader); @override - void report(LocatedMessage message, List? context) { + void report(LocatedMessage message, [List? context]) { // Try to find library. LibraryBuilder? builder = loader.builders[message.uri]; if (builder == null) { @@ -43,20 +41,4 @@ class KernelConstantErrorReporter extends ErrorReporter { context: context); } } - - @override - void reportInvalidExpression(InvalidExpression node) { - // TODO(johnniwinther): Improve the precision of this assertion. Do we - // for instance allow warnings only to have been reported in previous - // compilations. - assert( - // Either we have already reported an error - loader.hasSeenError || - // or we have reported an error in a previous compilation. - loader.builders.values.any((builder) => - builder.library.problemsAsJson?.isNotEmpty ?? false), - "No error reported before seeing: " - "${node.message}"); - // Assumed to be already reported. - } } diff --git a/pkg/front_end/lib/src/testing/id_extractor.dart b/pkg/front_end/lib/src/testing/id_extractor.dart index 13229aa703e..705c7830c3f 100644 --- a/pkg/front_end/lib/src/testing/id_extractor.dart +++ b/pkg/front_end/lib/src/testing/id_extractor.dart @@ -600,7 +600,10 @@ abstract class DataExtractor extends Visitor @override visitInvalidExpression(InvalidExpression node) { - computeForNode(node, computeDefaultNodeId(node)); + // Invalid expressions produced in the constant evaluator don't have a + // file offset. + computeForNode( + node, computeDefaultNodeId(node, skipNodeWithNoOffset: true)); return super.visitInvalidExpression(node); } } diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status index 0f446e2ff8f..67c3c4fa230 100644 --- a/pkg/front_end/messages.status +++ b/pkg/front_end/messages.status @@ -102,6 +102,8 @@ ConstEvalDeferredLibrary/example: Fail ConstEvalDuplicateElement/example: Fail ConstEvalDuplicateKey/example: Fail ConstEvalElementImplementsEqual/example: Fail +ConstEvalError/analyzerCode: Fail +ConstEvalError/example: Fail ConstEvalExtension/example: Fail ConstEvalExternalConstructor/analyzerCode: Fail ConstEvalExternalConstructor/example: Fail diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml index 681d3b4d62d..e6c77d05126 100644 --- a/pkg/front_end/messages.yaml +++ b/pkg/front_end/messages.yaml @@ -228,6 +228,9 @@ ConstEvalExternalFactory: ConstEvalUnevaluated: template: "Couldn't evaluate constant expression." +ConstEvalError: + template: "Error evaluating constant expression: #string" + ConstEvalUnhandledCoreException: template: "Unhandled core exception: #stringOKEmpty" diff --git a/pkg/front_end/test/constant_evaluator_benchmark.dart b/pkg/front_end/test/constant_evaluator_benchmark.dart index 4595cf8dd74..ff7ee82ef1a 100644 --- a/pkg/front_end/test/constant_evaluator_benchmark.dart +++ b/pkg/front_end/test/constant_evaluator_benchmark.dart @@ -125,12 +125,7 @@ void benchmark(Component component, List libraries) { class SilentErrorReporter implements constants.ErrorReporter { @override - void report(LocatedMessage message, List context) { - // ignore - } - - @override - void reportInvalidExpression(InvalidExpression node) { + void report(LocatedMessage message, [List context]) { // ignore } } diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart index b35320ca5c0..c07935bed12 100644 --- a/pkg/front_end/test/fasta/testing/suite.dart +++ b/pkg/front_end/test/fasta/testing/suite.dart @@ -1030,12 +1030,7 @@ class StressConstantEvaluatorVisitor extends RecursiveResultVisitor } @override - void report(LocatedMessage message, List context) { - // ignored. - } - - @override - void reportInvalidExpression(InvalidExpression node) { + void report(LocatedMessage message, [List context]) { // ignored. } } diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt index 89c8686770d..373ae97b329 100644 --- a/pkg/front_end/test/spell_checking_list_tests.txt +++ b/pkg/front_end/test/spell_checking_list_tests.txt @@ -209,6 +209,7 @@ confirm consecutive considering consist +constr constrains consts contract diff --git a/pkg/front_end/testcases/const_functions/non_function_invocation.dart b/pkg/front_end/testcases/const_functions/non_function_invocation.dart new file mode 100644 index 00000000000..a23de2a768d --- /dev/null +++ b/pkg/front_end/testcases/const_functions/non_function_invocation.dart @@ -0,0 +1,8 @@ +// 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. + +const dynamic a = null; +const dynamic b = a(); + +main() {} diff --git a/pkg/front_end/testcases/const_functions/non_function_invocation.dart.strong.expect b/pkg/front_end/testcases/const_functions/non_function_invocation.dart.strong.expect new file mode 100644 index 00000000000..a98efbdf83d --- /dev/null +++ b/pkg/front_end/testcases/const_functions/non_function_invocation.dart.strong.expect @@ -0,0 +1,23 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:20: Error: Constant evaluation error: +// const dynamic b = a(); +// ^ +// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:20: Context: Null value during constant evaluation. +// const dynamic b = a(); +// ^ +// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:15: Context: While analyzing: +// const dynamic b = a(); +// ^ +// +import self as self; + +static const field dynamic a = #C1; +static const field dynamic b = invalid-expression "Null value during constant evaluation."; +static method main() → dynamic {} + +constants { + #C1 = null +} diff --git a/pkg/front_end/testcases/const_functions/non_function_invocation.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/non_function_invocation.dart.strong.transformed.expect new file mode 100644 index 00000000000..a98efbdf83d --- /dev/null +++ b/pkg/front_end/testcases/const_functions/non_function_invocation.dart.strong.transformed.expect @@ -0,0 +1,23 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:20: Error: Constant evaluation error: +// const dynamic b = a(); +// ^ +// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:20: Context: Null value during constant evaluation. +// const dynamic b = a(); +// ^ +// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:15: Context: While analyzing: +// const dynamic b = a(); +// ^ +// +import self as self; + +static const field dynamic a = #C1; +static const field dynamic b = invalid-expression "Null value during constant evaluation."; +static method main() → dynamic {} + +constants { + #C1 = null +} diff --git a/pkg/front_end/testcases/const_functions/non_function_invocation.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/non_function_invocation.dart.textual_outline.expect new file mode 100644 index 00000000000..ce635b77040 --- /dev/null +++ b/pkg/front_end/testcases/const_functions/non_function_invocation.dart.textual_outline.expect @@ -0,0 +1,3 @@ +const dynamic a = null; +const dynamic b = a(); +main() {} diff --git a/pkg/front_end/testcases/const_functions/non_function_invocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/const_functions/non_function_invocation.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..ce635b77040 --- /dev/null +++ b/pkg/front_end/testcases/const_functions/non_function_invocation.dart.textual_outline_modelled.expect @@ -0,0 +1,3 @@ +const dynamic a = null; +const dynamic b = a(); +main() {} diff --git a/pkg/front_end/testcases/const_functions/non_function_invocation.dart.weak.expect b/pkg/front_end/testcases/const_functions/non_function_invocation.dart.weak.expect new file mode 100644 index 00000000000..a98efbdf83d --- /dev/null +++ b/pkg/front_end/testcases/const_functions/non_function_invocation.dart.weak.expect @@ -0,0 +1,23 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:20: Error: Constant evaluation error: +// const dynamic b = a(); +// ^ +// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:20: Context: Null value during constant evaluation. +// const dynamic b = a(); +// ^ +// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:15: Context: While analyzing: +// const dynamic b = a(); +// ^ +// +import self as self; + +static const field dynamic a = #C1; +static const field dynamic b = invalid-expression "Null value during constant evaluation."; +static method main() → dynamic {} + +constants { + #C1 = null +} diff --git a/pkg/front_end/testcases/const_functions/non_function_invocation.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/non_function_invocation.dart.weak.outline.expect new file mode 100644 index 00000000000..bb4027082a6 --- /dev/null +++ b/pkg/front_end/testcases/const_functions/non_function_invocation.dart.weak.outline.expect @@ -0,0 +1,12 @@ +library /*isNonNullableByDefault*/; +import self as self; + +static const field dynamic a = null; +static const field dynamic b = self::a{dynamic}.call(); +static method main() → dynamic + ; + + +Extra constant evaluation status: +Evaluated: StaticGet @ org-dartlang-testcase:///non_function_invocation.dart:6:19 -> NullConstant(null) +Extra constant evaluation: evaluated: 2, effectively constant: 1 diff --git a/pkg/front_end/testcases/const_functions/non_function_invocation.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/non_function_invocation.dart.weak.transformed.expect new file mode 100644 index 00000000000..a98efbdf83d --- /dev/null +++ b/pkg/front_end/testcases/const_functions/non_function_invocation.dart.weak.transformed.expect @@ -0,0 +1,23 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:20: Error: Constant evaluation error: +// const dynamic b = a(); +// ^ +// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:20: Context: Null value during constant evaluation. +// const dynamic b = a(); +// ^ +// pkg/front_end/testcases/const_functions/non_function_invocation.dart:6:15: Context: While analyzing: +// const dynamic b = a(); +// ^ +// +import self as self; + +static const field dynamic a = #C1; +static const field dynamic b = invalid-expression "Null value during constant evaluation."; +static method main() → dynamic {} + +constants { + #C1 = null +} diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart b/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart new file mode 100644 index 00000000000..016df79b7fa --- /dev/null +++ b/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart @@ -0,0 +1,26 @@ +// 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. + + +class MyClass { + final a; + const MyClass(int i, int j) : a = (i + j); + const MyClass.constr() : a = 0; +} + +test() { + const v1 = MyClass.new; + const v2 = MyClass.constr; + const v3 = MyClass.new; + const v4 = MyClass.constr; + + const c1 = v1(3, 14); + const c2 = v1(3, 14); + const c3 = v2(); + const c4 = v2(); + const c5 = v3(3, 14); + const c6 = v4(); +} + +main() {} \ No newline at end of file diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.strong.expect new file mode 100644 index 00000000000..9c76f69e482 --- /dev/null +++ b/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.strong.expect @@ -0,0 +1,49 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:18:16: Error: Function invocation is not a constant expression. +// const c1 = v1(3, 14); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:19:16: Error: Function invocation is not a constant expression. +// const c2 = v1(3, 14); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:20:16: Error: Function invocation is not a constant expression. +// const c3 = v2(); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:21:16: Error: Function invocation is not a constant expression. +// const c4 = v2(); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:22:16: Error: Function invocation is not a constant expression. +// const c5 = v3(3, 14); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:23:16: Error: Function invocation is not a constant expression. +// const c6 = v4(); +// ^ +// +import self as self; +import "dart:core" as core; + +class MyClass extends core::Object /*hasConstConstructor*/ { + final field dynamic a; + const constructor •(core::int i, core::int j) → self::MyClass + : self::MyClass::a = i.{core::num::+}(j){(core::num) → core::int}, super core::Object::•() + ; + const constructor constr() → self::MyClass + : self::MyClass::a = 0, super core::Object::•() + ; +} +static method test() → dynamic { + const self::MyClass c1 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c2 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c3 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c4 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c5 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c6 = invalid-expression "Function invocation is not a constant expression."; +} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.strong.transformed.expect new file mode 100644 index 00000000000..9c76f69e482 --- /dev/null +++ b/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.strong.transformed.expect @@ -0,0 +1,49 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:18:16: Error: Function invocation is not a constant expression. +// const c1 = v1(3, 14); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:19:16: Error: Function invocation is not a constant expression. +// const c2 = v1(3, 14); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:20:16: Error: Function invocation is not a constant expression. +// const c3 = v2(); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:21:16: Error: Function invocation is not a constant expression. +// const c4 = v2(); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:22:16: Error: Function invocation is not a constant expression. +// const c5 = v3(3, 14); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:23:16: Error: Function invocation is not a constant expression. +// const c6 = v4(); +// ^ +// +import self as self; +import "dart:core" as core; + +class MyClass extends core::Object /*hasConstConstructor*/ { + final field dynamic a; + const constructor •(core::int i, core::int j) → self::MyClass + : self::MyClass::a = i.{core::num::+}(j){(core::num) → core::int}, super core::Object::•() + ; + const constructor constr() → self::MyClass + : self::MyClass::a = 0, super core::Object::•() + ; +} +static method test() → dynamic { + const self::MyClass c1 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c2 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c3 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c4 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c5 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c6 = invalid-expression "Function invocation is not a constant expression."; +} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.textual_outline.expect b/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.textual_outline.expect new file mode 100644 index 00000000000..62af4b808a9 --- /dev/null +++ b/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.textual_outline.expect @@ -0,0 +1,8 @@ +class MyClass { + final a; + const MyClass(int i, int j) : a = (i + j); + const MyClass.constr() : a = 0; +} + +test() {} +main() {} diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..831b45836f1 --- /dev/null +++ b/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.textual_outline_modelled.expect @@ -0,0 +1,8 @@ +class MyClass { + const MyClass(int i, int j) : a = (i + j); + const MyClass.constr() : a = 0; + final a; +} + +main() {} +test() {} diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.weak.expect new file mode 100644 index 00000000000..9c76f69e482 --- /dev/null +++ b/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.weak.expect @@ -0,0 +1,49 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:18:16: Error: Function invocation is not a constant expression. +// const c1 = v1(3, 14); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:19:16: Error: Function invocation is not a constant expression. +// const c2 = v1(3, 14); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:20:16: Error: Function invocation is not a constant expression. +// const c3 = v2(); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:21:16: Error: Function invocation is not a constant expression. +// const c4 = v2(); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:22:16: Error: Function invocation is not a constant expression. +// const c5 = v3(3, 14); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:23:16: Error: Function invocation is not a constant expression. +// const c6 = v4(); +// ^ +// +import self as self; +import "dart:core" as core; + +class MyClass extends core::Object /*hasConstConstructor*/ { + final field dynamic a; + const constructor •(core::int i, core::int j) → self::MyClass + : self::MyClass::a = i.{core::num::+}(j){(core::num) → core::int}, super core::Object::•() + ; + const constructor constr() → self::MyClass + : self::MyClass::a = 0, super core::Object::•() + ; +} +static method test() → dynamic { + const self::MyClass c1 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c2 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c3 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c4 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c5 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c6 = invalid-expression "Function invocation is not a constant expression."; +} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.weak.outline.expect new file mode 100644 index 00000000000..e701b2d1912 --- /dev/null +++ b/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.weak.outline.expect @@ -0,0 +1,17 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +class MyClass extends core::Object /*hasConstConstructor*/ { + final field dynamic a; + const constructor •(core::int i, core::int j) → self::MyClass + : self::MyClass::a = i.{core::num::+}(j){(core::num) → core::int}, super core::Object::•() + ; + const constructor constr() → self::MyClass + : self::MyClass::a = 0, super core::Object::•() + ; +} +static method test() → dynamic + ; +static method main() → dynamic + ; diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.weak.transformed.expect new file mode 100644 index 00000000000..9c76f69e482 --- /dev/null +++ b/pkg/front_end/testcases/constructor_tearoffs/issue46925.dart.weak.transformed.expect @@ -0,0 +1,49 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:18:16: Error: Function invocation is not a constant expression. +// const c1 = v1(3, 14); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:19:16: Error: Function invocation is not a constant expression. +// const c2 = v1(3, 14); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:20:16: Error: Function invocation is not a constant expression. +// const c3 = v2(); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:21:16: Error: Function invocation is not a constant expression. +// const c4 = v2(); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:22:16: Error: Function invocation is not a constant expression. +// const c5 = v3(3, 14); +// ^ +// +// pkg/front_end/testcases/constructor_tearoffs/issue46925.dart:23:16: Error: Function invocation is not a constant expression. +// const c6 = v4(); +// ^ +// +import self as self; +import "dart:core" as core; + +class MyClass extends core::Object /*hasConstConstructor*/ { + final field dynamic a; + const constructor •(core::int i, core::int j) → self::MyClass + : self::MyClass::a = i.{core::num::+}(j){(core::num) → core::int}, super core::Object::•() + ; + const constructor constr() → self::MyClass + : self::MyClass::a = 0, super core::Object::•() + ; +} +static method test() → dynamic { + const self::MyClass c1 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c2 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c3 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c4 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c5 = invalid-expression "Function invocation is not a constant expression."; + const self::MyClass c6 = invalid-expression "Function invocation is not a constant expression."; +} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart index 89c77a67eed..35490303472 100644 --- a/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart +++ b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart @@ -1,7 +1,7 @@ // 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. -// @dart=2.9 + class A { const A() : this.bad(); diff --git a/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline.expect b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline.expect index c7cfcc7dd51..8d81665e547 100644 --- a/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline.expect +++ b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline.expect @@ -1,4 +1,3 @@ -// @dart = 2.9 class A { const A() : this.bad(); A.bad() {} diff --git a/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline_modelled.expect index d07c96d1fbb..bee691e0dc2 100644 --- a/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline_modelled.expect +++ b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline_modelled.expect @@ -1,4 +1,3 @@ -// @dart = 2.9 class A { A.bad() {} const A() : this.bad(); diff --git a/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.weak.expect b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.weak.expect index 94978d1745f..38baae20309 100644 --- a/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.weak.expect +++ b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.weak.expect @@ -1,4 +1,4 @@ -library; +library /*isNonNullableByDefault*/; // // Problems in library: // @@ -14,30 +14,20 @@ import self as self; import "dart:core" as core; class A extends core::Object /*hasConstConstructor*/ { - const constructor •() → self::A* + const constructor •() → self::A : this self::A::bad() ; - constructor bad() → self::A* + constructor bad() → self::A : super core::Object::•() {} - abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode - abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf - abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf - abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue - abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse - abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::== - abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode - abstract member-signature method toString() → core::String*; -> core::Object::toString - abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod - abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType } class B extends self::A /*hasConstConstructor*/ { - const constructor •() → self::B* + const constructor •() → self::B : super self::A::bad() ; } static method test() → dynamic { - core::print(invalid-expression "Non-const constructor invocation."); - core::print(invalid-expression "Non-const constructor invocation."); + core::print(invalid-expression "A constant constructor can't call a non-constant constructor."); + core::print(invalid-expression "A constant constructor can't call a non-constant super constructor."); } static method main() → dynamic { core::print(new self::A::•()); @@ -49,5 +39,4 @@ static method main() → dynamic { Constructor coverage from constants: org-dartlang-testcase:///const_redirect_to_nonconst.dart: - A. (from org-dartlang-testcase:///const_redirect_to_nonconst.dart:6:9) -- A.bad (from org-dartlang-testcase:///const_redirect_to_nonconst.dart:8:3) - B. (from org-dartlang-testcase:///const_redirect_to_nonconst.dart:12:9) diff --git a/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.weak.outline.expect b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.weak.outline.expect index 13e7c4369f1..ed9eb741d53 100644 --- a/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.weak.outline.expect +++ b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.weak.outline.expect @@ -1,4 +1,4 @@ -library; +library /*isNonNullableByDefault*/; // // Problems in library: // @@ -10,24 +10,14 @@ import self as self; import "dart:core" as core; class A extends core::Object /*hasConstConstructor*/ { - const constructor •() → self::A* + const constructor •() → self::A : this self::A::bad() ; - constructor bad() → self::A* + constructor bad() → self::A ; - abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode - abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf - abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf - abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue - abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse - abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::== - abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode - abstract member-signature method toString() → core::String*; -> core::Object::toString - abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod - abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType } class B extends self::A /*hasConstConstructor*/ { - const constructor •() → self::B* + const constructor •() → self::B : super self::A::bad() ; } diff --git a/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.weak.transformed.expect b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.weak.transformed.expect index 94978d1745f..38baae20309 100644 --- a/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.weak.transformed.expect @@ -1,4 +1,4 @@ -library; +library /*isNonNullableByDefault*/; // // Problems in library: // @@ -14,30 +14,20 @@ import self as self; import "dart:core" as core; class A extends core::Object /*hasConstConstructor*/ { - const constructor •() → self::A* + const constructor •() → self::A : this self::A::bad() ; - constructor bad() → self::A* + constructor bad() → self::A : super core::Object::•() {} - abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode - abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf - abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf - abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue - abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse - abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::== - abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode - abstract member-signature method toString() → core::String*; -> core::Object::toString - abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod - abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType } class B extends self::A /*hasConstConstructor*/ { - const constructor •() → self::B* + const constructor •() → self::B : super self::A::bad() ; } static method test() → dynamic { - core::print(invalid-expression "Non-const constructor invocation."); - core::print(invalid-expression "Non-const constructor invocation."); + core::print(invalid-expression "A constant constructor can't call a non-constant constructor."); + core::print(invalid-expression "A constant constructor can't call a non-constant super constructor."); } static method main() → dynamic { core::print(new self::A::•()); @@ -49,5 +39,4 @@ static method main() → dynamic { Constructor coverage from constants: org-dartlang-testcase:///const_redirect_to_nonconst.dart: - A. (from org-dartlang-testcase:///const_redirect_to_nonconst.dart:6:9) -- A.bad (from org-dartlang-testcase:///const_redirect_to_nonconst.dart:8:3) - B. (from org-dartlang-testcase:///const_redirect_to_nonconst.dart:12:9) diff --git a/pkg/front_end/testcases/general/constants/function_invocation.dart b/pkg/front_end/testcases/general/constants/function_invocation.dart new file mode 100644 index 00000000000..903e3059627 --- /dev/null +++ b/pkg/front_end/testcases/general/constants/function_invocation.dart @@ -0,0 +1,9 @@ +// 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. + +method() {} +const tearOff = method; +const invocation = tearOff(); + +main() {} diff --git a/pkg/front_end/testcases/general/constants/function_invocation.dart.textual_outline.expect b/pkg/front_end/testcases/general/constants/function_invocation.dart.textual_outline.expect new file mode 100644 index 00000000000..a69fea2e0d6 --- /dev/null +++ b/pkg/front_end/testcases/general/constants/function_invocation.dart.textual_outline.expect @@ -0,0 +1,4 @@ +method() {} +const tearOff = method; +const invocation = tearOff(); +main() {} diff --git a/pkg/front_end/testcases/general/constants/function_invocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/constants/function_invocation.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..502cda9f0eb --- /dev/null +++ b/pkg/front_end/testcases/general/constants/function_invocation.dart.textual_outline_modelled.expect @@ -0,0 +1,4 @@ +const invocation = tearOff(); +const tearOff = method; +main() {} +method() {} diff --git a/pkg/front_end/testcases/general/constants/function_invocation.dart.weak.expect b/pkg/front_end/testcases/general/constants/function_invocation.dart.weak.expect new file mode 100644 index 00000000000..ade1d0579c3 --- /dev/null +++ b/pkg/front_end/testcases/general/constants/function_invocation.dart.weak.expect @@ -0,0 +1,20 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/constants/function_invocation.dart:7:20: Error: Method invocation is not a constant expression. +// const invocation = tearOff(); +// ^^^^^^^ +// +import self as self; + +static const field () → dynamic tearOff = #C1; +static const field invalid-type invocation = invalid-expression "pkg/front_end/testcases/general/constants/function_invocation.dart:7:20: Error: Method invocation is not a constant expression. +const invocation = tearOff(); + ^^^^^^^"; +static method method() → dynamic {} +static method main() → dynamic {} + +constants { + #C1 = static-tearoff self::method +} diff --git a/pkg/front_end/testcases/general/constants/function_invocation.dart.weak.outline.expect b/pkg/front_end/testcases/general/constants/function_invocation.dart.weak.outline.expect new file mode 100644 index 00000000000..e9cad486a7f --- /dev/null +++ b/pkg/front_end/testcases/general/constants/function_invocation.dart.weak.outline.expect @@ -0,0 +1,23 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/constants/function_invocation.dart:7:20: Error: Method invocation is not a constant expression. +// const invocation = tearOff(); +// ^^^^^^^ +// +import self as self; + +static const field () → dynamic tearOff = self::method; +static const field invalid-type invocation = invalid-expression "pkg/front_end/testcases/general/constants/function_invocation.dart:7:20: Error: Method invocation is not a constant expression. +const invocation = tearOff(); + ^^^^^^^"; +static method method() → dynamic + ; +static method main() → dynamic + ; + + +Extra constant evaluation status: +Evaluated: StaticTearOff @ org-dartlang-testcase:///function_invocation.dart:6:17 -> StaticTearOffConstant(method) +Extra constant evaluation: evaluated: 1, effectively constant: 1 diff --git a/pkg/front_end/testcases/general/constants/function_invocation.dart.weak.transformed.expect b/pkg/front_end/testcases/general/constants/function_invocation.dart.weak.transformed.expect new file mode 100644 index 00000000000..ade1d0579c3 --- /dev/null +++ b/pkg/front_end/testcases/general/constants/function_invocation.dart.weak.transformed.expect @@ -0,0 +1,20 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/constants/function_invocation.dart:7:20: Error: Method invocation is not a constant expression. +// const invocation = tearOff(); +// ^^^^^^^ +// +import self as self; + +static const field () → dynamic tearOff = #C1; +static const field invalid-type invocation = invalid-expression "pkg/front_end/testcases/general/constants/function_invocation.dart:7:20: Error: Method invocation is not a constant expression. +const invocation = tearOff(); + ^^^^^^^"; +static method method() → dynamic {} +static method main() → dynamic {} + +constants { + #C1 = static-tearoff self::method +} diff --git a/pkg/front_end/testcases/general/constants/issue46925.dart b/pkg/front_end/testcases/general/constants/issue46925.dart new file mode 100644 index 00000000000..016df79b7fa --- /dev/null +++ b/pkg/front_end/testcases/general/constants/issue46925.dart @@ -0,0 +1,26 @@ +// 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. + + +class MyClass { + final a; + const MyClass(int i, int j) : a = (i + j); + const MyClass.constr() : a = 0; +} + +test() { + const v1 = MyClass.new; + const v2 = MyClass.constr; + const v3 = MyClass.new; + const v4 = MyClass.constr; + + const c1 = v1(3, 14); + const c2 = v1(3, 14); + const c3 = v2(); + const c4 = v2(); + const c5 = v3(3, 14); + const c6 = v4(); +} + +main() {} \ No newline at end of file diff --git a/pkg/front_end/testcases/general/constants/issue46925.dart.textual_outline.expect b/pkg/front_end/testcases/general/constants/issue46925.dart.textual_outline.expect new file mode 100644 index 00000000000..62af4b808a9 --- /dev/null +++ b/pkg/front_end/testcases/general/constants/issue46925.dart.textual_outline.expect @@ -0,0 +1,8 @@ +class MyClass { + final a; + const MyClass(int i, int j) : a = (i + j); + const MyClass.constr() : a = 0; +} + +test() {} +main() {} diff --git a/pkg/front_end/testcases/general/constants/issue46925.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/constants/issue46925.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..831b45836f1 --- /dev/null +++ b/pkg/front_end/testcases/general/constants/issue46925.dart.textual_outline_modelled.expect @@ -0,0 +1,8 @@ +class MyClass { + const MyClass(int i, int j) : a = (i + j); + const MyClass.constr() : a = 0; + final a; +} + +main() {} +test() {} diff --git a/pkg/front_end/testcases/general/constants/issue46925.dart.weak.expect b/pkg/front_end/testcases/general/constants/issue46925.dart.weak.expect new file mode 100644 index 00000000000..d03ca9a40bf --- /dev/null +++ b/pkg/front_end/testcases/general/constants/issue46925.dart.weak.expect @@ -0,0 +1,95 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/constants/issue46925.dart:13:21: Error: This requires the 'constructor-tearoffs' language feature to be enabled. +// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'. +// const v1 = MyClass.new; +// ^ +// +// pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: This requires the 'constructor-tearoffs' language feature to be enabled. +// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'. +// const v1 = MyClass.new; +// ^^^ +// +// pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: Getter not found: 'new'. +// const v1 = MyClass.new; +// ^^^ +// +// pkg/front_end/testcases/general/constants/issue46925.dart:14:21: Error: This requires the 'constructor-tearoffs' language feature to be enabled. +// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'. +// const v2 = MyClass.constr; +// ^ +// +// pkg/front_end/testcases/general/constants/issue46925.dart:14:27: Error: Getter not found: 'constr'. +// const v2 = MyClass.constr; +// ^^^^^^ +// +// pkg/front_end/testcases/general/constants/issue46925.dart:15:21: Error: This requires the 'constructor-tearoffs' language feature to be enabled. +// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'. +// const v3 = MyClass.new; +// ^ +// +// pkg/front_end/testcases/general/constants/issue46925.dart:15:27: Error: This requires the 'constructor-tearoffs' language feature to be enabled. +// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'. +// const v3 = MyClass.new; +// ^^^ +// +// pkg/front_end/testcases/general/constants/issue46925.dart:15:27: Error: Getter not found: 'new'. +// const v3 = MyClass.new; +// ^^^ +// +// pkg/front_end/testcases/general/constants/issue46925.dart:16:21: Error: This requires the 'constructor-tearoffs' language feature to be enabled. +// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'. +// const v4 = MyClass.constr; +// ^ +// +// pkg/front_end/testcases/general/constants/issue46925.dart:16:30: Error: Getter not found: 'constr'. +// const v4 = MyClass.constr; +// ^^^^^^ +// +import self as self; +import "dart:core" as core; + +class MyClass extends core::Object /*hasConstConstructor*/ { + final field dynamic a; + const constructor •(core::int i, core::int j) → self::MyClass + : self::MyClass::a = i.{core::num::+}(j){(core::num) → core::int}, super core::Object::•() + ; + const constructor constr() → self::MyClass + : self::MyClass::a = 0, super core::Object::•() + ; +} +static method test() → dynamic { + const invalid-type v1 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: Getter not found: 'new'. + const v1 = MyClass.new; + ^^^"; + const invalid-type v2 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:14:27: Error: Getter not found: 'constr'. + const v2 = MyClass.constr; + ^^^^^^"; + const invalid-type v3 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:15:27: Error: Getter not found: 'new'. + const v3 = MyClass.new; + ^^^"; + const invalid-type v4 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:16:30: Error: Getter not found: 'constr'. + const v4 = MyClass.constr; + ^^^^^^"; + const dynamic c1 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: Getter not found: 'new'. + const v1 = MyClass.new; + ^^^"; + const dynamic c2 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: Getter not found: 'new'. + const v1 = MyClass.new; + ^^^"; + const dynamic c3 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:14:27: Error: Getter not found: 'constr'. + const v2 = MyClass.constr; + ^^^^^^"; + const dynamic c4 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:14:27: Error: Getter not found: 'constr'. + const v2 = MyClass.constr; + ^^^^^^"; + const dynamic c5 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:15:27: Error: Getter not found: 'new'. + const v3 = MyClass.new; + ^^^"; + const dynamic c6 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:16:30: Error: Getter not found: 'constr'. + const v4 = MyClass.constr; + ^^^^^^"; +} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/general/constants/issue46925.dart.weak.outline.expect b/pkg/front_end/testcases/general/constants/issue46925.dart.weak.outline.expect new file mode 100644 index 00000000000..e701b2d1912 --- /dev/null +++ b/pkg/front_end/testcases/general/constants/issue46925.dart.weak.outline.expect @@ -0,0 +1,17 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +class MyClass extends core::Object /*hasConstConstructor*/ { + final field dynamic a; + const constructor •(core::int i, core::int j) → self::MyClass + : self::MyClass::a = i.{core::num::+}(j){(core::num) → core::int}, super core::Object::•() + ; + const constructor constr() → self::MyClass + : self::MyClass::a = 0, super core::Object::•() + ; +} +static method test() → dynamic + ; +static method main() → dynamic + ; diff --git a/pkg/front_end/testcases/general/constants/issue46925.dart.weak.transformed.expect b/pkg/front_end/testcases/general/constants/issue46925.dart.weak.transformed.expect new file mode 100644 index 00000000000..d03ca9a40bf --- /dev/null +++ b/pkg/front_end/testcases/general/constants/issue46925.dart.weak.transformed.expect @@ -0,0 +1,95 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/constants/issue46925.dart:13:21: Error: This requires the 'constructor-tearoffs' language feature to be enabled. +// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'. +// const v1 = MyClass.new; +// ^ +// +// pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: This requires the 'constructor-tearoffs' language feature to be enabled. +// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'. +// const v1 = MyClass.new; +// ^^^ +// +// pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: Getter not found: 'new'. +// const v1 = MyClass.new; +// ^^^ +// +// pkg/front_end/testcases/general/constants/issue46925.dart:14:21: Error: This requires the 'constructor-tearoffs' language feature to be enabled. +// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'. +// const v2 = MyClass.constr; +// ^ +// +// pkg/front_end/testcases/general/constants/issue46925.dart:14:27: Error: Getter not found: 'constr'. +// const v2 = MyClass.constr; +// ^^^^^^ +// +// pkg/front_end/testcases/general/constants/issue46925.dart:15:21: Error: This requires the 'constructor-tearoffs' language feature to be enabled. +// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'. +// const v3 = MyClass.new; +// ^ +// +// pkg/front_end/testcases/general/constants/issue46925.dart:15:27: Error: This requires the 'constructor-tearoffs' language feature to be enabled. +// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'. +// const v3 = MyClass.new; +// ^^^ +// +// pkg/front_end/testcases/general/constants/issue46925.dart:15:27: Error: Getter not found: 'new'. +// const v3 = MyClass.new; +// ^^^ +// +// pkg/front_end/testcases/general/constants/issue46925.dart:16:21: Error: This requires the 'constructor-tearoffs' language feature to be enabled. +// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'. +// const v4 = MyClass.constr; +// ^ +// +// pkg/front_end/testcases/general/constants/issue46925.dart:16:30: Error: Getter not found: 'constr'. +// const v4 = MyClass.constr; +// ^^^^^^ +// +import self as self; +import "dart:core" as core; + +class MyClass extends core::Object /*hasConstConstructor*/ { + final field dynamic a; + const constructor •(core::int i, core::int j) → self::MyClass + : self::MyClass::a = i.{core::num::+}(j){(core::num) → core::int}, super core::Object::•() + ; + const constructor constr() → self::MyClass + : self::MyClass::a = 0, super core::Object::•() + ; +} +static method test() → dynamic { + const invalid-type v1 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: Getter not found: 'new'. + const v1 = MyClass.new; + ^^^"; + const invalid-type v2 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:14:27: Error: Getter not found: 'constr'. + const v2 = MyClass.constr; + ^^^^^^"; + const invalid-type v3 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:15:27: Error: Getter not found: 'new'. + const v3 = MyClass.new; + ^^^"; + const invalid-type v4 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:16:30: Error: Getter not found: 'constr'. + const v4 = MyClass.constr; + ^^^^^^"; + const dynamic c1 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: Getter not found: 'new'. + const v1 = MyClass.new; + ^^^"; + const dynamic c2 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:13:30: Error: Getter not found: 'new'. + const v1 = MyClass.new; + ^^^"; + const dynamic c3 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:14:27: Error: Getter not found: 'constr'. + const v2 = MyClass.constr; + ^^^^^^"; + const dynamic c4 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:14:27: Error: Getter not found: 'constr'. + const v2 = MyClass.constr; + ^^^^^^"; + const dynamic c5 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:15:27: Error: Getter not found: 'new'. + const v3 = MyClass.new; + ^^^"; + const dynamic c6 = invalid-expression "pkg/front_end/testcases/general/constants/issue46925.dart:16:30: Error: Getter not found: 'constr'. + const v4 = MyClass.constr; + ^^^^^^"; +} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/general/constants/issue_43431.dart b/pkg/front_end/testcases/general/constants/issue_43431.dart index a0b0bc2ce40..45b056c8323 100644 --- a/pkg/front_end/testcases/general/constants/issue_43431.dart +++ b/pkg/front_end/testcases/general/constants/issue_43431.dart @@ -1,7 +1,9 @@ // Copyright (c) 2020, 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. + // @dart=2.9 + class Foo { const Foo({bool x: true}); const x = Foo(); diff --git a/pkg/front_end/testcases/general/constants/issue_43431.dart.weak.expect b/pkg/front_end/testcases/general/constants/issue_43431.dart.weak.expect index b8bb029e0c7..65e909feb75 100644 --- a/pkg/front_end/testcases/general/constants/issue_43431.dart.weak.expect +++ b/pkg/front_end/testcases/general/constants/issue_43431.dart.weak.expect @@ -2,27 +2,27 @@ library; // // Problems in library: // -// pkg/front_end/testcases/general/constants/issue_43431.dart:7:3: Error: Only static fields can be declared as const. +// pkg/front_end/testcases/general/constants/issue_43431.dart:9:3: Error: Only static fields can be declared as const. // Try using 'final' instead of 'const', or adding the keyword 'static'. // const x = Foo(); // ^^^^^ // -// pkg/front_end/testcases/general/constants/issue_43431.dart:7:13: Error: Constant expression expected. +// pkg/front_end/testcases/general/constants/issue_43431.dart:9:13: Error: Constant expression expected. // Try inserting 'const'. // const x = Foo(); // ^^^ // -// pkg/front_end/testcases/general/constants/issue_43431.dart:6:9: Error: Constructor is marked 'const' so all fields must be final. +// pkg/front_end/testcases/general/constants/issue_43431.dart:8:9: Error: Constructor is marked 'const' so all fields must be final. // const Foo({bool x: true}); // ^ -// pkg/front_end/testcases/general/constants/issue_43431.dart:7:9: Context: Field isn't final, but constructor is 'const'. +// pkg/front_end/testcases/general/constants/issue_43431.dart:9:9: Context: Field isn't final, but constructor is 'const'. // const x = Foo(); // ^ // -// pkg/front_end/testcases/general/constants/issue_43431.dart:7:13: Error: Constant evaluation error: +// pkg/front_end/testcases/general/constants/issue_43431.dart:9:13: Error: Constant evaluation error: // const x = Foo(); // ^ -// pkg/front_end/testcases/general/constants/issue_43431.dart:7:13: Context: Constant expression depends on itself. +// pkg/front_end/testcases/general/constants/issue_43431.dart:9:13: Context: Constant expression depends on itself. // const x = Foo(); // ^ // @@ -54,4 +54,4 @@ constants { Constructor coverage from constants: org-dartlang-testcase:///issue_43431.dart: -- Foo. (from org-dartlang-testcase:///issue_43431.dart:6:9) +- Foo. (from org-dartlang-testcase:///issue_43431.dart:8:9) diff --git a/pkg/front_end/testcases/general/constants/issue_43431.dart.weak.outline.expect b/pkg/front_end/testcases/general/constants/issue_43431.dart.weak.outline.expect index 1854d2a4c05..c1256e58009 100644 --- a/pkg/front_end/testcases/general/constants/issue_43431.dart.weak.outline.expect +++ b/pkg/front_end/testcases/general/constants/issue_43431.dart.weak.outline.expect @@ -2,7 +2,7 @@ library; // // Problems in library: // -// pkg/front_end/testcases/general/constants/issue_43431.dart:7:3: Error: Only static fields can be declared as const. +// pkg/front_end/testcases/general/constants/issue_43431.dart:9:3: Error: Only static fields can be declared as const. // Try using 'final' instead of 'const', or adding the keyword 'static'. // const x = Foo(); // ^^^^^ diff --git a/pkg/front_end/testcases/general/constants/issue_43431.dart.weak.transformed.expect b/pkg/front_end/testcases/general/constants/issue_43431.dart.weak.transformed.expect index b8bb029e0c7..65e909feb75 100644 --- a/pkg/front_end/testcases/general/constants/issue_43431.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/general/constants/issue_43431.dart.weak.transformed.expect @@ -2,27 +2,27 @@ library; // // Problems in library: // -// pkg/front_end/testcases/general/constants/issue_43431.dart:7:3: Error: Only static fields can be declared as const. +// pkg/front_end/testcases/general/constants/issue_43431.dart:9:3: Error: Only static fields can be declared as const. // Try using 'final' instead of 'const', or adding the keyword 'static'. // const x = Foo(); // ^^^^^ // -// pkg/front_end/testcases/general/constants/issue_43431.dart:7:13: Error: Constant expression expected. +// pkg/front_end/testcases/general/constants/issue_43431.dart:9:13: Error: Constant expression expected. // Try inserting 'const'. // const x = Foo(); // ^^^ // -// pkg/front_end/testcases/general/constants/issue_43431.dart:6:9: Error: Constructor is marked 'const' so all fields must be final. +// pkg/front_end/testcases/general/constants/issue_43431.dart:8:9: Error: Constructor is marked 'const' so all fields must be final. // const Foo({bool x: true}); // ^ -// pkg/front_end/testcases/general/constants/issue_43431.dart:7:9: Context: Field isn't final, but constructor is 'const'. +// pkg/front_end/testcases/general/constants/issue_43431.dart:9:9: Context: Field isn't final, but constructor is 'const'. // const x = Foo(); // ^ // -// pkg/front_end/testcases/general/constants/issue_43431.dart:7:13: Error: Constant evaluation error: +// pkg/front_end/testcases/general/constants/issue_43431.dart:9:13: Error: Constant evaluation error: // const x = Foo(); // ^ -// pkg/front_end/testcases/general/constants/issue_43431.dart:7:13: Context: Constant expression depends on itself. +// pkg/front_end/testcases/general/constants/issue_43431.dart:9:13: Context: Constant expression depends on itself. // const x = Foo(); // ^ // @@ -54,4 +54,4 @@ constants { Constructor coverage from constants: org-dartlang-testcase:///issue_43431.dart: -- Foo. (from org-dartlang-testcase:///issue_43431.dart:6:9) +- Foo. (from org-dartlang-testcase:///issue_43431.dart:8:9) diff --git a/pkg/front_end/testcases/general/constants/non_const_constructor.dart b/pkg/front_end/testcases/general/constants/non_const_constructor.dart new file mode 100644 index 00000000000..60819d1cb0b --- /dev/null +++ b/pkg/front_end/testcases/general/constants/non_const_constructor.dart @@ -0,0 +1,16 @@ +// 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. + +class Class { + Class(); + + const Class.named() { + 1; + } +} + +const a = const Class(); +const b = const Class.named(); + +main() {} \ No newline at end of file diff --git a/pkg/front_end/testcases/general/constants/non_const_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/general/constants/non_const_constructor.dart.textual_outline.expect new file mode 100644 index 00000000000..69dda5b1eae --- /dev/null +++ b/pkg/front_end/testcases/general/constants/non_const_constructor.dart.textual_outline.expect @@ -0,0 +1,7 @@ +class Class { + Class(); + const Class.named() {} +} +const a = const Class(); +const b = const Class.named(); +main() {} diff --git a/pkg/front_end/testcases/general/constants/non_const_constructor.dart.weak.expect b/pkg/front_end/testcases/general/constants/non_const_constructor.dart.weak.expect new file mode 100644 index 00000000000..378710d4624 --- /dev/null +++ b/pkg/front_end/testcases/general/constants/non_const_constructor.dart.weak.expect @@ -0,0 +1,40 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/constants/non_const_constructor.dart:8:3: Error: A const constructor can't have a body. +// Try removing either the 'const' keyword or the body. +// const Class.named() { +// ^^^^^ +// +// pkg/front_end/testcases/general/constants/non_const_constructor.dart:13:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected. +// Try using a constructor or factory that is 'const'. +// const a = const Class(); +// ^^^^^ +// +// pkg/front_end/testcases/general/constants/non_const_constructor.dart:14:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected. +// Try using a constructor or factory that is 'const'. +// const b = const Class.named(); +// ^^^^^ +// +import self as self; +import "dart:core" as core; + +class Class extends core::Object { + constructor •() → self::Class + : super core::Object::•() + ; + constructor named() → self::Class + : super core::Object::•() { + 1; + } +} +static const field invalid-type a = invalid-expression "pkg/front_end/testcases/general/constants/non_const_constructor.dart:13:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected. +Try using a constructor or factory that is 'const'. +const a = const Class(); + ^^^^^"; +static const field invalid-type b = invalid-expression "pkg/front_end/testcases/general/constants/non_const_constructor.dart:14:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected. +Try using a constructor or factory that is 'const'. +const b = const Class.named(); + ^^^^^"; +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/general/constants/non_const_constructor.dart.weak.outline.expect b/pkg/front_end/testcases/general/constants/non_const_constructor.dart.weak.outline.expect new file mode 100644 index 00000000000..8d7f5daedcc --- /dev/null +++ b/pkg/front_end/testcases/general/constants/non_const_constructor.dart.weak.outline.expect @@ -0,0 +1,38 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/constants/non_const_constructor.dart:8:3: Error: A const constructor can't have a body. +// Try removing either the 'const' keyword or the body. +// const Class.named() { +// ^^^^^ +// +// pkg/front_end/testcases/general/constants/non_const_constructor.dart:13:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected. +// Try using a constructor or factory that is 'const'. +// const a = const Class(); +// ^^^^^ +// +// pkg/front_end/testcases/general/constants/non_const_constructor.dart:14:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected. +// Try using a constructor or factory that is 'const'. +// const b = const Class.named(); +// ^^^^^ +// +import self as self; +import "dart:core" as core; + +class Class extends core::Object { + constructor •() → self::Class + ; + constructor named() → self::Class + ; +} +static const field invalid-type a = invalid-expression "pkg/front_end/testcases/general/constants/non_const_constructor.dart:13:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected. +Try using a constructor or factory that is 'const'. +const a = const Class(); + ^^^^^"; +static const field invalid-type b = invalid-expression "pkg/front_end/testcases/general/constants/non_const_constructor.dart:14:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected. +Try using a constructor or factory that is 'const'. +const b = const Class.named(); + ^^^^^"; +static method main() → dynamic + ; diff --git a/pkg/front_end/testcases/general/constants/non_const_constructor.dart.weak.transformed.expect b/pkg/front_end/testcases/general/constants/non_const_constructor.dart.weak.transformed.expect new file mode 100644 index 00000000000..378710d4624 --- /dev/null +++ b/pkg/front_end/testcases/general/constants/non_const_constructor.dart.weak.transformed.expect @@ -0,0 +1,40 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/constants/non_const_constructor.dart:8:3: Error: A const constructor can't have a body. +// Try removing either the 'const' keyword or the body. +// const Class.named() { +// ^^^^^ +// +// pkg/front_end/testcases/general/constants/non_const_constructor.dart:13:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected. +// Try using a constructor or factory that is 'const'. +// const a = const Class(); +// ^^^^^ +// +// pkg/front_end/testcases/general/constants/non_const_constructor.dart:14:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected. +// Try using a constructor or factory that is 'const'. +// const b = const Class.named(); +// ^^^^^ +// +import self as self; +import "dart:core" as core; + +class Class extends core::Object { + constructor •() → self::Class + : super core::Object::•() + ; + constructor named() → self::Class + : super core::Object::•() { + 1; + } +} +static const field invalid-type a = invalid-expression "pkg/front_end/testcases/general/constants/non_const_constructor.dart:13:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected. +Try using a constructor or factory that is 'const'. +const a = const Class(); + ^^^^^"; +static const field invalid-type b = invalid-expression "pkg/front_end/testcases/general/constants/non_const_constructor.dart:14:17: Error: Cannot invoke a non-'const' constructor where a const expression is expected. +Try using a constructor or factory that is 'const'. +const b = const Class.named(); + ^^^^^"; +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/general/constants/non_const_variable.dart b/pkg/front_end/testcases/general/constants/non_const_variable.dart new file mode 100644 index 00000000000..3f932dcc39b --- /dev/null +++ b/pkg/front_end/testcases/general/constants/non_const_variable.dart @@ -0,0 +1,10 @@ +// 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. + +method() { + var a = 0; + const b = a; +} + +main() {} diff --git a/pkg/front_end/testcases/general/constants/non_const_variable.dart.textual_outline.expect b/pkg/front_end/testcases/general/constants/non_const_variable.dart.textual_outline.expect new file mode 100644 index 00000000000..b169126c12c --- /dev/null +++ b/pkg/front_end/testcases/general/constants/non_const_variable.dart.textual_outline.expect @@ -0,0 +1,2 @@ +method() {} +main() {} diff --git a/pkg/front_end/testcases/general/constants/non_const_variable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/constants/non_const_variable.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..49b9b34c912 --- /dev/null +++ b/pkg/front_end/testcases/general/constants/non_const_variable.dart.textual_outline_modelled.expect @@ -0,0 +1,2 @@ +main() {} +method() {} diff --git a/pkg/front_end/testcases/general/constants/non_const_variable.dart.weak.expect b/pkg/front_end/testcases/general/constants/non_const_variable.dart.weak.expect new file mode 100644 index 00000000000..a60069436c4 --- /dev/null +++ b/pkg/front_end/testcases/general/constants/non_const_variable.dart.weak.expect @@ -0,0 +1,18 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/constants/non_const_variable.dart:7:13: Error: Not a constant expression. +// const b = a; +// ^ +// +import self as self; +import "dart:core" as core; + +static method method() → dynamic { + core::int a = 0; + const invalid-type b = invalid-expression "pkg/front_end/testcases/general/constants/non_const_variable.dart:7:13: Error: Not a constant expression. + const b = a; + ^"; +} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/general/constants/non_const_variable.dart.weak.outline.expect b/pkg/front_end/testcases/general/constants/non_const_variable.dart.weak.outline.expect new file mode 100644 index 00000000000..6519787c348 --- /dev/null +++ b/pkg/front_end/testcases/general/constants/non_const_variable.dart.weak.outline.expect @@ -0,0 +1,7 @@ +library /*isNonNullableByDefault*/; +import self as self; + +static method method() → dynamic + ; +static method main() → dynamic + ; diff --git a/pkg/front_end/testcases/general/constants/non_const_variable.dart.weak.transformed.expect b/pkg/front_end/testcases/general/constants/non_const_variable.dart.weak.transformed.expect new file mode 100644 index 00000000000..a60069436c4 --- /dev/null +++ b/pkg/front_end/testcases/general/constants/non_const_variable.dart.weak.transformed.expect @@ -0,0 +1,18 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/constants/non_const_variable.dart:7:13: Error: Not a constant expression. +// const b = a; +// ^ +// +import self as self; +import "dart:core" as core; + +static method method() → dynamic { + core::int a = 0; + const invalid-type b = invalid-expression "pkg/front_end/testcases/general/constants/non_const_variable.dart:7:13: Error: Not a constant expression. + const b = a; + ^"; +} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/general/constants/various.dart.weak.expect b/pkg/front_end/testcases/general/constants/various.dart.weak.expect index 37e01f5f88c..62853b92bd3 100644 --- a/pkg/front_end/testcases/general/constants/various.dart.weak.expect +++ b/pkg/front_end/testcases/general/constants/various.dart.weak.expect @@ -100,6 +100,14 @@ library; // class ExtendsFoo1 extends Foo { // ^ // +// pkg/front_end/testcases/general/constants/various.dart:99:4: Error: Not a constant expression. +// @AbstractClass() +// ^ +// +// pkg/front_end/testcases/general/constants/various.dart:102:4: Error: Not a constant expression. +// @AbstractClassWithConstructor() +// ^ +// // pkg/front_end/testcases/general/constants/various.dart:10:34: Error: Constant evaluation error: // const bool notBarFromEnvOrNull = !barFromEnvOrNull; // ^ @@ -341,9 +349,9 @@ abstract class AbstractClassWithConstructor extends core::Object /*hasConstConst abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType } class NotAbstractClass extends core::Object { - @invalid-expression "Constant evaluation has no support for Throw!" + @invalid-expression "Not a constant expression." field core::Object* foo = null; - @invalid-expression "Constant evaluation has no support for Throw!" + @invalid-expression "Not a constant expression." field core::Object* bar = null; synthetic constructor •() → self::NotAbstractClass* : super core::Object::•() @@ -518,8 +526,8 @@ static const field dynamic binaryOnStringWithStringOK = #C11; static const field dynamic binaryOnStringWithInt = invalid-expression "Binary operator '+' on '\"hello\"' requires operand of type 'String', but was of type 'int'."; static const field dynamic binaryOnStringWithStringBad = invalid-expression "The method '-' can't be invoked on '\"hello\"' in a constant expression."; static field core::int* x = 1; -static const field core::int* x1 = invalid-expression "Constant evaluation has no support for StaticSet!"; -static const field core::int* x2 = invalid-expression "Constant evaluation has no support for StaticSet!"; +static const field core::int* x1 = invalid-expression "Not a constant expression."; +static const field core::int* x2 = invalid-expression "Not a constant expression."; static const field core::int* x3 = invalid-expression "The invocation of 'x' is not allowed in a constant expression."; static const field core::int* x4 = invalid-expression "The invocation of 'x' is not allowed in a constant expression."; static const field core::int* y = #C12; diff --git a/pkg/front_end/testcases/general/constants/various.dart.weak.transformed.expect b/pkg/front_end/testcases/general/constants/various.dart.weak.transformed.expect index 72184978d17..9d9530c2a18 100644 --- a/pkg/front_end/testcases/general/constants/various.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/general/constants/various.dart.weak.transformed.expect @@ -100,6 +100,14 @@ library; // class ExtendsFoo1 extends Foo { // ^ // +// pkg/front_end/testcases/general/constants/various.dart:99:4: Error: Not a constant expression. +// @AbstractClass() +// ^ +// +// pkg/front_end/testcases/general/constants/various.dart:102:4: Error: Not a constant expression. +// @AbstractClassWithConstructor() +// ^ +// // pkg/front_end/testcases/general/constants/various.dart:10:34: Error: Constant evaluation error: // const bool notBarFromEnvOrNull = !barFromEnvOrNull; // ^ @@ -341,9 +349,9 @@ abstract class AbstractClassWithConstructor extends core::Object /*hasConstConst abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType } class NotAbstractClass extends core::Object { - @invalid-expression "Constant evaluation has no support for Throw!" + @invalid-expression "Not a constant expression." field core::Object* foo = null; - @invalid-expression "Constant evaluation has no support for Throw!" + @invalid-expression "Not a constant expression." field core::Object* bar = null; synthetic constructor •() → self::NotAbstractClass* : super core::Object::•() @@ -518,8 +526,8 @@ static const field dynamic binaryOnStringWithStringOK = #C11; static const field dynamic binaryOnStringWithInt = invalid-expression "Binary operator '+' on '\"hello\"' requires operand of type 'String', but was of type 'int'."; static const field dynamic binaryOnStringWithStringBad = invalid-expression "The method '-' can't be invoked on '\"hello\"' in a constant expression."; static field core::int* x = 1; -static const field core::int* x1 = invalid-expression "Constant evaluation has no support for StaticSet!"; -static const field core::int* x2 = invalid-expression "Constant evaluation has no support for StaticSet!"; +static const field core::int* x1 = invalid-expression "Not a constant expression."; +static const field core::int* x2 = invalid-expression "Not a constant expression."; static const field core::int* x3 = invalid-expression "The invocation of 'x' is not allowed in a constant expression."; static const field core::int* x4 = invalid-expression "The invocation of 'x' is not allowed in a constant expression."; static const field core::int* y = #C12; diff --git a/pkg/front_end/testcases/general/magic_const.dart.weak.expect b/pkg/front_end/testcases/general/magic_const.dart.weak.expect index 191ed7b3f9c..60dcd8bce5e 100644 --- a/pkg/front_end/testcases/general/magic_const.dart.weak.expect +++ b/pkg/front_end/testcases/general/magic_const.dart.weak.expect @@ -22,6 +22,10 @@ library; // const NotConstant(); // ^^^^^^^^^^^ // +// pkg/front_end/testcases/general/magic_const.dart:15:39: Error: Non-constant list literal is not a constant expression. +// foo({a: Constant(), b: Constant(), c: []}) {} +// ^ +// import self as self; import "dart:core" as core; @@ -55,7 +59,7 @@ class NotConstant extends core::Object { abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType } -static method foo({dynamic a = #C1, dynamic b = #C1, dynamic c = invalid-expression "Non-constant list literal"}) → dynamic {} +static method foo({dynamic a = #C1, dynamic b = #C1, dynamic c = invalid-expression "Non-constant list literal is not a constant expression."}) → dynamic {} static method test() → dynamic { invalid-expression "pkg/front_end/testcases/general/magic_const.dart:18:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected. Try using a constructor or factory that is 'const'. diff --git a/pkg/front_end/testcases/general/magic_const.dart.weak.transformed.expect b/pkg/front_end/testcases/general/magic_const.dart.weak.transformed.expect index 7e7a8a42444..3755189b461 100644 --- a/pkg/front_end/testcases/general/magic_const.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/general/magic_const.dart.weak.transformed.expect @@ -22,6 +22,10 @@ library; // const NotConstant(); // ^^^^^^^^^^^ // +// pkg/front_end/testcases/general/magic_const.dart:15:39: Error: Non-constant list literal is not a constant expression. +// foo({a: Constant(), b: Constant(), c: []}) {} +// ^ +// import self as self; import "dart:core" as core; @@ -55,7 +59,7 @@ class NotConstant extends core::Object { abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType } -static method foo({dynamic a = #C1, dynamic b = #C1, dynamic c = invalid-expression "Non-constant list literal"}) → dynamic {} +static method foo({dynamic a = #C1, dynamic b = #C1, dynamic c = invalid-expression "Non-constant list literal is not a constant expression."}) → dynamic {} static method test() → dynamic { invalid-expression "pkg/front_end/testcases/general/magic_const.dart:18:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected. Try using a constructor or factory that is 'const'. diff --git a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.weak.expect b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.weak.expect index 998971198e8..900813e2931 100644 --- a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.weak.expect +++ b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.weak.expect @@ -16,6 +16,10 @@ library; // main(arguments = [x]) { // ^ // +// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:18: Error: Non-constant list literal is not a constant expression. +// main(arguments = [x]) { +// ^ +// import self as self; -static method main(dynamic arguments = invalid-expression "Non-constant list literal") → dynamic {} +static method main(dynamic arguments = invalid-expression "Non-constant list literal is not a constant expression.") → dynamic {} diff --git a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.weak.transformed.expect index 998971198e8..900813e2931 100644 --- a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.weak.transformed.expect @@ -16,6 +16,10 @@ library; // main(arguments = [x]) { // ^ // +// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:18: Error: Non-constant list literal is not a constant expression. +// main(arguments = [x]) { +// ^ +// import self as self; -static method main(dynamic arguments = invalid-expression "Non-constant list literal") → dynamic {} +static method main(dynamic arguments = invalid-expression "Non-constant list literal is not a constant expression.") → dynamic {} diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status index 27225628f3b..e2c84736321 100644 --- a/pkg/front_end/testcases/textual_outline.status +++ b/pkg/front_end/testcases/textual_outline.status @@ -41,6 +41,7 @@ general/bug31124: FormatterCrash general/clone_function_type: FormatterCrash general/constants/js_semantics/number_folds: FormatterCrash general/constants/js_semantics/number_folds_opt_out: FormatterCrash +general/constants/non_const_constructor: FormatterCrash general/constants/number_folds: FormatterCrash general/constants/number_folds_opt_out: FormatterCrash general/constants/various: FormatterCrash diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart index a7364338613..b2c5e0e5728 100644 --- a/pkg/kernel/lib/ast.dart +++ b/pkg/kernel/lib/ast.dart @@ -3251,7 +3251,7 @@ class AssertInitializer extends Initializer { @override void toTextInternal(AstPrinter printer) { - // TODO(johnniwinther): Implement this. + statement.toTextInternal(printer); } } diff --git a/tests/language/const/const_locals_constant_locals_test.dart b/tests/language/const/const_locals_constant_locals_test.dart index 472687b8202..95a47bbcf50 100644 --- a/tests/language/const/const_locals_constant_locals_test.dart +++ b/tests/language/const/const_locals_constant_locals_test.dart @@ -16,13 +16,11 @@ void main() { // ^^^^^ // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE // [cfe] Constant evaluation error: - // ^ // [cfe] Not a constant expression. const c4 = finalField; // ^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE // [cfe] Constant evaluation error: - // ^ // [cfe] Not a constant expression. const c5 = constField; const c6 = method(); @@ -33,6 +31,8 @@ void main() { // ^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE // [cfe] New expression is not a constant expression. + // ^ + // [cfe] New expression is not a constant expression. const c8 = const Class(); } diff --git a/tests/language/const/constructor_syntax_test.dart b/tests/language/const/constructor_syntax_test.dart index ea34671f13b..898aa6ca060 100644 --- a/tests/language/const/constructor_syntax_test.dart +++ b/tests/language/const/constructor_syntax_test.dart @@ -51,8 +51,8 @@ class C3 { // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION // ^ // [cfe] 'field' is a final instance variable that was initialized at the declaration. - // ^ // [cfe] Cannot invoke a non-'const' constructor where a const expression is expected. + // [cfe] Not a constant expression. // ^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.INVALID_CONSTANT // [cfe] New expression is not a constant expression. diff --git a/tests/language/const/factory_with_body_test.dart b/tests/language/const/factory_with_body_test.dart index a9577bb8907..e5402711e1d 100644 --- a/tests/language/const/factory_with_body_test.dart +++ b/tests/language/const/factory_with_body_test.dart @@ -15,4 +15,6 @@ class ConstFactoryWithBody { main() { const ConstFactoryWithBody.one(); + // ^ + // [cfe] Non-redirecting const factory invocation is not a constant expression. } diff --git a/tests/language/const/optional_args_test.dart b/tests/language/const/optional_args_test.dart index 3d7c7791c67..443c6db4a3d 100644 --- a/tests/language/const/optional_args_test.dart +++ b/tests/language/const/optional_args_test.dart @@ -14,6 +14,7 @@ invalid( // ^^ // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_DEFAULT_VALUE // [cfe] Constant expression expected. +// [cfe] Non-constant map literal is not a constant expression. main() { invalid(); diff --git a/tests/language/const/syntax_test.dart b/tests/language/const/syntax_test.dart index cf1ce3ac232..41f2818eb43 100644 --- a/tests/language/const/syntax_test.dart +++ b/tests/language/const/syntax_test.dart @@ -45,6 +45,8 @@ main() { // ^^^^^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE // [cfe] New expression is not a constant expression. + // ^ + // [cfe] New expression is not a constant expression. var f4 = B4; var f5 = B5; @@ -60,7 +62,6 @@ const int F3; // ^^ // [analyzer] COMPILE_TIME_ERROR.CONST_NOT_INITIALIZED // [cfe] Field 'F3' should be initialized because its type 'int' doesn't allow null. -// ^ // [cfe] The const variable 'F3' must be initialized. // ^ // [cfe] The value 'null' can't be assigned to a variable of type 'int' because 'int' is not nullable. @@ -83,10 +84,14 @@ const P2 = new Point(0, 0); // ^^^^^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE // [cfe] New expression is not a constant expression. +// ^ +// [cfe] New expression is not a constant expression. const P3 = new Point(0, 0) + 1; // ^^^^^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE // [cfe] New expression is not a constant expression. +// ^ +// [cfe] New expression is not a constant expression. // Check that we cannot have cyclic references in compile time // expressions. @@ -115,8 +120,8 @@ class C1 { // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION // ^ // [cfe] 'x' is a final instance variable that was initialized at the declaration. - // ^ // [cfe] Cannot invoke a non-'const' constructor where a const expression is expected. + // [cfe] Not a constant expression. ; final x = null; } @@ -138,4 +143,6 @@ const B4 = identical(1, new Point(1, 2)); // ^^^^^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE // [cfe] New expression is not a constant expression. +// ^ +// [cfe] New expression is not a constant expression. const B5 = identical(1, const Point(1, 2)); diff --git a/tests/language/const_functions/const_functions_const_factory_disabled_test.dart b/tests/language/const_functions/const_functions_const_factory_disabled_test.dart index e6bf9c6a965..0215a1d3905 100644 --- a/tests/language/const_functions/const_functions_const_factory_disabled_test.dart +++ b/tests/language/const_functions/const_functions_const_factory_disabled_test.dart @@ -7,6 +7,8 @@ import "package:expect/expect.dart"; const printConst = MessageType.parse("print"); +// ^ +// [cfe] Non-redirecting const factory invocation is not a constant expression. class MessageType { static const print = MessageType._('print'); diff --git a/tests/language_2/const/const_locals_constant_locals_test.dart b/tests/language_2/const/const_locals_constant_locals_test.dart index 2d272164f06..4ce5265d38a 100644 --- a/tests/language_2/const/const_locals_constant_locals_test.dart +++ b/tests/language_2/const/const_locals_constant_locals_test.dart @@ -18,13 +18,11 @@ void main() { // ^^^^^ // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE // [cfe] Constant evaluation error: - // ^ // [cfe] Not a constant expression. const c4 = finalField; // ^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE // [cfe] Constant evaluation error: - // ^ // [cfe] Not a constant expression. const c5 = constField; const c6 = method(); @@ -35,6 +33,8 @@ void main() { // ^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE // [cfe] New expression is not a constant expression. + // ^ + // [cfe] New expression is not a constant expression. const c8 = const Class(); } diff --git a/tests/language_2/const/constructor_syntax_test.dart b/tests/language_2/const/constructor_syntax_test.dart index e29bf6c0168..585c36ef5df 100644 --- a/tests/language_2/const/constructor_syntax_test.dart +++ b/tests/language_2/const/constructor_syntax_test.dart @@ -53,8 +53,8 @@ class C3 { // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION // ^ // [cfe] 'field' is a final instance variable that was initialized at the declaration. - // ^ // [cfe] Cannot invoke a non-'const' constructor where a const expression is expected. + // [cfe] Not a constant expression. // ^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.INVALID_CONSTANT // [cfe] New expression is not a constant expression. diff --git a/tests/language_2/const/factory_with_body_test.dart b/tests/language_2/const/factory_with_body_test.dart index 46d08fb4444..7dd5a120465 100644 --- a/tests/language_2/const/factory_with_body_test.dart +++ b/tests/language_2/const/factory_with_body_test.dart @@ -15,4 +15,6 @@ class ConstFactoryWithBody { main() { const ConstFactoryWithBody.one(); + // ^ + // [cfe] Non-redirecting const factory invocation is not a constant expression. } diff --git a/tests/language_2/const/optional_args_test.dart b/tests/language_2/const/optional_args_test.dart index 5d752e0e647..b16ce2f7569 100644 --- a/tests/language_2/const/optional_args_test.dart +++ b/tests/language_2/const/optional_args_test.dart @@ -16,6 +16,7 @@ invalid( // ^^ // [analyzer] COMPILE_TIME_ERROR.NON_CONSTANT_DEFAULT_VALUE // [cfe] Constant expression expected. +// [cfe] Non-constant map literal is not a constant expression. main() { invalid(); diff --git a/tests/language_2/const/syntax_test.dart b/tests/language_2/const/syntax_test.dart index 364a421b6ec..a42bd6b5869 100644 --- a/tests/language_2/const/syntax_test.dart +++ b/tests/language_2/const/syntax_test.dart @@ -47,6 +47,8 @@ main() { // ^^^^^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE // [cfe] New expression is not a constant expression. + // ^ + // [cfe] New expression is not a constant expression. var f4 = B4; var f5 = B5; @@ -81,10 +83,14 @@ const P2 = new Point(0, 0); // ^^^^^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE // [cfe] New expression is not a constant expression. +// ^ +// [cfe] New expression is not a constant expression. const P3 = new Point(0, 0) + 1; // ^^^^^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE // [cfe] New expression is not a constant expression. +// ^ +// [cfe] New expression is not a constant expression. // Check that we cannot have cyclic references in compile time // expressions. @@ -113,8 +119,8 @@ class C1 { // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION // ^ // [cfe] 'x' is a final instance variable that was initialized at the declaration. - // ^ // [cfe] Cannot invoke a non-'const' constructor where a const expression is expected. + // [cfe] Not a constant expression. ; final x = null; } @@ -136,4 +142,6 @@ const B4 = identical(1, new Point(1, 2)); // ^^^^^^^^^^^^^^^ // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE // [cfe] New expression is not a constant expression. +// ^ +// [cfe] New expression is not a constant expression. const B5 = identical(1, const Point(1, 2));