From 4b9c7c05d4ea7e9bce8b358a767708d758925ecc Mon Sep 17 00:00:00 2001 From: Alexander Markov Date: Fri, 15 Sep 2023 16:54:08 +0000 Subject: [PATCH] [vm, dart2wasm] Early lowering of FunctionTearOff nodes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FunctionTearOff node represents a tear-off of the 'call' method of a Function, so it is basically a no-op: FunctionTearOff(receiver) == receiver So we can remove this node early, during lowering transformation on kernel AST and clean up handling of FunctionTearOff nodes from the VM and dart2wasm compilation pipelines. TEST=ci Change-Id: Ia1500a066a0261076162e018ff0ab502258f606f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/325924 Reviewed-by: Ömer Ağacan Reviewed-by: Ryan Macnak Commit-Queue: Alexander Markov Reviewed-by: Johnni Winther --- pkg/dart2wasm/lib/await_transformer.dart | 3 -- pkg/dart2wasm/lib/code_generator.dart | 5 --- pkg/dart2wasm/lib/transformers.dart | 6 +++ .../bug21938.dart.strong.transformed.expect | 2 +- .../bug21938.dart.weak.transformed.expect | 2 +- .../call.dart.strong.transformed.expect | 26 ++++++------- .../general/call.dart.weak.transformed.expect | 26 ++++++------- ...pe_variable.dart.strong.transformed.expect | 6 +-- ...type_variable.dart.weak.transformed.expect | 6 +-- ...off_of_call.dart.strong.transformed.expect | 2 +- ...aroff_of_call.dart.weak.transformed.expect | 2 +- ...able_access.dart.strong.transformed.expect | 8 ++-- ...llable_access.dart.weak.transformed.expect | 8 ++-- ...ttern_types.dart.strong.transformed.expect | 2 +- ...pattern_types.dart.weak.transformed.expect | 2 +- ...ll_shorting.dart.strong.transformed.expect | 4 +- ...null_shorting.dart.weak.transformed.expect | 4 +- pkg/vm/lib/transformations/lowering.dart | 6 +++ .../type_flow/summary_collector.dart | 5 --- .../type_flow/transformer.dart | 17 --------- .../frontend/kernel_binary_flowgraph.cc | 38 ++----------------- .../frontend/kernel_binary_flowgraph.h | 1 - .../compiler/frontend/kernel_fingerprints.cc | 6 +-- .../frontend/kernel_translation_helper.cc | 6 +-- runtime/vm/compiler/frontend/scope_builder.cc | 6 +-- 25 files changed, 74 insertions(+), 125 deletions(-) diff --git a/pkg/dart2wasm/lib/await_transformer.dart b/pkg/dart2wasm/lib/await_transformer.dart index f0ebf611ee2..3a2c36e4102 100644 --- a/pkg/dart2wasm/lib/await_transformer.dart +++ b/pkg/dart2wasm/lib/await_transformer.dart @@ -843,9 +843,6 @@ class _ExpressionTransformer extends Transformer { @override TreeNode visitInstanceTearOff(InstanceTearOff expr) => unary(expr); - @override - TreeNode visitFunctionTearOff(FunctionTearOff expr) => unary(expr); - @override TreeNode visitSuperPropertySet(SuperPropertySet expr) => unary(expr); diff --git a/pkg/dart2wasm/lib/code_generator.dart b/pkg/dart2wasm/lib/code_generator.dart index 076618a7633..c5e563e0e0f 100644 --- a/pkg/dart2wasm/lib/code_generator.dart +++ b/pkg/dart2wasm/lib/code_generator.dart @@ -2144,11 +2144,6 @@ class CodeGenerator extends ExpressionVisitor1 } } - @override - w.ValueType visitFunctionTearOff( - FunctionTearOff node, w.ValueType expectedType) => - wrap(node.receiver, expectedType); - @override w.ValueType visitInstanceTearOff( InstanceTearOff node, w.ValueType expectedType) { diff --git a/pkg/dart2wasm/lib/transformers.dart b/pkg/dart2wasm/lib/transformers.dart index 04d6bb848a4..5f3f25c96dc 100644 --- a/pkg/dart2wasm/lib/transformers.dart +++ b/pkg/dart2wasm/lib/transformers.dart @@ -710,6 +710,12 @@ class _WasmTransformer extends Transformer { node.transformChildren(this); return _listFactorySpecializer.transformStaticInvocation(node); } + + @override + visitFunctionTearOff(FunctionTearOff node) { + node.transformChildren(this); + return node.receiver; + } } class _AsyncStarFrame { diff --git a/pkg/front_end/testcases/general/bug21938.dart.strong.transformed.expect b/pkg/front_end/testcases/general/bug21938.dart.strong.transformed.expect index a7594fa60c9..a9fbfdcf579 100644 --- a/pkg/front_end/testcases/general/bug21938.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/general/bug21938.dart.strong.transformed.expect @@ -40,7 +40,7 @@ Try correcting the name to the name of an existing method, or defining a method Try correcting the name to the name of an existing method, or defining a method named 'call'. x.call(); ^^^^" in x{}.call(); - f.call; + f; f(5, 2); } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/general/bug21938.dart.weak.transformed.expect b/pkg/front_end/testcases/general/bug21938.dart.weak.transformed.expect index a7594fa60c9..a9fbfdcf579 100644 --- a/pkg/front_end/testcases/general/bug21938.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/general/bug21938.dart.weak.transformed.expect @@ -40,7 +40,7 @@ Try correcting the name to the name of an existing method, or defining a method Try correcting the name to the name of an existing method, or defining a method named 'call'. x.call(); ^^^^" in x{}.call(); - f.call; + f; f(5, 2); } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/general/call.dart.strong.transformed.expect b/pkg/front_end/testcases/general/call.dart.strong.transformed.expect index 45d0ca4e800..9804a19c74e 100644 --- a/pkg/front_end/testcases/general/call.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/general/call.dart.strong.transformed.expect @@ -111,13 +111,13 @@ class CallableGetter extends core::Object { static field (dynamic) → dynamic closure = (dynamic x) → dynamic => x; static field dynamic int1 = self::closure(1){(dynamic) → dynamic}; static field dynamic int2 = self::closure(1){(dynamic) → dynamic}; -static field dynamic int3 = self::closure.call(1){(dynamic) → dynamic}; -static field dynamic int4 = self::closure.call.call(1){(dynamic) → dynamic}; +static field dynamic int3 = self::closure(1){(dynamic) → dynamic}; +static field dynamic int4 = self::closure(1){(dynamic) → dynamic}; static field self::Callable callable = new self::Callable::•(); static field dynamic string1 = self::callable.{self::Callable::call}(1){(dynamic) → dynamic}; static field dynamic string2 = self::callable.{self::Callable::call}(1){(dynamic) → dynamic}; static field dynamic string3 = self::callable.{self::Callable::call}{(dynamic) → dynamic}(1){(dynamic) → dynamic}; -static field dynamic string4 = self::callable.{self::Callable::call}{(dynamic) → dynamic}.call(1){(dynamic) → dynamic}; +static field dynamic string4 = self::callable.{self::Callable::call}{(dynamic) → dynamic}(1){(dynamic) → dynamic}; static field self::CallableGetter callableGetter = new self::CallableGetter::•(); static field invalid-type string5 = invalid-expression "pkg/front_end/testcases/general/call.dart:63:29: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method. - 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'. @@ -135,10 +135,10 @@ var nothing2 = closure.call(); ^" in self::closure{}.(); static field invalid-type nothing3 = invalid-expression "pkg/front_end/testcases/general/call.dart:70:33: Error: Too few positional arguments: 1 required, 0 given. var nothing3 = closure.call.call(); - ^" in self::closure.call{}.(); + ^" in self::closure{}.(); static field invalid-type nothing4 = invalid-expression "pkg/front_end/testcases/general/call.dart:71:38: Error: Too few positional arguments: 1 required, 0 given. var nothing4 = closure.call.call.call(); - ^" in self::closure.call.call{}.(); + ^" in self::closure{}.(); static field invalid-type nothing5 = invalid-expression "pkg/front_end/testcases/general/call.dart:73:24: Error: Too few positional arguments: 1 required, 0 given. var nothing5 = callable(); ^" in self::callable.{self::Callable::call}{}.(){() → invalid-type}; @@ -150,7 +150,7 @@ var nothing7 = callable.call.call(); ^" in self::callable.{self::Callable::call}{(dynamic) → dynamic}{}.(); static field invalid-type nothing8 = invalid-expression "pkg/front_end/testcases/general/call.dart:76:39: Error: Too few positional arguments: 1 required, 0 given. var nothing8 = callable.call.call.call(); - ^" in self::callable.{self::Callable::call}{(dynamic) → dynamic}.call{}.(); + ^" in self::callable.{self::Callable::call}{(dynamic) → dynamic}{}.(); static field invalid-type nothing9 = invalid-expression "pkg/front_end/testcases/general/call.dart:78:30: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method. - 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'. Try changing 'call' to a method or explicitly invoke 'call'. @@ -163,13 +163,13 @@ static method main() → dynamic { (dynamic) → dynamic closure = (dynamic x) → dynamic => x; dynamic int1 = closure(1){(dynamic) → dynamic}; dynamic int2 = closure(1){(dynamic) → dynamic}; - dynamic int3 = closure.call(1){(dynamic) → dynamic}; - dynamic int4 = closure.call.call(1){(dynamic) → dynamic}; + dynamic int3 = closure(1){(dynamic) → dynamic}; + dynamic int4 = closure(1){(dynamic) → dynamic}; self::Callable callable = new self::Callable::•(); dynamic string1 = callable.{self::Callable::call}(1){(dynamic) → dynamic}; dynamic string2 = callable.{self::Callable::call}(1){(dynamic) → dynamic}; dynamic string3 = callable.{self::Callable::call}{(dynamic) → dynamic}(1){(dynamic) → dynamic}; - dynamic string4 = callable.{self::Callable::call}{(dynamic) → dynamic}.call(1){(dynamic) → dynamic}; + dynamic string4 = callable.{self::Callable::call}{(dynamic) → dynamic}(1){(dynamic) → dynamic}; self::CallableGetter callableGetter = new self::CallableGetter::•(); invalid-type string5 = invalid-expression "pkg/front_end/testcases/general/call.dart:29:31: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method. - 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'. @@ -187,10 +187,10 @@ Try changing 'call' to a method or explicitly invoke 'call'. ^" in closure{}.(); invalid-type nothing3 = invalid-expression "pkg/front_end/testcases/general/call.dart:36:35: Error: Too few positional arguments: 1 required, 0 given. var nothing3 = closure.call.call(); - ^" in closure.call{}.(); + ^" in closure{}.(); invalid-type nothing4 = invalid-expression "pkg/front_end/testcases/general/call.dart:37:40: Error: Too few positional arguments: 1 required, 0 given. var nothing4 = closure.call.call.call(); - ^" in closure.call.call{}.(); + ^" in closure{}.(); invalid-type nothing5 = invalid-expression "pkg/front_end/testcases/general/call.dart:39:26: Error: Too few positional arguments: 1 required, 0 given. var nothing5 = callable(); ^" in callable.{self::Callable::call}{}.(){() → invalid-type}; @@ -202,7 +202,7 @@ Try changing 'call' to a method or explicitly invoke 'call'. ^" in callable.{self::Callable::call}{(dynamic) → dynamic}{}.(); invalid-type nothing8 = invalid-expression "pkg/front_end/testcases/general/call.dart:42:41: Error: Too few positional arguments: 1 required, 0 given. var nothing8 = callable.call.call.call(); - ^" in callable.{self::Callable::call}{(dynamic) → dynamic}.call{}.(); + ^" in callable.{self::Callable::call}{(dynamic) → dynamic}{}.(); invalid-type nothing9 = invalid-expression "pkg/front_end/testcases/general/call.dart:44:32: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method. - 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'. Try changing 'call' to a method or explicitly invoke 'call'. @@ -217,4 +217,4 @@ Try changing 'call' to a method or explicitly invoke 'call'. Extra constant evaluation status: Evaluated: VariableGet @ org-dartlang-testcase:///call.dart:30:37 -> IntConstant(1) Evaluated: VariableGet @ org-dartlang-testcase:///call.dart:64:35 -> IntConstant(1) -Extra constant evaluation: evaluated: 101, effectively constant: 2 +Extra constant evaluation: evaluated: 93, effectively constant: 2 diff --git a/pkg/front_end/testcases/general/call.dart.weak.transformed.expect b/pkg/front_end/testcases/general/call.dart.weak.transformed.expect index 45d0ca4e800..9804a19c74e 100644 --- a/pkg/front_end/testcases/general/call.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/general/call.dart.weak.transformed.expect @@ -111,13 +111,13 @@ class CallableGetter extends core::Object { static field (dynamic) → dynamic closure = (dynamic x) → dynamic => x; static field dynamic int1 = self::closure(1){(dynamic) → dynamic}; static field dynamic int2 = self::closure(1){(dynamic) → dynamic}; -static field dynamic int3 = self::closure.call(1){(dynamic) → dynamic}; -static field dynamic int4 = self::closure.call.call(1){(dynamic) → dynamic}; +static field dynamic int3 = self::closure(1){(dynamic) → dynamic}; +static field dynamic int4 = self::closure(1){(dynamic) → dynamic}; static field self::Callable callable = new self::Callable::•(); static field dynamic string1 = self::callable.{self::Callable::call}(1){(dynamic) → dynamic}; static field dynamic string2 = self::callable.{self::Callable::call}(1){(dynamic) → dynamic}; static field dynamic string3 = self::callable.{self::Callable::call}{(dynamic) → dynamic}(1){(dynamic) → dynamic}; -static field dynamic string4 = self::callable.{self::Callable::call}{(dynamic) → dynamic}.call(1){(dynamic) → dynamic}; +static field dynamic string4 = self::callable.{self::Callable::call}{(dynamic) → dynamic}(1){(dynamic) → dynamic}; static field self::CallableGetter callableGetter = new self::CallableGetter::•(); static field invalid-type string5 = invalid-expression "pkg/front_end/testcases/general/call.dart:63:29: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method. - 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'. @@ -135,10 +135,10 @@ var nothing2 = closure.call(); ^" in self::closure{}.(); static field invalid-type nothing3 = invalid-expression "pkg/front_end/testcases/general/call.dart:70:33: Error: Too few positional arguments: 1 required, 0 given. var nothing3 = closure.call.call(); - ^" in self::closure.call{}.(); + ^" in self::closure{}.(); static field invalid-type nothing4 = invalid-expression "pkg/front_end/testcases/general/call.dart:71:38: Error: Too few positional arguments: 1 required, 0 given. var nothing4 = closure.call.call.call(); - ^" in self::closure.call.call{}.(); + ^" in self::closure{}.(); static field invalid-type nothing5 = invalid-expression "pkg/front_end/testcases/general/call.dart:73:24: Error: Too few positional arguments: 1 required, 0 given. var nothing5 = callable(); ^" in self::callable.{self::Callable::call}{}.(){() → invalid-type}; @@ -150,7 +150,7 @@ var nothing7 = callable.call.call(); ^" in self::callable.{self::Callable::call}{(dynamic) → dynamic}{}.(); static field invalid-type nothing8 = invalid-expression "pkg/front_end/testcases/general/call.dart:76:39: Error: Too few positional arguments: 1 required, 0 given. var nothing8 = callable.call.call.call(); - ^" in self::callable.{self::Callable::call}{(dynamic) → dynamic}.call{}.(); + ^" in self::callable.{self::Callable::call}{(dynamic) → dynamic}{}.(); static field invalid-type nothing9 = invalid-expression "pkg/front_end/testcases/general/call.dart:78:30: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method. - 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'. Try changing 'call' to a method or explicitly invoke 'call'. @@ -163,13 +163,13 @@ static method main() → dynamic { (dynamic) → dynamic closure = (dynamic x) → dynamic => x; dynamic int1 = closure(1){(dynamic) → dynamic}; dynamic int2 = closure(1){(dynamic) → dynamic}; - dynamic int3 = closure.call(1){(dynamic) → dynamic}; - dynamic int4 = closure.call.call(1){(dynamic) → dynamic}; + dynamic int3 = closure(1){(dynamic) → dynamic}; + dynamic int4 = closure(1){(dynamic) → dynamic}; self::Callable callable = new self::Callable::•(); dynamic string1 = callable.{self::Callable::call}(1){(dynamic) → dynamic}; dynamic string2 = callable.{self::Callable::call}(1){(dynamic) → dynamic}; dynamic string3 = callable.{self::Callable::call}{(dynamic) → dynamic}(1){(dynamic) → dynamic}; - dynamic string4 = callable.{self::Callable::call}{(dynamic) → dynamic}.call(1){(dynamic) → dynamic}; + dynamic string4 = callable.{self::Callable::call}{(dynamic) → dynamic}(1){(dynamic) → dynamic}; self::CallableGetter callableGetter = new self::CallableGetter::•(); invalid-type string5 = invalid-expression "pkg/front_end/testcases/general/call.dart:29:31: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method. - 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'. @@ -187,10 +187,10 @@ Try changing 'call' to a method or explicitly invoke 'call'. ^" in closure{}.(); invalid-type nothing3 = invalid-expression "pkg/front_end/testcases/general/call.dart:36:35: Error: Too few positional arguments: 1 required, 0 given. var nothing3 = closure.call.call(); - ^" in closure.call{}.(); + ^" in closure{}.(); invalid-type nothing4 = invalid-expression "pkg/front_end/testcases/general/call.dart:37:40: Error: Too few positional arguments: 1 required, 0 given. var nothing4 = closure.call.call.call(); - ^" in closure.call.call{}.(); + ^" in closure{}.(); invalid-type nothing5 = invalid-expression "pkg/front_end/testcases/general/call.dart:39:26: Error: Too few positional arguments: 1 required, 0 given. var nothing5 = callable(); ^" in callable.{self::Callable::call}{}.(){() → invalid-type}; @@ -202,7 +202,7 @@ Try changing 'call' to a method or explicitly invoke 'call'. ^" in callable.{self::Callable::call}{(dynamic) → dynamic}{}.(); invalid-type nothing8 = invalid-expression "pkg/front_end/testcases/general/call.dart:42:41: Error: Too few positional arguments: 1 required, 0 given. var nothing8 = callable.call.call.call(); - ^" in callable.{self::Callable::call}{(dynamic) → dynamic}.call{}.(); + ^" in callable.{self::Callable::call}{(dynamic) → dynamic}{}.(); invalid-type nothing9 = invalid-expression "pkg/front_end/testcases/general/call.dart:44:32: Error: Cannot invoke an instance of 'CallableGetter' because it declares 'call' to be something other than a method. - 'CallableGetter' is from 'pkg/front_end/testcases/general/call.dart'. Try changing 'call' to a method or explicitly invoke 'call'. @@ -217,4 +217,4 @@ Try changing 'call' to a method or explicitly invoke 'call'. Extra constant evaluation status: Evaluated: VariableGet @ org-dartlang-testcase:///call.dart:30:37 -> IntConstant(1) Evaluated: VariableGet @ org-dartlang-testcase:///call.dart:64:35 -> IntConstant(1) -Extra constant evaluation: evaluated: 101, effectively constant: 2 +Extra constant evaluation: evaluated: 93, effectively constant: 2 diff --git a/pkg/front_end/testcases/general/callable_type_variable.dart.strong.transformed.expect b/pkg/front_end/testcases/general/callable_type_variable.dart.strong.transformed.expect index 61b47c3493e..4fcd99b6581 100644 --- a/pkg/front_end/testcases/general/callable_type_variable.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/general/callable_type_variable.dart.strong.transformed.expect @@ -21,7 +21,7 @@ class Class1 extends core::Object { method method() → dynamic { dynamic v1 = this.{self::Class1::field}{self::Class1::T}(); dynamic v2 = let final core::int #t1 = 0 in this.{self::Class1::field}{self::Class1::T}(#t1); - self::Class1::T v3 = this.{self::Class1::field}{self::Class1::T}.call; + self::Class1::T v3 = this.{self::Class1::field}{self::Class1::T}; dynamic v4 = this.{self::Class1::field}{self::Class1::T}(); dynamic v5 = this.{self::Class1::field}{self::Class1::T}(0); } @@ -36,7 +36,7 @@ class Class2 extends core::Object { var v1 = field(); // error ^" in this.{self::Class2::field}{self::Class2::T}{}.(); core::String v2 = let final core::int #t2 = 0 in this.{self::Class2::field}{self::Class2::T}(#t2){(core::int) → core::String}; - self::Class2::T v3 = this.{self::Class2::field}{self::Class2::T}.call; + self::Class2::T v3 = this.{self::Class2::field}{self::Class2::T}; invalid-type v4 = invalid-expression "pkg/front_end/testcases/general/callable_type_variable.dart:28:24: Error: Too few positional arguments: 1 required, 0 given. var v4 = field.call(); // error ^" in this.{self::Class2::field}{self::Class2::T}{}.(); @@ -49,4 +49,4 @@ static method main() → dynamic {} Extra constant evaluation status: Evaluated: VariableGet @ org-dartlang-testcase:///callable_type_variable.dart:12:20 -> IntConstant(0) Evaluated: VariableGet @ org-dartlang-testcase:///callable_type_variable.dart:26:20 -> IntConstant(0) -Extra constant evaluation: evaluated: 30, effectively constant: 2 +Extra constant evaluation: evaluated: 28, effectively constant: 2 diff --git a/pkg/front_end/testcases/general/callable_type_variable.dart.weak.transformed.expect b/pkg/front_end/testcases/general/callable_type_variable.dart.weak.transformed.expect index 61b47c3493e..4fcd99b6581 100644 --- a/pkg/front_end/testcases/general/callable_type_variable.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/general/callable_type_variable.dart.weak.transformed.expect @@ -21,7 +21,7 @@ class Class1 extends core::Object { method method() → dynamic { dynamic v1 = this.{self::Class1::field}{self::Class1::T}(); dynamic v2 = let final core::int #t1 = 0 in this.{self::Class1::field}{self::Class1::T}(#t1); - self::Class1::T v3 = this.{self::Class1::field}{self::Class1::T}.call; + self::Class1::T v3 = this.{self::Class1::field}{self::Class1::T}; dynamic v4 = this.{self::Class1::field}{self::Class1::T}(); dynamic v5 = this.{self::Class1::field}{self::Class1::T}(0); } @@ -36,7 +36,7 @@ class Class2 extends core::Object { var v1 = field(); // error ^" in this.{self::Class2::field}{self::Class2::T}{}.(); core::String v2 = let final core::int #t2 = 0 in this.{self::Class2::field}{self::Class2::T}(#t2){(core::int) → core::String}; - self::Class2::T v3 = this.{self::Class2::field}{self::Class2::T}.call; + self::Class2::T v3 = this.{self::Class2::field}{self::Class2::T}; invalid-type v4 = invalid-expression "pkg/front_end/testcases/general/callable_type_variable.dart:28:24: Error: Too few positional arguments: 1 required, 0 given. var v4 = field.call(); // error ^" in this.{self::Class2::field}{self::Class2::T}{}.(); @@ -49,4 +49,4 @@ static method main() → dynamic {} Extra constant evaluation status: Evaluated: VariableGet @ org-dartlang-testcase:///callable_type_variable.dart:12:20 -> IntConstant(0) Evaluated: VariableGet @ org-dartlang-testcase:///callable_type_variable.dart:26:20 -> IntConstant(0) -Extra constant evaluation: evaluated: 30, effectively constant: 2 +Extra constant evaluation: evaluated: 28, effectively constant: 2 diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.strong.transformed.expect index 11ce2fa4822..db5d68a205b 100644 --- a/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.strong.transformed.expect @@ -17,6 +17,6 @@ static method test((T*) →* T* f) → void { (core::int*) →* core::int* func; func = invalid-expression "pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart:12:12: Error: A value of type 'T Function(T)' can't be assigned to a variable of type 'int Function(int)'. func = f.call; - ^" in f.call as{TypeError,ForLegacy} (core::int*) →* core::int*; + ^" in f as{TypeError,ForLegacy} (core::int*) →* core::int*; } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.weak.transformed.expect index 74faced195d..1444f0508a6 100644 --- a/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.weak.transformed.expect @@ -13,6 +13,6 @@ static method test((T*) →* T* f) → void { (core::int*) →* core::int* func; func = invalid-expression "pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart:12:12: Error: A value of type 'T Function(T)' can't be assigned to a variable of type 'int Function(int)'. func = f.call; - ^" in f.call as{TypeError,ForLegacy} (core::int*) →* core::int*; + ^" in f as{TypeError,ForLegacy} (core::int*) →* core::int*; } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.transformed.expect index 415839d6b1e..27307afaf05 100644 --- a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.strong.transformed.expect @@ -507,7 +507,7 @@ static field core::Function? topLevelFunctionTearOff = invalid-expression "pkg/f - 'Function' is from 'dart:core'. Try accessing using ?. instead. var topLevelFunctionTearOff = nullableFunction.call; - ^^^^" in self::nullableFunction.call; + ^^^^" in self::nullableFunction; static field void topLevelFunctionTypeImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null. Try calling using ?.call instead. var topLevelFunctionTypeImplicitCall = nullableFunctionType(); @@ -519,7 +519,7 @@ var topLevelFunctionTypeExplicitCall = nullableFunctionType.call(); static field () →? void topLevelFunctionTypeTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null. Try accessing using ?. instead. var topLevelFunctionTypeTearOff = nullableFunctionType.call; - ^^^^" in self::nullableFunctionType.call; + ^^^^" in self::nullableFunctionType; static field dynamic topLevelFunctionField = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null. - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'. Try calling using ?.call instead. @@ -714,7 +714,7 @@ Try calling using ?. instead. - 'Function' is from 'dart:core'. Try accessing using ?. instead. var localFunctionTearOff = nullableFunction.call; - ^^^^" in self::nullableFunction.call; + ^^^^" in self::nullableFunction; void localFunctionTypeImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:89:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null. Try calling using ?.call instead. var localFunctionTypeImplicitCall = nullableFunctionType(); @@ -726,7 +726,7 @@ Try calling using ?. instead. () →? void localFunctionTypeTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:91:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null. Try accessing using ?. instead. var localFunctionTypeTearOff = nullableFunctionType.call; - ^^^^" in self::nullableFunctionType.call; + ^^^^" in self::nullableFunctionType; dynamic localFunctionField = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:92:42: Error: Can't use an expression of type 'Class?' as a function because it's potentially null. - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'. Try calling using ?.call instead. diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.transformed.expect index 415839d6b1e..27307afaf05 100644 --- a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.weak.transformed.expect @@ -507,7 +507,7 @@ static field core::Function? topLevelFunctionTearOff = invalid-expression "pkg/f - 'Function' is from 'dart:core'. Try accessing using ?. instead. var topLevelFunctionTearOff = nullableFunction.call; - ^^^^" in self::nullableFunction.call; + ^^^^" in self::nullableFunction; static field void topLevelFunctionTypeImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:50:60: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null. Try calling using ?.call instead. var topLevelFunctionTypeImplicitCall = nullableFunctionType(); @@ -519,7 +519,7 @@ var topLevelFunctionTypeExplicitCall = nullableFunctionType.call(); static field () →? void topLevelFunctionTypeTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:52:56: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null. Try accessing using ?. instead. var topLevelFunctionTypeTearOff = nullableFunctionType.call; - ^^^^" in self::nullableFunctionType.call; + ^^^^" in self::nullableFunctionType; static field dynamic topLevelFunctionField = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:53:43: Error: Can't use an expression of type 'Class?' as a function because it's potentially null. - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'. Try calling using ?.call instead. @@ -714,7 +714,7 @@ Try calling using ?. instead. - 'Function' is from 'dart:core'. Try accessing using ?. instead. var localFunctionTearOff = nullableFunction.call; - ^^^^" in self::nullableFunction.call; + ^^^^" in self::nullableFunction; void localFunctionTypeImplicitCall = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:89:59: Error: Can't use an expression of type 'void Function()?' as a function because it's potentially null. Try calling using ?.call instead. var localFunctionTypeImplicitCall = nullableFunctionType(); @@ -726,7 +726,7 @@ Try calling using ?. instead. () →? void localFunctionTypeTearOff = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:91:55: Error: Property 'call' cannot be accessed on 'void Function()?' because it is potentially null. Try accessing using ?. instead. var localFunctionTypeTearOff = nullableFunctionType.call; - ^^^^" in self::nullableFunctionType.call; + ^^^^" in self::nullableFunctionType; dynamic localFunctionField = invalid-expression "pkg/front_end/testcases/nnbd/potentially_nullable_access.dart:92:42: Error: Can't use an expression of type 'Class?' as a function because it's potentially null. - 'Class' is from 'pkg/front_end/testcases/nnbd/potentially_nullable_access.dart'. Try calling using ?.call instead. diff --git a/pkg/front_end/testcases/patterns/pattern_types.dart.strong.transformed.expect b/pkg/front_end/testcases/patterns/pattern_types.dart.strong.transformed.expect index b10a2fe66b4..d39b377fed6 100644 --- a/pkg/front_end/testcases/patterns/pattern_types.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/patterns/pattern_types.dart.strong.transformed.expect @@ -227,7 +227,7 @@ static method objectPattern(dynamic o) → dynamic { lowered core::int $1#case#1; lowered core::String named#case#1; invalid-type ambiguousField; - if(#0#0 is Null && (let final core::int #t1 = hashCode = #0#0{Null}.{core::Object::hashCode}{core::int} in true) || #0#0 is Null && (let final () → core::String #t2 = toString = #0#0{Null}.{core::Object::toString}{() → core::String} in true) || #0#0 is self::Class && (let final dynamic #t3 = field#case#0 = #0#5#isSet ?{dynamic} #0#5{dynamic} : let final core::bool* #t4 = #0#5#isSet = true in #0#5 = #0#0{self::Class}.{self::Class::field}{dynamic} in true) || #0#0 is self::Class && (let final () → void #t5 = method#case#0 = #0#6#isSet ?{() → void} #0#6{() → void} : let final core::bool* #t6 = #0#6#isSet = true in #0#6 = #0#0{self::Class}.{self::Class::method}{() → void} in true) || #0#0 is self::Class && (let final core::int #t7 = extensionGetter#case#0 = self::_extension#0|get#extensionGetter(#0#0{self::Class}) in true) || #0#0 is self::Class && (let final () → void #t8 = extensionMethod#case#0 = self::_extension#0|get#extensionMethod(#0#0{self::Class}) in true) || #0#0 is dynamic && (let final dynamic #t9 = dynamicAccess = #0#0{dynamic}.dynamicAccess in true) || #0#0 is () → void && (let final () → void #t10 = call#case#0 = #0#12#isSet ?{() → void} #0#12{() → void} : let final core::bool* #t11 = #0#12#isSet = true in #0#12 = #0#0{() → void}.call in true) || #0#0 is (core::int, {required named: core::String}) && (let final core::int #t12 = $1#case#0 = #0#14#isSet ?{core::int} #0#14{core::int} : let final core::bool* #t13 = #0#14#isSet = true in #0#14 = #0#0{(core::int, {required named: core::String})}.$1{core::int} in true) || #0#0 is (core::int, {required named: core::String}) && (let final core::String #t14 = named#case#0 = #0#15#isSet ?{core::String} #0#15{core::String} : let final core::bool* #t15 = #0#15#isSet = true in #0#15 = #0#0{(core::int, {required named: core::String})}.named{core::String} in true) || #0#0 is self::Class && (let final invalid-type #t16 = invalid-expression "pkg/front_end/testcases/patterns/pattern_types.dart:73:16: Error: The getter 'missing' isn't defined for the class 'Class'. + if(#0#0 is Null && (let final core::int #t1 = hashCode = #0#0{Null}.{core::Object::hashCode}{core::int} in true) || #0#0 is Null && (let final () → core::String #t2 = toString = #0#0{Null}.{core::Object::toString}{() → core::String} in true) || #0#0 is self::Class && (let final dynamic #t3 = field#case#0 = #0#5#isSet ?{dynamic} #0#5{dynamic} : let final core::bool* #t4 = #0#5#isSet = true in #0#5 = #0#0{self::Class}.{self::Class::field}{dynamic} in true) || #0#0 is self::Class && (let final () → void #t5 = method#case#0 = #0#6#isSet ?{() → void} #0#6{() → void} : let final core::bool* #t6 = #0#6#isSet = true in #0#6 = #0#0{self::Class}.{self::Class::method}{() → void} in true) || #0#0 is self::Class && (let final core::int #t7 = extensionGetter#case#0 = self::_extension#0|get#extensionGetter(#0#0{self::Class}) in true) || #0#0 is self::Class && (let final () → void #t8 = extensionMethod#case#0 = self::_extension#0|get#extensionMethod(#0#0{self::Class}) in true) || #0#0 is dynamic && (let final dynamic #t9 = dynamicAccess = #0#0{dynamic}.dynamicAccess in true) || #0#0 is () → void && (let final () → void #t10 = call#case#0 = #0#12#isSet ?{() → void} #0#12{() → void} : let final core::bool* #t11 = #0#12#isSet = true in #0#12 = #0#0{() → void} in true) || #0#0 is (core::int, {required named: core::String}) && (let final core::int #t12 = $1#case#0 = #0#14#isSet ?{core::int} #0#14{core::int} : let final core::bool* #t13 = #0#14#isSet = true in #0#14 = #0#0{(core::int, {required named: core::String})}.$1{core::int} in true) || #0#0 is (core::int, {required named: core::String}) && (let final core::String #t14 = named#case#0 = #0#15#isSet ?{core::String} #0#15{core::String} : let final core::bool* #t15 = #0#15#isSet = true in #0#15 = #0#0{(core::int, {required named: core::String})}.named{core::String} in true) || #0#0 is self::Class && (let final invalid-type #t16 = invalid-expression "pkg/front_end/testcases/patterns/pattern_types.dart:73:16: Error: The getter 'missing' isn't defined for the class 'Class'. - 'Class' is from 'pkg/front_end/testcases/patterns/pattern_types.dart'. Try correcting the name to the name of an existing getter, or defining a getter or field named 'missing'. case Class(: var missing): // Error: missing getter diff --git a/pkg/front_end/testcases/patterns/pattern_types.dart.weak.transformed.expect b/pkg/front_end/testcases/patterns/pattern_types.dart.weak.transformed.expect index 6bf8fdb8926..80867aa05a0 100644 --- a/pkg/front_end/testcases/patterns/pattern_types.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/patterns/pattern_types.dart.weak.transformed.expect @@ -228,7 +228,7 @@ static method objectPattern(dynamic o) → dynamic { lowered core::int $1#case#1; lowered core::String named#case#1; invalid-type ambiguousField; - if(#0#0 is Null && (let final core::int #t1 = hashCode = #0#0{Null}.{core::Object::hashCode}{core::int} in true) || #0#0 is Null && (let final () → core::String #t2 = toString = #0#0{Null}.{core::Object::toString}{() → core::String} in true) || #0#0 is self::Class && (let final dynamic #t3 = field#case#0 = #0#5#isSet ?{dynamic} #0#5{dynamic} : let final core::bool* #t4 = #0#5#isSet = true in #0#5 = #0#0{self::Class}.{self::Class::field}{dynamic} in true) || #0#0 is self::Class && (let final () → void #t5 = method#case#0 = #0#6#isSet ?{() → void} #0#6{() → void} : let final core::bool* #t6 = #0#6#isSet = true in #0#6 = #0#0{self::Class}.{self::Class::method}{() → void} in true) || #0#0 is self::Class && (let final core::int #t7 = extensionGetter#case#0 = self::_extension#0|get#extensionGetter(#0#0{self::Class}) in true) || #0#0 is self::Class && (let final () → void #t8 = extensionMethod#case#0 = self::_extension#0|get#extensionMethod(#0#0{self::Class}) in true) || #0#0 is dynamic && (let final dynamic #t9 = dynamicAccess = #0#0{dynamic}.dynamicAccess in true) || #0#0 is () → void && (let final () → void #t10 = call#case#0 = #0#12#isSet ?{() → void} #0#12{() → void} : let final core::bool* #t11 = #0#12#isSet = true in #0#12 = #0#0{() → void}.call in true) || #0#0 is (core::int, {required named: core::String}) && (let final core::int #t12 = $1#case#0 = #0#14#isSet ?{core::int} #0#14{core::int} : let final core::bool* #t13 = #0#14#isSet = true in #0#14 = #0#0{(core::int, {required named: core::String})}.$1{core::int} in true) || #0#0 is (core::int, {required named: core::String}) && (let final core::String #t14 = named#case#0 = #0#15#isSet ?{core::String} #0#15{core::String} : let final core::bool* #t15 = #0#15#isSet = true in #0#15 = #0#0{(core::int, {required named: core::String})}.named{core::String} in true) || #0#0 is self::Class && (let final invalid-type #t16 = invalid-expression "pkg/front_end/testcases/patterns/pattern_types.dart:73:16: Error: The getter 'missing' isn't defined for the class 'Class'. + if(#0#0 is Null && (let final core::int #t1 = hashCode = #0#0{Null}.{core::Object::hashCode}{core::int} in true) || #0#0 is Null && (let final () → core::String #t2 = toString = #0#0{Null}.{core::Object::toString}{() → core::String} in true) || #0#0 is self::Class && (let final dynamic #t3 = field#case#0 = #0#5#isSet ?{dynamic} #0#5{dynamic} : let final core::bool* #t4 = #0#5#isSet = true in #0#5 = #0#0{self::Class}.{self::Class::field}{dynamic} in true) || #0#0 is self::Class && (let final () → void #t5 = method#case#0 = #0#6#isSet ?{() → void} #0#6{() → void} : let final core::bool* #t6 = #0#6#isSet = true in #0#6 = #0#0{self::Class}.{self::Class::method}{() → void} in true) || #0#0 is self::Class && (let final core::int #t7 = extensionGetter#case#0 = self::_extension#0|get#extensionGetter(#0#0{self::Class}) in true) || #0#0 is self::Class && (let final () → void #t8 = extensionMethod#case#0 = self::_extension#0|get#extensionMethod(#0#0{self::Class}) in true) || #0#0 is dynamic && (let final dynamic #t9 = dynamicAccess = #0#0{dynamic}.dynamicAccess in true) || #0#0 is () → void && (let final () → void #t10 = call#case#0 = #0#12#isSet ?{() → void} #0#12{() → void} : let final core::bool* #t11 = #0#12#isSet = true in #0#12 = #0#0{() → void} in true) || #0#0 is (core::int, {required named: core::String}) && (let final core::int #t12 = $1#case#0 = #0#14#isSet ?{core::int} #0#14{core::int} : let final core::bool* #t13 = #0#14#isSet = true in #0#14 = #0#0{(core::int, {required named: core::String})}.$1{core::int} in true) || #0#0 is (core::int, {required named: core::String}) && (let final core::String #t14 = named#case#0 = #0#15#isSet ?{core::String} #0#15{core::String} : let final core::bool* #t15 = #0#15#isSet = true in #0#15 = #0#0{(core::int, {required named: core::String})}.named{core::String} in true) || #0#0 is self::Class && (let final invalid-type #t16 = invalid-expression "pkg/front_end/testcases/patterns/pattern_types.dart:73:16: Error: The getter 'missing' isn't defined for the class 'Class'. - 'Class' is from 'pkg/front_end/testcases/patterns/pattern_types.dart'. Try correcting the name to the name of an existing getter, or defining a getter or field named 'missing'. case Class(: var missing): // Error: missing getter diff --git a/pkg/front_end/testcases/records/null_shorting.dart.strong.transformed.expect b/pkg/front_end/testcases/records/null_shorting.dart.strong.transformed.expect index 4c0989785bd..15c309f627e 100644 --- a/pkg/front_end/testcases/records/null_shorting.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/records/null_shorting.dart.strong.transformed.expect @@ -147,7 +147,7 @@ Try calling using ?.call instead. let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t11 = record in #t11 == null ?{core::bool?} null : #t11{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$1{core::int}.{core::int::isEven}{core::bool}; let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t12 = record in #t12 == null ?{core::int?} null : #t12{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$2{core::String}.{core::String::length}{core::int}; let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t13 = record in #t13 == null ?{core::bool?} null : #t13{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.d{core::double}.{core::num::isNaN}{core::bool}; - let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t14 = record in #t14 == null ?{() →? void} null : #t14{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.f{() → void}.call; + let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t14 = record in #t14 == null ?{() →? void} null : #t14{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.f{() → void}; let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t15 = record in #t15 == null ?{() →? void} null : #t15{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.c{self::Class}.{self::Class::call}{() → void}; let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t16 = list in #t16 == null ?{core::int?} null : #t16{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$1{core::int}; let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t17 = list in #t17 == null ?{core::String?} null : #t17{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$2{core::String}; @@ -162,7 +162,7 @@ Try calling using ?.call instead. let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t26 = list in #t26 == null ?{core::bool?} null : #t26{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$1{core::int}.{core::int::isEven}{core::bool}; let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t27 = list in #t27 == null ?{core::int?} null : #t27{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$2{core::String}.{core::String::length}{core::int}; let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t28 = list in #t28 == null ?{core::bool?} null : #t28{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.d{core::double}.{core::num::isNaN}{core::bool}; - let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t29 = list in #t29 == null ?{() →? void} null : #t29{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.f{() → void}.call; + let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t29 = list in #t29 == null ?{() →? void} null : #t29{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.f{() → void}; let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t30 = list in #t30 == null ?{() →? void} null : #t30{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.c{self::Class}.{self::Class::call}{() → void}; } static extension-member method _extension#0|call(lowered final core::int #this) → void {} diff --git a/pkg/front_end/testcases/records/null_shorting.dart.weak.transformed.expect b/pkg/front_end/testcases/records/null_shorting.dart.weak.transformed.expect index 4c0989785bd..15c309f627e 100644 --- a/pkg/front_end/testcases/records/null_shorting.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/records/null_shorting.dart.weak.transformed.expect @@ -147,7 +147,7 @@ Try calling using ?.call instead. let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t11 = record in #t11 == null ?{core::bool?} null : #t11{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$1{core::int}.{core::int::isEven}{core::bool}; let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t12 = record in #t12 == null ?{core::int?} null : #t12{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$2{core::String}.{core::String::length}{core::int}; let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t13 = record in #t13 == null ?{core::bool?} null : #t13{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.d{core::double}.{core::num::isNaN}{core::bool}; - let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t14 = record in #t14 == null ?{() →? void} null : #t14{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.f{() → void}.call; + let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t14 = record in #t14 == null ?{() →? void} null : #t14{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.f{() → void}; let final(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})? #t15 = record in #t15 == null ?{() →? void} null : #t15{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.c{self::Class}.{self::Class::call}{() → void}; let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t16 = list in #t16 == null ?{core::int?} null : #t16{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$1{core::int}; let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t17 = list in #t17 == null ?{core::String?} null : #t17{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$2{core::String}; @@ -162,7 +162,7 @@ Try calling using ?.call instead. let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t26 = list in #t26 == null ?{core::bool?} null : #t26{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$1{core::int}.{core::int::isEven}{core::bool}; let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t27 = list in #t27 == null ?{core::int?} null : #t27{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.$2{core::String}.{core::String::length}{core::int}; let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t28 = list in #t28 == null ?{core::bool?} null : #t28{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.d{core::double}.{core::num::isNaN}{core::bool}; - let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t29 = list in #t29 == null ?{() →? void} null : #t29{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.f{() → void}.call; + let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t29 = list in #t29 == null ?{() →? void} null : #t29{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.f{() → void}; let final core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>? #t30 = list in #t30 == null ?{() →? void} null : #t30{core::List<(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})>}.{core::Iterable::first}{(core::int, core::String, {required c: self::Class, required d: core::double, required f: () → void})}.c{self::Class}.{self::Class::call}{() → void}; } static extension-member method _extension#0|call(lowered final core::int #this) → void {} diff --git a/pkg/vm/lib/transformations/lowering.dart b/pkg/vm/lib/transformations/lowering.dart index f86ff95b40c..6e656cc8c0f 100644 --- a/pkg/vm/lib/transformations/lowering.dart +++ b/pkg/vm/lib/transformations/lowering.dart @@ -126,4 +126,10 @@ class _Lowering extends Transformer { return forInLowering.transformForInStatement( node, _currentFunctionNode, _staticTypeContext); } + + @override + visitFunctionTearOff(FunctionTearOff node) { + node.transformChildren(this); + return node.receiver; + } } diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart index 0e4425c0320..56bb000268a 100644 --- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart +++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart @@ -1898,11 +1898,6 @@ class SummaryCollector extends RecursiveResultVisitor { node, node.receiver, node.interfaceTarget, node.name); } - @override - TypeExpr visitFunctionTearOff(FunctionTearOff node) { - return _handlePropertyGet(node, node.receiver, null, Name('call')); - } - @override TypeExpr visitDynamicGet(DynamicGet node) { return _handlePropertyGet(node, node.receiver, null, node.name); diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart index 53926a3ff42..d41498473fa 100644 --- a/pkg/vm/lib/transformations/type_flow/transformer.dart +++ b/pkg/vm/lib/transformations/type_flow/transformer.dart @@ -623,12 +623,6 @@ class AnnotateKernel extends RecursiveVisitor { super.visitInstanceTearOff(node); } - @override - visitFunctionTearOff(FunctionTearOff node) { - _annotateCallSite(node, null); - super.visitFunctionTearOff(node); - } - @override visitDynamicGet(DynamicGet node) { _annotateCallSite(node, null); @@ -1368,17 +1362,6 @@ class _TreeShakerPass1 extends RemovingTransformer { } } - @override - TreeNode visitFunctionTearOff( - FunctionTearOff node, TreeNode? removalSentinel) { - node.transformOrRemoveChildren(this); - if (_isUnreachable(node)) { - return _makeUnreachableCall([node.receiver]); - } else { - return node; - } - } - @override TreeNode visitInstanceSet(InstanceSet node, TreeNode? removalSentinel) { node.transformOrRemoveChildren(this); diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc index 758245835cf..1904c9ca38d 100644 --- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc +++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc @@ -1055,7 +1055,9 @@ Fragment StreamingFlowGraphBuilder::BuildExpression(TokenPosition* position) { case kInstanceTearOff: return BuildInstanceTearOff(position); case kFunctionTearOff: - return BuildFunctionTearOff(position); + // Removed by lowering kernel transformation. + UNREACHABLE(); + break; case kInstanceSet: return BuildInstanceSet(position); case kDynamicSet: @@ -2304,40 +2306,6 @@ Fragment StreamingFlowGraphBuilder::BuildInstanceTearOff(TokenPosition* p) { return instructions; } -Fragment StreamingFlowGraphBuilder::BuildFunctionTearOff(TokenPosition* p) { - const intptr_t offset = ReaderOffset() - 1; // Include the tag. - const TokenPosition position = ReadPosition(); // read position. - if (p != nullptr) *p = position; - - const DirectCallMetadata direct_call = - direct_call_metadata_helper_.GetDirectTargetForPropertyGet(offset); - const InferredTypeMetadata result_type = - inferred_type_metadata_helper_.GetInferredType(offset); - - Fragment instructions = BuildExpression(); // read receiver. - - if (direct_call.check_receiver_for_null_) { - const auto receiver = MakeTemporary(); - instructions += CheckNull(position, receiver, Symbols::GetCall()); - } - - if (!direct_call.target_.IsNull()) { - ASSERT(CompilerState::Current().is_aot()); - instructions += - StaticCall(position, direct_call.target_, 1, Array::null_array(), - ICData::kNoRebind, &result_type); - } else { - const intptr_t kTypeArgsLen = 0; - const intptr_t kNumArgsChecked = 1; - instructions += InstanceCall(position, Symbols::GetCall(), Token::kGET, - kTypeArgsLen, 1, Array::null_array(), - kNumArgsChecked, Function::null_function(), - Function::null_function(), &result_type); - } - - return instructions; -} - Fragment StreamingFlowGraphBuilder::BuildInstanceSet(TokenPosition* p) { const intptr_t offset = ReaderOffset() - 1; // Include the tag. ReadByte(); // read kind. diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h index 80d3fb07df1..ce5ceeb5170 100644 --- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h +++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h @@ -282,7 +282,6 @@ class StreamingFlowGraphBuilder : public KernelReaderHelper { Fragment BuildInstanceGet(TokenPosition* position); Fragment BuildDynamicGet(TokenPosition* position); Fragment BuildInstanceTearOff(TokenPosition* position); - Fragment BuildFunctionTearOff(TokenPosition* position); Fragment BuildInstanceSet(TokenPosition* position); Fragment BuildDynamicSet(TokenPosition* position); Fragment BuildAllocateInvocationMirrorCall(TokenPosition position, diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc index 61d09880d51..f059f33fb66 100644 --- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc +++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc @@ -421,9 +421,9 @@ void KernelFingerprintHelper::CalculateExpressionFingerprint() { CalculateGetterNameFingerprint(); // read interface_target_reference. return; case kFunctionTearOff: - ReadPosition(); // read position. - CalculateExpressionFingerprint(); // read receiver. - return; + // Removed by lowering kernel transformation. + UNREACHABLE(); + break; case kInstanceSet: ReadByte(); // read kind. ReadPosition(); // read position. diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc index 6c2dfc79dfd..903f911d134 100644 --- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc +++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc @@ -2517,9 +2517,9 @@ void KernelReaderHelper::SkipExpression() { SkipInterfaceMemberNameReference(); // read interface_target_reference. return; case kFunctionTearOff: - ReadPosition(); // read position. - SkipExpression(); // read receiver. - return; + // Removed by lowering kernel transformation. + UNREACHABLE(); + break; case kInstanceSet: ReadByte(); // read kind. ReadPosition(); // read position. diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc index 25945574698..845840c0084 100644 --- a/runtime/vm/compiler/frontend/scope_builder.cc +++ b/runtime/vm/compiler/frontend/scope_builder.cc @@ -682,9 +682,9 @@ void ScopeBuilder::VisitExpression() { helper_.SkipInterfaceMemberNameReference(); return; case kFunctionTearOff: - helper_.ReadPosition(); // read position. - VisitExpression(); // read receiver. - return; + // Removed by lowering kernel transformation. + UNREACHABLE(); + break; case kInstanceSet: helper_.ReadByte(); // read kind. helper_.ReadPosition(); // read position.