Error message for circular constant expressions
Handles the situations described in #34204 and #34189 when front-end
constant folding is enabled.
Change-Id: I64fd8449ac1661f6fe67411113c6f99d8009547c
Reviewed-on: https://dart-review.googlesource.com/c/90007
Reviewed-by: Kevin Millikin <kmillikin@google.com>
Commit-Queue: Aske Simon Christensen <askesc@google.com>
diff --git a/pkg/front_end/lib/src/api_unstable/vm.dart b/pkg/front_end/lib/src/api_unstable/vm.dart
index e9c843d..8ca86a7 100644
--- a/pkg/front_end/lib/src/api_unstable/vm.dart
+++ b/pkg/front_end/lib/src/api_unstable/vm.dart
@@ -34,6 +34,7 @@
show
LocatedMessage,
Message,
+ messageConstEvalCircularity,
messageConstEvalContext,
messageConstEvalFailedAssertion,
noLength,
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index 3c87fc7..43f48ce 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -974,6 +974,15 @@
r"""Constant constructor can't call non-constant super constructors.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeConstEvalCircularity = messageConstEvalCircularity;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageConstEvalCircularity = const MessageCode(
+ "ConstEvalCircularity",
+ analyzerCodes: <String>["RECURSIVE_COMPILE_TIME_CONSTANT"],
+ message: r"""Constant expression depends on itself.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeConstEvalContext = messageConstEvalContext;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
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 0d0fc88..7927a7d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart
@@ -30,6 +30,7 @@
show
Message,
noLength,
+ messageConstEvalCircularity,
messageConstEvalFailedAssertion,
templateConstEvalDeferredLibrary,
templateConstEvalDuplicateKey,
@@ -176,6 +177,11 @@
return addProblem(
node, templateConstEvalDeferredLibrary.withArguments(importName));
}
+
+ @override
+ String circularity(List<TreeNode> context, TreeNode node) {
+ return addProblem(node, messageConstEvalCircularity);
+ }
}
class KernelConstantsBackend extends ConstantsBackend {
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 20e3338..445d797 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -56,6 +56,7 @@
ConstConstructorNonFinalField/example: Fail
ConstConstructorRedirectionToNonConst/analyzerCode: Fail # The analyzer doesn't report this error.
ConstConstructorWithNonConstSuper/example: Fail
+ConstEvalCircularity/example: Fail
ConstEvalContext/analyzerCode: Fail # This is just used for displaying the context.
ConstEvalContext/example: Fail # This is just used for displaying the context.
ConstEvalDeferredLibrary/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 50c5be3..7b717b1 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -146,6 +146,10 @@
ConstEvalFreeTypeParameter:
template: "The type '#type' is not a constant because it depends on a type parameter, only instantiated types are allowed."
+ConstEvalCircularity:
+ template: "Constant expression depends on itself."
+ analyzerCode: RECURSIVE_COMPILE_TIME_CONSTANT
+
NotConstantExpression:
template: "#string is not a constant expression."
analyzerCode: NOT_CONSTANT_EXPRESSION
diff --git a/pkg/kernel/lib/transformations/constants.dart b/pkg/kernel/lib/transformations/constants.dart
index a76259f..4661791 100644
--- a/pkg/kernel/lib/transformations/constants.dart
+++ b/pkg/kernel/lib/transformations/constants.dart
@@ -415,7 +415,9 @@
// environment.
if (nodeCache.containsKey(node)) {
final Constant constant = nodeCache[node];
- if (constant == null) throw new _AbortCurrentEvaluation('circularity');
+ if (constant == null)
+ throw new _AbortCurrentEvaluation(
+ errorReporter.circularity(contextChain, node));
return constant;
}
@@ -1514,6 +1516,7 @@
List<TreeNode> context, TreeNode node, String variableName);
String deferredLibrary(
List<TreeNode> context, TreeNode node, String importName);
+ String circularity(List<TreeNode> context, TreeNode node);
}
class SimpleErrorReporter extends ErrorReporter {
@@ -1657,6 +1660,11 @@
'expression',
node);
}
+
+ @override
+ String circularity(List<TreeNode> context, TreeNode node) {
+ return report(context, 'Constant expression depends on itself.', node);
+ }
}
class IsInstantiatedVisitor extends DartTypeVisitor<bool> {
diff --git a/pkg/vm/lib/constants_error_reporter.dart b/pkg/vm/lib/constants_error_reporter.dart
index 0842add..d2fdc95 100644
--- a/pkg/vm/lib/constants_error_reporter.dart
+++ b/pkg/vm/lib/constants_error_reporter.dart
@@ -140,6 +140,12 @@
return reportIt(context, message, node);
}
+ @override
+ String circularity(List<TreeNode> context, TreeNode node) {
+ final message = codes.messageConstEvalCircularity;
+ return reportIt(context, message, node);
+ }
+
String reportIt(
List<TreeNode> context, codes.Message message, TreeNode node) {
final Uri uri = getFileUri(node);