[cfe] Ajust scoping for pattern variables in pattern-for statements

Part of https://github.com/dart-lang/sdk/issues/49749

Change-Id: Ia5551f14b73b6ce50e8e7390f3b7995aaf5fda3b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/284140
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
This commit is contained in:
Chloe Stefantsova
2023-02-20 15:02:26 +00:00
committed by Commit Queue
parent 93e73bf93a
commit 459010fc3f
15 changed files with 512 additions and 8 deletions
@@ -4081,6 +4081,23 @@ class BodyBuilder extends StackListenerImpl
declareVariable(variable, scope);
typeInferrer.assignedVariables.declare(variable);
}
Scope forScope = scope.createNestedScope(
debugName: "pattern-for internal variables",
kind: ScopeKind.forStatement);
exitLocalScope();
enterLocalScope(forScope);
List<VariableDeclaration> internalVariables = [];
for (VariableDeclaration variable in pattern.declaredVariables) {
VariableDeclaration internalVariable = forest.createVariableDeclaration(
variable.fileOffset, variable.name,
initializer:
forest.createVariableGet(variable.fileOffset, variable),
type: variable.type);
internalVariables.add(internalVariable);
declareVariable(internalVariable, scope);
typeInferrer.assignedVariables.declare(internalVariable);
}
push(internalVariables);
push(new PatternVariableDeclaration(pattern, toValue(expression),
fileOffset: offsetForToken(keyword),
isFinal: keyword.lexeme == "final"));
@@ -4131,10 +4148,14 @@ class BodyBuilder extends StackListenerImpl
typeInferrer.assignedVariables.popNode();
Object? variableOrExpression = pop();
List<VariableDeclaration>? variables;
if (variableOrExpression is PatternVariableDeclaration) {
variables = pop() as List<VariableDeclaration>; // Internal variables.
} else {
variables = _buildForLoopVariableDeclarations(variableOrExpression)!;
}
exitLocalScope();
List<VariableDeclaration> variables =
_buildForLoopVariableDeclarations(variableOrExpression)!;
typeInferrer.assignedVariables.pushNode(assignedVariablesNodeInfo);
Expression? condition;
if (conditionStatement is ExpressionStatement) {
@@ -4199,7 +4220,9 @@ class BodyBuilder extends StackListenerImpl
Object? variableOrExpression = pop();
List<VariableDeclaration>? variables =
_buildForLoopVariableDeclarations(variableOrExpression);
variableOrExpression is PatternVariableDeclaration
? pop() as List<VariableDeclaration>
: _buildForLoopVariableDeclarations(variableOrExpression);
exitLocalScope();
JumpTarget continueTarget = exitContinueTarget() as JumpTarget;
JumpTarget breakTarget = exitBreakTarget() as JumpTarget;
@@ -12,7 +12,7 @@ static method test1(dynamic x) → dynamic {
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (#0#6 is{ForNonNullableByDefault} core::int && (let final dynamic #t1 = i = #0#6{core::int} in true))))
throw new _in::ReachabilityError::•();
}
for (; true; ) {
for (core::int i = i; true; ) {
return i;
}
}
@@ -14,7 +14,7 @@ static method test1(dynamic x) → dynamic {
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (#0#6 is{ForNonNullableByDefault} core::int && (let final core::int #t1 = i = #0#6{core::int} in true))))
throw new _in::ReachabilityError::•();
}
for (; true; ) {
for (core::int i = i; true; ) {
return i;
}
}
@@ -12,7 +12,7 @@ static method test1(dynamic x) → dynamic {
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (#0#6 is{ForNonNullableByDefault} core::int && (let final dynamic #t1 = i = #0#6{core::int} in true))))
throw new _in::ReachabilityError::•();
}
for (; true; ) {
for (core::int i = i; true; ) {
return i;
}
}
@@ -12,7 +12,7 @@ static method test1(dynamic x) → dynamic {
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (#0#6 is{ForNonNullableByDefault} core::int && (let final dynamic #t1 = i = #0#6{core::int} in true))))
throw new _in::ReachabilityError::•();
}
for (; true; ) {
for (core::int i = i; true; ) {
return i;
}
}
@@ -14,7 +14,7 @@ static method test1(dynamic x) → dynamic {
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (#0#6 is{ForNonNullableByDefault} core::int && (let final core::int #t1 = i = #0#6{core::int} in true))))
throw new _in::ReachabilityError::•();
}
for (; true; ) {
for (core::int i = i; true; ) {
return i;
}
}
@@ -0,0 +1,51 @@
// Copyright (c) 2023, 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.
test1(dynamic x) {
int i;
for (var [i] = x; true;) {
return i;
}
}
test2(dynamic x) {
for (var [int i] = x; i < 3; i++) {
int i = -1;
return i;
}
}
test3(dynamic x) {
List<int Function()> functions = [];
for (var [int i] = x; i < 5; i++) {
functions.add(() => i);
}
return functions.map((f) => f()).fold(0, (a, x) => a + x);
}
main() {
expectEquals(test1([0]), 0);
expectThrows(() => test1("foo"));
expectEquals(test2([0]), -1);
expectEquals(test3([0]), 10);
}
expectEquals(x, y) {
if (x != y) {
throw "Expected '${x}' to be equal to '${y}'.";
}
}
expectThrows(void Function() f) {
bool hasThrown = true;
try {
f();
hasThrown = false;
} catch (e) {}
if (!hasThrown) {
throw "Expected the function to throw.";
}
}
@@ -0,0 +1,77 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:_internal" as _in;
static method test1(dynamic x) → dynamic {
core::int i;
{
dynamic i;
{
final dynamic #0#0 = x;
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t1 = i = #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic} in true)))
throw new _in::ReachabilityError::•();
}
for (dynamic i = i; true; ) {
return i;
}
}
}
static method test2(dynamic x) → dynamic {
{
core::int i;
{
final dynamic #0#0 = x;
late final dynamic #0#6 = #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (#0#6 is{ForNonNullableByDefault} core::int && (let final dynamic #t2 = i = #0#6{core::int} in true))))
throw new _in::ReachabilityError::•();
}
for (core::int i = i; i.{core::num::<}(3){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
core::int i = 1.{core::int::unary-}(){() → core::int};
return i;
}
}
}
static method test3(dynamic x) → dynamic {
core::List<() → core::int> functions = <() → core::int>[];
{
core::int i;
{
final dynamic #0#0 = x;
late final dynamic #0#6 = #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (#0#6 is{ForNonNullableByDefault} core::int && (let final dynamic #t3 = i = #0#6{core::int} in true))))
throw new _in::ReachabilityError::•();
}
for (core::int i = i; i.{core::num::<}(5){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
functions.{core::List::add}(() → core::int => i){(() → core::int) → void};
}
}
return functions.{core::Iterable::map}<core::int>((() → core::int f) → core::int => f(){() → core::int}){((() → core::int) → core::int) → core::Iterable<core::int>}.{core::Iterable::fold}<core::int>(0, (core::int a, core::int x) → core::int => a.{core::num::+}(x){(core::num) → core::int}){(core::int, (core::int, core::int) → core::int) → core::int};
}
static method main() → dynamic {
self::expectEquals(self::test1(<core::int>[0]), 0);
self::expectThrows(() → void => self::test1("foo"));
self::expectEquals(self::test2(<core::int>[0]), 1.{core::int::unary-}(){() → core::int});
self::expectEquals(self::test3(<core::int>[0]), 10);
}
static method expectEquals(dynamic x, dynamic y) → dynamic {
if(!(x =={core::Object::==}{(core::Object) → core::bool} y)) {
throw "Expected '${x}' to be equal to '${y}'.";
}
}
static method expectThrows(() → void f) → dynamic {
core::bool hasThrown = true;
try {
f(){() → void};
hasThrown = false;
}
on core::Object catch(final core::Object e) {
}
if(!hasThrown) {
throw "Expected the function to throw.";
}
}
constants {
#C1 = 1
}
@@ -0,0 +1,86 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:_internal" as _in;
static method test1(dynamic x) → dynamic {
core::int i;
{
dynamic i;
{
final dynamic #0#0 = x;
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t1 = i = #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic} in true)))
throw new _in::ReachabilityError::•();
}
for (dynamic i = i; true; ) {
return i;
}
}
}
static method test2(dynamic x) → dynamic {
{
core::int i;
{
final dynamic #0#0 = x;
function ##0#6#initializer() → dynamic
return #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
late final dynamic #0#6 = ##0#6#initializer(){() → dynamic};
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (#0#6 is{ForNonNullableByDefault} core::int && (let final core::int #t2 = i = #0#6{core::int} in true))))
throw new _in::ReachabilityError::•();
}
for (core::int i = i; i.{core::num::<}(3){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
core::int i = 1.{core::int::unary-}(){() → core::int};
return i;
}
}
}
static method test3(dynamic x) → dynamic {
core::List<() → core::int> functions = core::_GrowableList::•<() → core::int>(0);
{
core::int i;
{
final dynamic #0#0 = x;
function ##0#6#initializer() → dynamic
return #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
late final dynamic #0#6 = ##0#6#initializer(){() → dynamic};
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (#0#6 is{ForNonNullableByDefault} core::int && (let final core::int #t3 = i = #0#6{core::int} in true))))
throw new _in::ReachabilityError::•();
}
for (core::int i = i; i.{core::num::<}(5){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
functions.{core::List::add}(() → core::int => i){(() → core::int) → void};
}
}
return functions.{core::Iterable::map}<core::int>((() → core::int f) → core::int => f(){() → core::int}){((() → core::int) → core::int) → core::Iterable<core::int>}.{core::Iterable::fold}<core::int>(0, (core::int a, core::int x) → core::int => a.{core::num::+}(x){(core::num) → core::int}){(core::int, (core::int, core::int) → core::int) → core::int};
}
static method main() → dynamic {
self::expectEquals(self::test1(core::_GrowableList::_literal1<core::int>(0)), 0);
self::expectThrows(() → void => self::test1("foo"));
self::expectEquals(self::test2(core::_GrowableList::_literal1<core::int>(0)), 1.{core::int::unary-}(){() → core::int});
self::expectEquals(self::test3(core::_GrowableList::_literal1<core::int>(0)), 10);
}
static method expectEquals(dynamic x, dynamic y) → dynamic {
if(!(x =={core::Object::==}{(core::Object) → core::bool} y)) {
throw "Expected '${x}' to be equal to '${y}'.";
}
}
static method expectThrows(() → void f) → dynamic {
core::bool hasThrown = true;
try {
f(){() → void};
hasThrown = false;
}
on core::Object catch(final core::Object e) {
}
if(!hasThrown) {
throw "Expected the function to throw.";
}
}
constants {
#C1 = 1
}
Extra constant evaluation status:
Evaluated: InstanceInvocation @ org-dartlang-testcase:///variable_scoping_in_pattern_for_statements.dart:14:13 -> IntConstant(-1)
Evaluated: InstanceInvocation @ org-dartlang-testcase:///variable_scoping_in_pattern_for_statements.dart:31:28 -> IntConstant(-1)
Extra constant evaluation: evaluated: 113, effectively constant: 2
@@ -0,0 +1,6 @@
test1(dynamic x) {}
test2(dynamic x) {}
test3(dynamic x) {}
main() {}
expectEquals(x, y) {}
expectThrows(void Function() f) {}
@@ -0,0 +1,6 @@
expectEquals(x, y) {}
expectThrows(void Function() f) {}
main() {}
test1(dynamic x) {}
test2(dynamic x) {}
test3(dynamic x) {}
@@ -0,0 +1,77 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:_internal" as _in;
static method test1(dynamic x) → dynamic {
core::int i;
{
dynamic i;
{
final dynamic #0#0 = x;
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t1 = i = #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic} in true)))
throw new _in::ReachabilityError::•();
}
for (dynamic i = i; true; ) {
return i;
}
}
}
static method test2(dynamic x) → dynamic {
{
core::int i;
{
final dynamic #0#0 = x;
late final dynamic #0#6 = #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (#0#6 is{ForNonNullableByDefault} core::int && (let final dynamic #t2 = i = #0#6{core::int} in true))))
throw new _in::ReachabilityError::•();
}
for (core::int i = i; i.{core::num::<}(3){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
core::int i = 1.{core::int::unary-}(){() → core::int};
return i;
}
}
}
static method test3(dynamic x) → dynamic {
core::List<() → core::int> functions = <() → core::int>[];
{
core::int i;
{
final dynamic #0#0 = x;
late final dynamic #0#6 = #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (#0#6 is{ForNonNullableByDefault} core::int && (let final dynamic #t3 = i = #0#6{core::int} in true))))
throw new _in::ReachabilityError::•();
}
for (core::int i = i; i.{core::num::<}(5){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
functions.{core::List::add}(() → core::int => i){(() → core::int) → void};
}
}
return functions.{core::Iterable::map}<core::int>((() → core::int f) → core::int => f(){() → core::int}){((() → core::int) → core::int) → core::Iterable<core::int>}.{core::Iterable::fold}<core::int>(0, (core::int a, core::int x) → core::int => a.{core::num::+}(x){(core::num) → core::int}){(core::int, (core::int, core::int) → core::int) → core::int};
}
static method main() → dynamic {
self::expectEquals(self::test1(<core::int>[0]), 0);
self::expectThrows(() → void => self::test1("foo"));
self::expectEquals(self::test2(<core::int>[0]), 1.{core::int::unary-}(){() → core::int});
self::expectEquals(self::test3(<core::int>[0]), 10);
}
static method expectEquals(dynamic x, dynamic y) → dynamic {
if(!(x =={core::Object::==}{(core::Object) → core::bool} y)) {
throw "Expected '${x}' to be equal to '${y}'.";
}
}
static method expectThrows(() → void f) → dynamic {
core::bool hasThrown = true;
try {
f(){() → void};
hasThrown = false;
}
on core::Object catch(final core::Object e) {
}
if(!hasThrown) {
throw "Expected the function to throw.";
}
}
constants {
#C1 = 1
}
@@ -0,0 +1,77 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:_internal" as _in;
static method test1(dynamic x) → dynamic {
core::int i;
{
dynamic i;
{
final dynamic #0#0 = x;
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t1 = i = #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic} in true)))
throw new _in::ReachabilityError::•();
}
for (dynamic i = i; true; ) {
return i;
}
}
}
static method test2(dynamic x) → dynamic {
{
core::int i;
{
final dynamic #0#0 = x;
late final dynamic #0#6 = #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (#0#6 is{ForNonNullableByDefault} core::int && (let final dynamic #t2 = i = #0#6{core::int} in true))))
throw new _in::ReachabilityError::•();
}
for (core::int i = i; i.{core::num::<}(3){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
core::int i = 1.{core::int::unary-}(){() → core::int};
return i;
}
}
}
static method test3(dynamic x) → dynamic {
core::List<() → core::int> functions = <() → core::int>[];
{
core::int i;
{
final dynamic #0#0 = x;
late final dynamic #0#6 = #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (#0#6 is{ForNonNullableByDefault} core::int && (let final dynamic #t3 = i = #0#6{core::int} in true))))
throw new _in::ReachabilityError::•();
}
for (core::int i = i; i.{core::num::<}(5){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
functions.{core::List::add}(() → core::int => i){(() → core::int) → void};
}
}
return functions.{core::Iterable::map}<core::int>((() → core::int f) → core::int => f(){() → core::int}){((() → core::int) → core::int) → core::Iterable<core::int>}.{core::Iterable::fold}<core::int>(0, (core::int a, core::int x) → core::int => a.{core::num::+}(x){(core::num) → core::int}){(core::int, (core::int, core::int) → core::int) → core::int};
}
static method main() → dynamic {
self::expectEquals(self::test1(<core::int>[0]), 0);
self::expectThrows(() → void => self::test1("foo"));
self::expectEquals(self::test2(<core::int>[0]), 1.{core::int::unary-}(){() → core::int});
self::expectEquals(self::test3(<core::int>[0]), 10);
}
static method expectEquals(dynamic x, dynamic y) → dynamic {
if(!(x =={core::Object::==}{(core::Object) → core::bool} y)) {
throw "Expected '${x}' to be equal to '${y}'.";
}
}
static method expectThrows(() → void f) → dynamic {
core::bool hasThrown = true;
try {
f(){() → void};
hasThrown = false;
}
on core::Object catch(final core::Object e) {
}
if(!hasThrown) {
throw "Expected the function to throw.";
}
}
constants {
#C1 = 1
}
@@ -0,0 +1,15 @@
library /*isNonNullableByDefault*/;
import self as self;
static method test1(dynamic x) → dynamic
;
static method test2(dynamic x) → dynamic
;
static method test3(dynamic x) → dynamic
;
static method main() → dynamic
;
static method expectEquals(dynamic x, dynamic y) → dynamic
;
static method expectThrows(() → void f) → dynamic
;
@@ -0,0 +1,86 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "dart:_internal" as _in;
static method test1(dynamic x) → dynamic {
core::int i;
{
dynamic i;
{
final dynamic #0#0 = x;
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t1 = i = #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic} in true)))
throw new _in::ReachabilityError::•();
}
for (dynamic i = i; true; ) {
return i;
}
}
}
static method test2(dynamic x) → dynamic {
{
core::int i;
{
final dynamic #0#0 = x;
function ##0#6#initializer() → dynamic
return #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
late final dynamic #0#6 = ##0#6#initializer(){() → dynamic};
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (#0#6 is{ForNonNullableByDefault} core::int && (let final core::int #t2 = i = #0#6{core::int} in true))))
throw new _in::ReachabilityError::•();
}
for (core::int i = i; i.{core::num::<}(3){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
core::int i = 1.{core::int::unary-}(){() → core::int};
return i;
}
}
}
static method test3(dynamic x) → dynamic {
core::List<() → core::int> functions = core::_GrowableList::•<() → core::int>(0);
{
core::int i;
{
final dynamic #0#0 = x;
function ##0#6#initializer() → dynamic
return #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
late final dynamic #0#6 = ##0#6#initializer(){() → dynamic};
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (#0#6 is{ForNonNullableByDefault} core::int && (let final core::int #t3 = i = #0#6{core::int} in true))))
throw new _in::ReachabilityError::•();
}
for (core::int i = i; i.{core::num::<}(5){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
functions.{core::List::add}(() → core::int => i){(() → core::int) → void};
}
}
return functions.{core::Iterable::map}<core::int>((() → core::int f) → core::int => f(){() → core::int}){((() → core::int) → core::int) → core::Iterable<core::int>}.{core::Iterable::fold}<core::int>(0, (core::int a, core::int x) → core::int => a.{core::num::+}(x){(core::num) → core::int}){(core::int, (core::int, core::int) → core::int) → core::int};
}
static method main() → dynamic {
self::expectEquals(self::test1(core::_GrowableList::_literal1<core::int>(0)), 0);
self::expectThrows(() → void => self::test1("foo"));
self::expectEquals(self::test2(core::_GrowableList::_literal1<core::int>(0)), 1.{core::int::unary-}(){() → core::int});
self::expectEquals(self::test3(core::_GrowableList::_literal1<core::int>(0)), 10);
}
static method expectEquals(dynamic x, dynamic y) → dynamic {
if(!(x =={core::Object::==}{(core::Object) → core::bool} y)) {
throw "Expected '${x}' to be equal to '${y}'.";
}
}
static method expectThrows(() → void f) → dynamic {
core::bool hasThrown = true;
try {
f(){() → void};
hasThrown = false;
}
on core::Object catch(final core::Object e) {
}
if(!hasThrown) {
throw "Expected the function to throw.";
}
}
constants {
#C1 = 1
}
Extra constant evaluation status:
Evaluated: InstanceInvocation @ org-dartlang-testcase:///variable_scoping_in_pattern_for_statements.dart:14:13 -> IntConstant(-1)
Evaluated: InstanceInvocation @ org-dartlang-testcase:///variable_scoping_in_pattern_for_statements.dart:31:28 -> IntConstant(-1)
Extra constant evaluation: evaluated: 113, effectively constant: 2