Report errors for using control-flow and spread features in a const context
CFE detects the const context while parsing, so we can report the error message
early on before we do any transformations.
Change-Id: Ib1cadb28366eb6a9a18612206aa155b04a4a5b32
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99540
Commit-Queue: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
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 01e5f4b..668da04 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -639,6 +639,30 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(Token token)>
+ templateCantUseControlFlowOrSpreadAsConstant =
+ const Template<Message Function(Token token)>(
+ messageTemplate:
+ r"""'#lexeme' is not supported in constant expressions.""",
+ withArguments: _withArgumentsCantUseControlFlowOrSpreadAsConstant);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(Token token)>
+ codeCantUseControlFlowOrSpreadAsConstant =
+ const Code<Message Function(Token token)>(
+ "CantUseControlFlowOrSpreadAsConstant",
+ templateCantUseControlFlowOrSpreadAsConstant,
+ analyzerCodes: <String>["NOT_CONSTANT_EXPRESSION"]);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsCantUseControlFlowOrSpreadAsConstant(Token token) {
+ String lexeme = token.lexeme;
+ return new Message(codeCantUseControlFlowOrSpreadAsConstant,
+ message: """'${lexeme}' is not supported in constant expressions.""",
+ arguments: {'token': token});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(
Token
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 e360c2e..0430c9d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -2316,6 +2316,18 @@
push(invalidCollectionElement);
return;
}
+
+ if (constantContext != ConstantContext.none &&
+ !library.loader.target.enableConstantUpdate2018) {
+ handleRecoverableError(
+ fasta.templateCantUseControlFlowOrSpreadAsConstant
+ .withArguments(forToken),
+ forToken,
+ forToken);
+ push(invalidCollectionElement);
+ return;
+ }
+
transformCollections = true;
List<VariableDeclaration> variables =
buildVariableDeclarations(variableOrExpression);
@@ -3718,6 +3730,18 @@
push(invalidCollectionElement);
return;
}
+
+ if (constantContext != ConstantContext.none &&
+ !library.loader.target.enableConstantUpdate2018) {
+ handleRecoverableError(
+ fasta.templateCantUseControlFlowOrSpreadAsConstant
+ .withArguments(ifToken),
+ ifToken,
+ ifToken);
+ push(invalidCollectionElement);
+ return;
+ }
+
transformCollections = true;
if (entry is MapEntry) {
push(forest.ifMapEntry(toValue(condition), entry, null, ifToken));
@@ -3744,6 +3768,18 @@
push(invalidCollectionElement);
return;
}
+
+ if (constantContext != ConstantContext.none &&
+ !library.loader.target.enableConstantUpdate2018) {
+ handleRecoverableError(
+ fasta.templateCantUseControlFlowOrSpreadAsConstant
+ .withArguments(ifToken),
+ ifToken,
+ ifToken);
+ push(invalidCollectionElement);
+ return;
+ }
+
transformCollections = true;
if (thenEntry is MapEntry) {
if (elseEntry is MapEntry) {
@@ -3804,6 +3840,18 @@
push(invalidCollectionElement);
return;
}
+
+ if (constantContext != ConstantContext.none &&
+ !library.loader.target.enableConstantUpdate2018) {
+ handleRecoverableError(
+ fasta.templateCantUseControlFlowOrSpreadAsConstant
+ .withArguments(spreadToken),
+ spreadToken,
+ spreadToken);
+ push(invalidCollectionElement);
+ return;
+ }
+
transformCollections = true;
push(forest.spreadElement(toValue(expression), spreadToken));
}
@@ -4115,6 +4163,18 @@
push(invalidCollectionElement);
return;
}
+
+ if (constantContext != ConstantContext.none &&
+ !library.loader.target.enableConstantUpdate2018) {
+ handleRecoverableError(
+ fasta.templateCantUseControlFlowOrSpreadAsConstant
+ .withArguments(forToken),
+ forToken,
+ forToken);
+ push(invalidCollectionElement);
+ return;
+ }
+
transformCollections = true;
VariableDeclaration variable = buildForInVariable(lvalue);
Expression problem = checkForInVariable(lvalue, variable, forToken);
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index d900666..c37983a 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -40,6 +40,7 @@
CantInferPackagesFromPackageUri/example: Fail
CantInferTypeDueToCircularity/example: Fail
CantInferTypeDueToInconsistentOverrides/example: Fail
+CantUseControlFlowOrSpreadAsConstant/example: Fail
CantUseSuperBoundedTypeForInstanceCreation/analyzerCode: Fail
CantUseSuperBoundedTypeForInstanceCreation/example: Fail
ColonInPlaceOfIn/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 962bdb7..bc98cf9 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -3200,6 +3200,10 @@
prefix?.Object;
}
+CantUseControlFlowOrSpreadAsConstant:
+ template: "'#lexeme' is not supported in constant expressions."
+ analyzerCode: NOT_CONSTANT_EXPRESSION
+
CantUseDeferredPrefixAsConstant:
template: >
'#lexeme' can't be used in a constant expression because it's marked as