Report CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE
R=brianwilkerson@google.com, paulberry@google.com
Bug: https://github.com/dart-lang/sdk/issues/25161
Change-Id: I27ebc09fd9fcd6d6d992268f158e80477c41d042
Reviewed-on: https://dart-review.googlesource.com/71424
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index e916ae7..b88db95 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -3897,8 +3897,10 @@
* assigned variable in a for-in statement.
*/
void _checkForInIterable(ForEachStatement node) {
+ DeclaredIdentifier loopVariable = node.loopVariable;
+
// Ignore malformed for statements.
- if (node.identifier == null && node.loopVariable == null) {
+ if (node.identifier == null && loopVariable == null) {
return;
}
@@ -3912,7 +3914,7 @@
}
// The type of the loop variable.
- SimpleIdentifier variable = node.identifier ?? node.loopVariable.identifier;
+ SimpleIdentifier variable = node.identifier ?? loopVariable.identifier;
DartType variableType = getStaticType(variable);
// TODO(mfairhurst) Check and guard against `for(void x in _)`?
@@ -3940,6 +3942,19 @@
}
}
+ if (loopVariable != null) {
+ if (loopVariable.isConst) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE, loopVariable);
+ }
+ } else if (node.identifier != null) {
+ Element variableElement = node.identifier.staticElement;
+ if (variableElement is VariableElement && variableElement.isConst) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE, node.identifier);
+ }
+ }
+
if (bestIterableType == null) {
_errorReporter.reportTypeErrorForNode(
StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE,
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
index fe9840b..0cd7e62 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
@@ -301,6 +301,12 @@
@override
@failingTest
+ test_forInWithConstVariable_forEach_identifier() async {
+ return super.test_forInWithConstVariable_forEach_identifier();
+ }
+
+ @override
+ @failingTest
test_genericFunctionTypeArgument_class() async {
await super.test_genericFunctionTypeArgument_class();
}
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index 27a8c27..d2202d1 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -2965,6 +2965,27 @@
verify([source]);
}
+ test_forInWithConstVariable_forEach_identifier() async {
+ Source source = addSource(r'''
+f() {
+ const x = 0;
+ for (x in [0, 1, 2]) {}
+}''');
+ await computeAnalysisResult(source);
+ assertErrors(source, [CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE]);
+ verify([source]);
+ }
+
+ test_forInWithConstVariable_forEach_loopVariable() async {
+ Source source = addSource(r'''
+f() {
+ for (const x in [0, 1, 2]) {}
+}''');
+ await computeAnalysisResult(source);
+ assertErrors(source, [CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE]);
+ verify([source]);
+ }
+
test_fromEnvironment_bool_badArgs() async {
Source source = addSource(r'''
var b1 = const bool.fromEnvironment(1);
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index 6853053..d5cd7ac 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -4667,7 +4667,8 @@
computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
// validate
_fillErrorListener(VERIFY_ERRORS);
- errorListener.assertNoErrors();
+ errorListener.assertErrorsWithCodes(
+ <ErrorCode>[CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE]);
}
test_perform_ConstantValidator_dependencyCycle() {
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index a8426c0..fd846a6 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -411,7 +411,6 @@
conflicting_generic_interfaces_hierarchy_loop_infinite_test: Skip # Crashes or times out
const_cast2_test/01: CompileTimeError
const_cast2_test/none: CompileTimeError
-const_for_in_variable_test/01: MissingCompileTimeError # Issue 25161
constructor9_test/01: MissingCompileTimeError # CFE Issue 33022
default_implementation2_test: CompileTimeError # Issue 30855
dynamic_prefix_core_test/01: MissingCompileTimeError
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index ab809ec..b11012f 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -36,7 +36,6 @@
const_cast2_test/none: CompileTimeError
const_constructor_mixin3_test/01: MissingCompileTimeError # Issue 33644
const_constructor_mixin_test/01: MissingCompileTimeError # Issue 33644
-const_for_in_variable_test/01: MissingCompileTimeError
constructor9_test/01: MissingCompileTimeError # CFE Issue 33022
constructor_type_parameter_test/00: MissingCompileTimeError
constructor_with_type_parameters_test/03: MissingCompileTimeError