From 3203a0784acbedc07ddf07647ab1d77166b01c01 Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Wed, 27 Apr 2022 20:30:35 +0000 Subject: [PATCH] Additional tests for deferred function literals. These tests exercise the "deferred type inference of function literals" part of https://github.com/dart-lang/language/issues/731 (improved inference for fold etc.) for super-constructor invocations and redirecting constructor invocations, both of which have their own code paths in the analyzer. Change-Id: I6877ac3c07a3cca31550ba74d941d250c8410cfd Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/241987 Commit-Queue: Paul Berry Reviewed-by: Samuel Rawlins Reviewed-by: Chloe Stefantsova --- .../inference_update_1_test.dart | 30 +++++++++++++++++++ .../write_capture_deferral_disabled_test.dart | 15 ++++++++++ .../write_capture_deferral_enabled_test.dart | 15 ++++++++++ 3 files changed, 60 insertions(+) diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/inference_update_1_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/inference_update_1_test.dart index fe971f49510c..c4ea903a696a 100644 --- a/pkg/analyzer/test/src/dart/resolution/type_inference/inference_update_1_test.dart +++ b/pkg/analyzer/test/src/dart/resolution/type_inference/inference_update_1_test.dart @@ -356,4 +356,34 @@ void f({required void Function() g, Object? x}) {} // regardless of whether the experiment is enabled. assertType(findNode.simple('i; // (2)'), 'int?'); } + + test_write_capture_deferred_redirecting_constructor() async { + await assertNoErrorsInCode(''' +class C { + C(int? i) : this.other(i!, () { i = null; }, i); + C.other(Object? x, void Function() g, Object? y); +} +'''); + // With the feature enabled, analysis of the closure is deferred until after + // all the other arguments to `this.other`, so the `i` passed to `y` is not + // yet write captured and retains its promoted value. With the experiment + // disabled, it is write captured immediately. + assertType(findNode.simple('i);'), _isEnabled ? 'int' : 'int?'); + } + + test_write_capture_deferred_super_constructor() async { + await assertNoErrorsInCode(''' +class B { + B(Object? x, void Function() g, Object? y); +} +class C extends B { + C(int? i) : super(i!, () { i = null; }, i); +} +'''); + // With the feature enabled, analysis of the closure is deferred until after + // all the other arguments to `this.other`, so the `i` passed to `y` is not + // yet write captured and retains its promoted value. With the experiment + // disabled, it is write captured immediately. + assertType(findNode.simple('i);'), _isEnabled ? 'int' : 'int?'); + } } diff --git a/tests/language/inference_update_1/write_capture_deferral_disabled_test.dart b/tests/language/inference_update_1/write_capture_deferral_disabled_test.dart index 1083524567a7..80c63a864713 100644 --- a/tests/language/inference_update_1/write_capture_deferral_disabled_test.dart +++ b/tests/language/inference_update_1/write_capture_deferral_disabled_test.dart @@ -52,4 +52,19 @@ withIdentical_rhs(int? i) { } } +class B { + B(Object? x, void Function() g, Object? y); + B.redirectingConstructorInvocation(int? i) + : this(i!, () { + i = null; + }, i..expectStaticType>()); +} + +class C extends B { + C.superConstructorInvocation(int? i) + : super(i!, () { + i = null; + }, i..expectStaticType>()); +} + main() {} diff --git a/tests/language/inference_update_1/write_capture_deferral_enabled_test.dart b/tests/language/inference_update_1/write_capture_deferral_enabled_test.dart index 3a93caafeb11..1a9a79f6c626 100644 --- a/tests/language/inference_update_1/write_capture_deferral_enabled_test.dart +++ b/tests/language/inference_update_1/write_capture_deferral_enabled_test.dart @@ -52,4 +52,19 @@ withIdentical_rhs(int? i) { } } +class B { + B(Object? x, void Function() g, Object? y); + B.redirectingConstructorInvocation(int? i) + : this(i!, () { + i = null; + }, i..expectStaticType>()); +} + +class C extends B { + C.superConstructorInvocation(int? i) + : super(i!, () { + i = null; + }, i..expectStaticType>()); +} + main() {}