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 f60989615e7..f40a6b031c7 100644 --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart @@ -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 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? variables; + if (variableOrExpression is PatternVariableDeclaration) { + variables = pop() as List; // Internal variables. + } else { + variables = _buildForLoopVariableDeclarations(variableOrExpression)!; + } exitLocalScope(); - List 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? variables = - _buildForLoopVariableDeclarations(variableOrExpression); + variableOrExpression is PatternVariableDeclaration + ? pop() as List + : _buildForLoopVariableDeclarations(variableOrExpression); exitLocalScope(); JumpTarget continueTarget = exitContinueTarget() as JumpTarget; JumpTarget breakTarget = exitBreakTarget() as JumpTarget; diff --git a/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.strong.expect b/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.strong.expect index da967204c9e..77270549be8 100644 --- a/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.strong.expect +++ b/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.strong.expect @@ -12,7 +12,7 @@ static method test1(dynamic x) → dynamic { if(!(#0#0 is{ForNonNullableByDefault} core::List && #0#0{core::List}.{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; } } diff --git a/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.strong.transformed.expect b/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.strong.transformed.expect index 6f44c7c0568..ae21d169f7c 100644 --- a/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.strong.transformed.expect @@ -14,7 +14,7 @@ static method test1(dynamic x) → dynamic { if(!(#0#0 is{ForNonNullableByDefault} core::List && #0#0{core::List}.{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; } } diff --git a/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.weak.expect b/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.weak.expect index da967204c9e..77270549be8 100644 --- a/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.weak.expect +++ b/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.weak.expect @@ -12,7 +12,7 @@ static method test1(dynamic x) → dynamic { if(!(#0#0 is{ForNonNullableByDefault} core::List && #0#0{core::List}.{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; } } diff --git a/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.weak.modular.expect b/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.weak.modular.expect index da967204c9e..77270549be8 100644 --- a/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.weak.modular.expect +++ b/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.weak.modular.expect @@ -12,7 +12,7 @@ static method test1(dynamic x) → dynamic { if(!(#0#0 is{ForNonNullableByDefault} core::List && #0#0{core::List}.{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; } } diff --git a/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.weak.transformed.expect b/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.weak.transformed.expect index 6f44c7c0568..ae21d169f7c 100644 --- a/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/patterns/simple_pattern_for_statements.dart.weak.transformed.expect @@ -14,7 +14,7 @@ static method test1(dynamic x) → dynamic { if(!(#0#0 is{ForNonNullableByDefault} core::List && #0#0{core::List}.{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; } } diff --git a/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart b/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart new file mode 100644 index 00000000000..fd4ab146ed6 --- /dev/null +++ b/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart @@ -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 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."; + } +} diff --git a/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.strong.expect b/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.strong.expect new file mode 100644 index 00000000000..4bfceeadef2 --- /dev/null +++ b/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.strong.expect @@ -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 && #0#0{core::List}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t1 = i = #0#0{core::List}.{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}.{core::List::[]}(0){(core::int) → dynamic}; + if(!(#0#0 is{ForNonNullableByDefault} core::List && #0#0{core::List}.{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}.{core::List::[]}(0){(core::int) → dynamic}; + if(!(#0#0 is{ForNonNullableByDefault} core::List && #0#0{core::List}.{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 f) → core::int => f(){() → core::int}){((() → core::int) → core::int) → core::Iterable}.{core::Iterable::fold}(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([0]), 0); + self::expectThrows(() → void => self::test1("foo")); + self::expectEquals(self::test2([0]), 1.{core::int::unary-}(){() → core::int}); + self::expectEquals(self::test3([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 +} diff --git a/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.strong.transformed.expect b/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.strong.transformed.expect new file mode 100644 index 00000000000..bfbe52ebba1 --- /dev/null +++ b/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.strong.transformed.expect @@ -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 && #0#0{core::List}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t1 = i = #0#0{core::List}.{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}.{core::List::[]}(0){(core::int) → dynamic}; + late final dynamic #0#6 = ##0#6#initializer(){() → dynamic}; + if(!(#0#0 is{ForNonNullableByDefault} core::List && #0#0{core::List}.{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}.{core::List::[]}(0){(core::int) → dynamic}; + late final dynamic #0#6 = ##0#6#initializer(){() → dynamic}; + if(!(#0#0 is{ForNonNullableByDefault} core::List && #0#0{core::List}.{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 f) → core::int => f(){() → core::int}){((() → core::int) → core::int) → core::Iterable}.{core::Iterable::fold}(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(0)), 0); + self::expectThrows(() → void => self::test1("foo")); + self::expectEquals(self::test2(core::_GrowableList::_literal1(0)), 1.{core::int::unary-}(){() → core::int}); + self::expectEquals(self::test3(core::_GrowableList::_literal1(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 diff --git a/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.textual_outline.expect b/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.textual_outline.expect new file mode 100644 index 00000000000..e33d857d2c5 --- /dev/null +++ b/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.textual_outline.expect @@ -0,0 +1,6 @@ +test1(dynamic x) {} +test2(dynamic x) {} +test3(dynamic x) {} +main() {} +expectEquals(x, y) {} +expectThrows(void Function() f) {} diff --git a/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..8036f8151fd --- /dev/null +++ b/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.textual_outline_modelled.expect @@ -0,0 +1,6 @@ +expectEquals(x, y) {} +expectThrows(void Function() f) {} +main() {} +test1(dynamic x) {} +test2(dynamic x) {} +test3(dynamic x) {} diff --git a/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.weak.expect b/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.weak.expect new file mode 100644 index 00000000000..4bfceeadef2 --- /dev/null +++ b/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.weak.expect @@ -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 && #0#0{core::List}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t1 = i = #0#0{core::List}.{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}.{core::List::[]}(0){(core::int) → dynamic}; + if(!(#0#0 is{ForNonNullableByDefault} core::List && #0#0{core::List}.{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}.{core::List::[]}(0){(core::int) → dynamic}; + if(!(#0#0 is{ForNonNullableByDefault} core::List && #0#0{core::List}.{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 f) → core::int => f(){() → core::int}){((() → core::int) → core::int) → core::Iterable}.{core::Iterable::fold}(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([0]), 0); + self::expectThrows(() → void => self::test1("foo")); + self::expectEquals(self::test2([0]), 1.{core::int::unary-}(){() → core::int}); + self::expectEquals(self::test3([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 +} diff --git a/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.weak.modular.expect b/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.weak.modular.expect new file mode 100644 index 00000000000..4bfceeadef2 --- /dev/null +++ b/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.weak.modular.expect @@ -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 && #0#0{core::List}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t1 = i = #0#0{core::List}.{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}.{core::List::[]}(0){(core::int) → dynamic}; + if(!(#0#0 is{ForNonNullableByDefault} core::List && #0#0{core::List}.{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}.{core::List::[]}(0){(core::int) → dynamic}; + if(!(#0#0 is{ForNonNullableByDefault} core::List && #0#0{core::List}.{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 f) → core::int => f(){() → core::int}){((() → core::int) → core::int) → core::Iterable}.{core::Iterable::fold}(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([0]), 0); + self::expectThrows(() → void => self::test1("foo")); + self::expectEquals(self::test2([0]), 1.{core::int::unary-}(){() → core::int}); + self::expectEquals(self::test3([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 +} diff --git a/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.weak.outline.expect b/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.weak.outline.expect new file mode 100644 index 00000000000..28508a83e36 --- /dev/null +++ b/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.weak.outline.expect @@ -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 + ; diff --git a/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.weak.transformed.expect b/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.weak.transformed.expect new file mode 100644 index 00000000000..bfbe52ebba1 --- /dev/null +++ b/pkg/front_end/testcases/patterns/variable_scoping_in_pattern_for_statements.dart.weak.transformed.expect @@ -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 && #0#0{core::List}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (let final dynamic #t1 = i = #0#0{core::List}.{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}.{core::List::[]}(0){(core::int) → dynamic}; + late final dynamic #0#6 = ##0#6#initializer(){() → dynamic}; + if(!(#0#0 is{ForNonNullableByDefault} core::List && #0#0{core::List}.{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}.{core::List::[]}(0){(core::int) → dynamic}; + late final dynamic #0#6 = ##0#6#initializer(){() → dynamic}; + if(!(#0#0 is{ForNonNullableByDefault} core::List && #0#0{core::List}.{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 f) → core::int => f(){() → core::int}){((() → core::int) → core::int) → core::Iterable}.{core::Iterable::fold}(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(0)), 0); + self::expectThrows(() → void => self::test1("foo")); + self::expectEquals(self::test2(core::_GrowableList::_literal1(0)), 1.{core::int::unary-}(){() → core::int}); + self::expectEquals(self::test3(core::_GrowableList::_literal1(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