Use promoted type to infer for-each iterables.
Fixes #42653.
Change-Id: I90319b775207e6cc1c6b7a79d29b2c237b750845
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/162625
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/bug42653.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/bug42653.dart
new file mode 100644
index 0000000..45304e0
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/bug42653.dart
@@ -0,0 +1,39 @@
+// 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.
+
+void forEachStatement(Object x) {
+ if (x is int) {
+ /*int*/ x;
+ for (x in [0]) {
+ /*int*/ x;
+ }
+ }
+}
+
+forEachElementInListLiteral(Object x) {
+ if (x is int) {
+ /*int*/ x;
+ return [
+ for (x in [0]) /*int*/ x
+ ];
+ }
+}
+
+forEachElementInMapLiteral(Object x) {
+ if (x is int) {
+ /*int*/ x;
+ return {
+ for (x in [0]) /*int*/ x: /*int*/ x
+ };
+ }
+}
+
+forEachElementInSetLiteral(Object x) {
+ if (x is int) {
+ /*int*/ x;
+ return {
+ for (x in [0]) /*int*/ x
+ };
+ }
+}
diff --git a/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart
index 454eeef..8946ab4 100644
--- a/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/for_resolver.dart
@@ -100,7 +100,7 @@
if (identifier != null) {
identifierElement = identifier.staticElement;
if (identifierElement is VariableElement) {
- valueType = identifierElement.type;
+ valueType = _resolver.localVariableTypeProvider.getType(identifier);
} else if (identifierElement is PropertyAccessorElement) {
var parameters = identifierElement.parameters;
if (parameters.isNotEmpty) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index a956473..f823190 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -6061,8 +6061,14 @@
LocalForInVariable(this.variableSet);
- DartType computeElementType(TypeInferrerImpl inferrer) =>
- variableSet.variable.type;
+ DartType computeElementType(TypeInferrerImpl inferrer) {
+ VariableDeclaration variable = variableSet.variable;
+ DartType promotedType;
+ if (inferrer.isNonNullableByDefault) {
+ promotedType = inferrer.flowAnalysis.promotedType(variable);
+ }
+ return promotedType ?? variable.type;
+ }
Expression inferAssignment(TypeInferrerImpl inferrer, DartType rhsType) {
Expression rhs = inferrer.ensureAssignable(