85cb56dd20
This changes the pattern matching lowering to avoid using late final variables (or lowerings thereof) and instead inline the initializer where used. This avoids generating closures that are hard for backends to reason about and optimize. Closes #52805 Closes #53804 Change-Id: Ia887446dd4d4475d05cf852c812bfe4b851de261 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/338860 Commit-Queue: Johnni Winther <johnniwinther@google.com> Reviewed-by: Jens Johansen <jensj@google.com>
125 lines
15 KiB
Plaintext
125 lines
15 KiB
Plaintext
library;
|
|
import self as self;
|
|
import "dart:core" as core;
|
|
|
|
static method test(dynamic o, [dynamic expectedRest = #C1]) → dynamic {
|
|
#L1:
|
|
{
|
|
final synthesized dynamic #0#0 = o;
|
|
synthesized core::bool #0#4;
|
|
synthesized core::bool #0#4#isSet = false;
|
|
synthesized core::int #0#2;
|
|
synthesized core::bool #0#2#isSet = false;
|
|
synthesized core::bool #0#8;
|
|
synthesized core::bool #0#8#isSet = false;
|
|
synthesized dynamic #0#9;
|
|
synthesized core::bool #0#9#isSet = false;
|
|
synthesized dynamic #0#12;
|
|
synthesized core::bool #0#12#isSet = false;
|
|
synthesized core::bool #0#19;
|
|
synthesized core::bool #0#19#isSet = false;
|
|
synthesized core::List<dynamic> #0#22;
|
|
synthesized core::bool #0#22#isSet = false;
|
|
synthesized core::bool #0#24;
|
|
synthesized core::bool #0#24#isSet = false;
|
|
synthesized core::bool #0#26;
|
|
synthesized core::bool #0#26#isSet = false;
|
|
synthesized core::int #0#29;
|
|
synthesized core::bool #0#29#isSet = false;
|
|
{
|
|
if(#0#0 is core::List<dynamic> && (#0#4#isSet ?{core::bool} #0#4{core::bool} : let final dynamic #t1 = #0#4#isSet = true in #0#4 = (#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t2 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::>=}(#C2){(core::num) → core::bool}) && (#0#8#isSet ?{core::bool} #0#8{core::bool} : let final dynamic #t3 = #0#8#isSet = true in #0#8 = #C3 =={core::num::==}{(core::Object) → core::bool} #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic}) && #C4 =={core::num::==}{(core::Object) → core::bool} (#0#9#isSet ?{dynamic} #0#9{dynamic} : let final dynamic #t4 = #0#9#isSet = true in #0#9 = #0#0{core::List<dynamic>}.{core::List::[]}(1){(core::int) → dynamic})) {
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
{
|
|
if(#0#0 is core::List<dynamic> && (#0#4#isSet ?{core::bool} #0#4{core::bool} : let final dynamic #t5 = #0#4#isSet = true in #0#4 = (#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t6 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::>=}(#C2){(core::num) → core::bool}) && (#0#8#isSet ?{core::bool} #0#8{core::bool} : let final dynamic #t7 = #0#8#isSet = true in #0#8 = #C3 =={core::num::==}{(core::Object) → core::bool} #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic}) && #C4 =={core::num::==}{(core::Object) → core::bool} (#0#12#isSet ?{dynamic} #0#12{dynamic} : let final dynamic #t8 = #0#12#isSet = true in #0#12 = #0#0{core::List<dynamic>}.{core::List::[]}((#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t9 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::-}(1){(core::num) → core::int}){(core::int) → dynamic})) {
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
{
|
|
hoisted core::List<dynamic> rest;
|
|
if(#0#0 is core::List<dynamic> && (#0#4#isSet ?{core::bool} #0#4{core::bool} : let final dynamic #t10 = #0#4#isSet = true in #0#4 = (#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t11 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::>=}(#C2){(core::num) → core::bool}) && (#0#8#isSet ?{core::bool} #0#8{core::bool} : let final dynamic #t12 = #0#8#isSet = true in #0#8 = #C3 =={core::num::==}{(core::Object) → core::bool} #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic}) && #C2 =={core::num::==}{(core::Object) → core::bool} (#0#9#isSet ?{dynamic} #0#9{dynamic} : let final dynamic #t13 = #0#9#isSet = true in #0#9 = #0#0{core::List<dynamic>}.{core::List::[]}(1){(core::int) → dynamic}) && (let final dynamic #t14 = rest = #0#0{core::List<dynamic>}.{core::List::sublist}(2){(core::int, [core::int?]) → core::List<dynamic>} in true)) {
|
|
{
|
|
self::expect(expectedRest, rest);
|
|
return 2;
|
|
}
|
|
}
|
|
}
|
|
{
|
|
hoisted core::List<dynamic> rest;
|
|
if(#0#0 is core::List<dynamic> && (#0#4#isSet ?{core::bool} #0#4{core::bool} : let final dynamic #t15 = #0#4#isSet = true in #0#4 = (#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t16 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::>=}(#C2){(core::num) → core::bool}) && (#0#8#isSet ?{core::bool} #0#8{core::bool} : let final dynamic #t17 = #0#8#isSet = true in #0#8 = #C3 =={core::num::==}{(core::Object) → core::bool} #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic}) && (let final dynamic #t18 = rest = #0#0{core::List<dynamic>}.{core::List::sublist}(1, (#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t19 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::-}(1){(core::num) → core::int}){(core::int, [core::int?]) → core::List<dynamic>} in true) && #C2 =={core::num::==}{(core::Object) → core::bool} (#0#12#isSet ?{dynamic} #0#12{dynamic} : let final dynamic #t20 = #0#12#isSet = true in #0#12 = #0#0{core::List<dynamic>}.{core::List::[]}((#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t21 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::-}(1){(core::num) → core::int}){(core::int) → dynamic})) {
|
|
{
|
|
self::expect(expectedRest, rest);
|
|
return 3;
|
|
}
|
|
}
|
|
}
|
|
{
|
|
hoisted core::List<dynamic> rest;
|
|
if(#0#0 is core::List<dynamic> && (#0#19#isSet ?{core::bool} #0#19{core::bool} : let final dynamic #t22 = #0#19#isSet = true in #0#19 = (#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t23 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::>=}(#C5){(core::num) → core::bool}) && (#0#8#isSet ?{core::bool} #0#8{core::bool} : let final dynamic #t24 = #0#8#isSet = true in #0#8 = #C3 =={core::num::==}{(core::Object) → core::bool} #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic}) && #C5 =={core::num::==}{(core::Object) → core::bool} (#0#9#isSet ?{dynamic} #0#9{dynamic} : let final dynamic #t25 = #0#9#isSet = true in #0#9 = #0#0{core::List<dynamic>}.{core::List::[]}(1){(core::int) → dynamic}) && (let final dynamic #t26 = rest = #0#22#isSet ?{core::List<dynamic>} #0#22{core::List<dynamic>} : let final dynamic #t27 = #0#22#isSet = true in #0#22 = #0#0{core::List<dynamic>}.{core::List::sublist}(2, (#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t28 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::-}(2){(core::num) → core::int}){(core::int, [core::int?]) → core::List<dynamic>} in true) && (#0#24#isSet ?{core::bool} #0#24{core::bool} : let final dynamic #t29 = #0#24#isSet = true in #0#24 = #C2 =={core::num::==}{(core::Object) → core::bool} #0#0{core::List<dynamic>}.{core::List::[]}((#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t30 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::-}(2){(core::num) → core::int}){(core::int) → dynamic}) && (#0#26#isSet ?{core::bool} #0#26{core::bool} : let final dynamic #t31 = #0#26#isSet = true in #0#26 = #C6 =={core::num::==}{(core::Object) → core::bool} (#0#12#isSet ?{dynamic} #0#12{dynamic} : let final dynamic #t32 = #0#12#isSet = true in #0#12 = #0#0{core::List<dynamic>}.{core::List::[]}((#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t33 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::-}(1){(core::num) → core::int}){(core::int) → dynamic}))) {
|
|
{
|
|
self::expect(expectedRest, rest);
|
|
return 4;
|
|
}
|
|
}
|
|
}
|
|
{
|
|
hoisted core::List<dynamic> rest;
|
|
if(#0#0 is core::List<dynamic> && (#0#19#isSet ?{core::bool} #0#19{core::bool} : let final dynamic #t34 = #0#19#isSet = true in #0#19 = (#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t35 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::>=}(#C5){(core::num) → core::bool}) && (#0#8#isSet ?{core::bool} #0#8{core::bool} : let final dynamic #t36 = #0#8#isSet = true in #0#8 = #C3 =={core::num::==}{(core::Object) → core::bool} #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic}) && #C7 =={core::num::==}{(core::Object) → core::bool} (#0#9#isSet ?{dynamic} #0#9{dynamic} : let final dynamic #t37 = #0#9#isSet = true in #0#9 = #0#0{core::List<dynamic>}.{core::List::[]}(1){(core::int) → dynamic}) && ((#0#29#isSet ?{core::int} #0#29{core::int} : let final dynamic #t38 = #0#29#isSet = true in #0#29 = (#0#22#isSet ?{core::List<dynamic>} #0#22{core::List<dynamic>} : let final dynamic #t39 = #0#22#isSet = true in #0#22 = #0#0{core::List<dynamic>}.{core::List::sublist}(2, (#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t40 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::-}(2){(core::num) → core::int}){(core::int, [core::int?]) → core::List<dynamic>}).{core::List::length}{core::int}).{core::num::>=}(#C2){(core::num) → core::bool} && #C4 =={core::num::==}{(core::Object) → core::bool} (#0#22#isSet ?{core::List<dynamic>} #0#22{core::List<dynamic>} : let final dynamic #t41 = #0#22#isSet = true in #0#22 = #0#0{core::List<dynamic>}.{core::List::sublist}(2, (#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t42 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::-}(2){(core::num) → core::int}){(core::int, [core::int?]) → core::List<dynamic>}).{core::List::[]}(0){(core::int) → dynamic} && (let final dynamic #t43 = rest = (#0#22#isSet ?{core::List<dynamic>} #0#22{core::List<dynamic>} : let final dynamic #t44 = #0#22#isSet = true in #0#22 = #0#0{core::List<dynamic>}.{core::List::sublist}(2, (#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t45 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::-}(2){(core::num) → core::int}){(core::int, [core::int?]) → core::List<dynamic>}).{core::List::sublist}(1, (#0#29#isSet ?{core::int} #0#29{core::int} : let final dynamic #t46 = #0#29#isSet = true in #0#29 = (#0#22#isSet ?{core::List<dynamic>} #0#22{core::List<dynamic>} : let final dynamic #t47 = #0#22#isSet = true in #0#22 = #0#0{core::List<dynamic>}.{core::List::sublist}(2, (#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t48 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::-}(2){(core::num) → core::int}){(core::int, [core::int?]) → core::List<dynamic>}).{core::List::length}{core::int}).{core::num::-}(1){(core::num) → core::int}){(core::int, [core::int?]) → core::List<dynamic>} in true) && #C2 =={core::num::==}{(core::Object) → core::bool} (#0#22#isSet ?{core::List<dynamic>} #0#22{core::List<dynamic>} : let final dynamic #t49 = #0#22#isSet = true in #0#22 = #0#0{core::List<dynamic>}.{core::List::sublist}(2, (#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t50 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::-}(2){(core::num) → core::int}){(core::int, [core::int?]) → core::List<dynamic>}).{core::List::[]}((#0#29#isSet ?{core::int} #0#29{core::int} : let final dynamic #t51 = #0#29#isSet = true in #0#29 = (#0#22#isSet ?{core::List<dynamic>} #0#22{core::List<dynamic>} : let final dynamic #t52 = #0#22#isSet = true in #0#22 = #0#0{core::List<dynamic>}.{core::List::sublist}(2, (#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t53 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::-}(2){(core::num) → core::int}){(core::int, [core::int?]) → core::List<dynamic>}).{core::List::length}{core::int}).{core::num::-}(1){(core::num) → core::int}){(core::int) → dynamic}) && (#0#24#isSet ?{core::bool} #0#24{core::bool} : let final dynamic #t54 = #0#24#isSet = true in #0#24 = #C2 =={core::num::==}{(core::Object) → core::bool} #0#0{core::List<dynamic>}.{core::List::[]}((#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t55 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::-}(2){(core::num) → core::int}){(core::int) → dynamic}) && (#0#26#isSet ?{core::bool} #0#26{core::bool} : let final dynamic #t56 = #0#26#isSet = true in #0#26 = #C6 =={core::num::==}{(core::Object) → core::bool} (#0#12#isSet ?{dynamic} #0#12{dynamic} : let final dynamic #t57 = #0#12#isSet = true in #0#12 = #0#0{core::List<dynamic>}.{core::List::[]}((#0#2#isSet ?{core::int} #0#2{core::int} : let final dynamic #t58 = #0#2#isSet = true in #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int}).{core::num::-}(1){(core::num) → core::int}){(core::int) → dynamic}))) {
|
|
{
|
|
self::expect(expectedRest, rest);
|
|
return 5;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
static method main() → dynamic {
|
|
self::expect(0, self::test(<core::int>[0, 1]));
|
|
self::expect(0, self::test(<core::int>[0, 1, 2]));
|
|
self::expect(1, self::test(<core::int>[0, 2, 1]));
|
|
self::expect(1, self::test(<core::int>[0, 2, 3, 1]));
|
|
self::expect(2, self::test(<core::int>[0, 2], <dynamic>[]));
|
|
self::expect(2, self::test(<core::int>[0, 2, 2], <core::int>[2]));
|
|
self::expect(2, self::test(<core::int>[0, 2, 3], <core::int>[3]));
|
|
self::expect(2, self::test(<core::int>[0, 2, 3, 4], <core::int>[3, 4]));
|
|
self::expect(3, self::test(<core::int>[0, 3, 4, 2], <core::int>[3, 4]));
|
|
self::expect(3, self::test(<core::int>[0, 3, 4, 5, 2], <core::int>[3, 4, 5]));
|
|
self::expect(4, self::test(<core::int>[0, 4, 2, 3], <dynamic>[]));
|
|
self::expect(4, self::test(<core::int>[0, 4, 2, 2, 3], <core::int>[2]));
|
|
self::expect(4, self::test(<core::int>[0, 4, 2, 3, 2, 3], <core::int>[2, 3]));
|
|
self::expect(null, self::test(<core::int>[0, 5, 3, 2, 3]));
|
|
self::expect(null, self::test(<core::Object>[0, 5, <dynamic>[], 2, 3]));
|
|
self::expect(null, self::test(<core::Object>[0, 5, <core::int>[0, 1], 2, 3]));
|
|
self::expect(5, self::test(<core::int>[0, 5, 1, 2, 2, 3], <dynamic>[]));
|
|
self::expect(5, self::test(<core::int>[0, 5, 1, 3, 2, 2, 3], <core::int>[3]));
|
|
}
|
|
static method expect(dynamic expected, dynamic actual) → dynamic {
|
|
if(expected is core::List<dynamic> && actual is core::List<dynamic>) {
|
|
if(expected{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} actual{core::List<dynamic>}.{core::List::length}{core::int}) {
|
|
for (core::int i = 0; i.{core::num::<}(expected{core::List<dynamic>}.{core::List::length}{core::int}){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
|
|
if(!(expected{core::List<dynamic>}.{core::List::[]}(i){(core::int) → dynamic} =={core::Object::==}{(core::Object) → core::bool} actual{core::List<dynamic>}.{core::List::[]}(i){(core::int) → dynamic})) {
|
|
throw "Expected ${expected{core::List<dynamic>}.{core::List::[]}(i){(core::int) → dynamic}}, actual ${actual{core::List<dynamic>}.{core::List::[]}(i){(core::int) → dynamic}} @ index ${i}";
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
|
|
throw "Expected ${expected}, actual ${actual}";
|
|
}
|
|
|
|
constants {
|
|
#C1 = null
|
|
#C2 = 2
|
|
#C3 = 0
|
|
#C4 = 1
|
|
#C5 = 4
|
|
#C6 = 3
|
|
#C7 = 5
|
|
}
|