From b0cbc4e9cd883119abdf66621f3b854a23dba3a1 Mon Sep 17 00:00:00 2001 From: Kevin Millikin Date: Thu, 28 Jun 2018 11:47:24 +0000 Subject: [PATCH] Fix a bug in top-level type inference dependency tracking When there was a top-level type inference dependency from a declared field to an overridden getter or setter, the dependency was not recorded in the field. This caused initializing formals to sometimes fail to infer the field type, because they did not see that it needed to be inferred. Fixes https://github.com/dart-lang/sdk/issues/32866 Change-Id: If75658d087c099787f74af5f5c6db2ee6837febe Reviewed-on: https://dart-review.googlesource.com/62800 Commit-Queue: Kevin Millikin Reviewed-by: Dmitry Stefantsov --- .../type_inference/interface_resolver.dart | 3 +++ pkg/front_end/testcases/bug32866.dart | 18 ++++++++++++++++++ .../testcases/bug32866.dart.direct.expect | 19 +++++++++++++++++++ .../bug32866.dart.direct.transformed.expect | 19 +++++++++++++++++++ .../testcases/bug32866.dart.outline.expect | 17 +++++++++++++++++ .../testcases/bug32866.dart.strong.expect | 19 +++++++++++++++++++ .../bug32866.dart.strong.transformed.expect | 19 +++++++++++++++++++ 7 files changed, 114 insertions(+) create mode 100644 pkg/front_end/testcases/bug32866.dart create mode 100644 pkg/front_end/testcases/bug32866.dart.direct.expect create mode 100644 pkg/front_end/testcases/bug32866.dart.direct.transformed.expect create mode 100644 pkg/front_end/testcases/bug32866.dart.outline.expect create mode 100644 pkg/front_end/testcases/bug32866.dart.strong.expect create mode 100644 pkg/front_end/testcases/bug32866.dart.strong.transformed.expect diff --git a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart index 9805fbf187a3..bf2284c28f0b 100644 --- a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart +++ b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart @@ -1112,6 +1112,9 @@ class InterfaceResolver { procedure._field.initializer != null) { node = new FieldInitializerInferenceNode( _typeInferenceEngine, procedure._field, library); + } + + if (node != null && procedure is SyntheticAccessor) { ShadowField.setInferenceNode(procedure._field, node); } } diff --git a/pkg/front_end/testcases/bug32866.dart b/pkg/front_end/testcases/bug32866.dart new file mode 100644 index 000000000000..4c97c86f283c --- /dev/null +++ b/pkg/front_end/testcases/bug32866.dart @@ -0,0 +1,18 @@ +// Copyright (c) 2018, 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. + +// Regression test that top-level inference correctly handles dependencies from +// top-level field -> initializing formal -> field that overrides a getter. + +abstract class B { + String get f; +} + +class A implements B { + final f; + A(this.f); +} + +var a = new A("foo"); +main() => print(a); diff --git a/pkg/front_end/testcases/bug32866.dart.direct.expect b/pkg/front_end/testcases/bug32866.dart.direct.expect new file mode 100644 index 000000000000..0e88c2aed7de --- /dev/null +++ b/pkg/front_end/testcases/bug32866.dart.direct.expect @@ -0,0 +1,19 @@ +library; +import self as self; +import "dart:core" as core; + +abstract class B extends core::Object { + synthetic constructor •() → void + : super core::Object::•() + ; + abstract get f() → core::String; +} +class A extends core::Object implements self::B { + final field dynamic f; + constructor •(dynamic f) → void + : self::A::f = f, super core::Object::•() + ; +} +static field dynamic a = new self::A::•("foo"); +static method main() → dynamic + return core::print(self::a); diff --git a/pkg/front_end/testcases/bug32866.dart.direct.transformed.expect b/pkg/front_end/testcases/bug32866.dart.direct.transformed.expect new file mode 100644 index 000000000000..0e88c2aed7de --- /dev/null +++ b/pkg/front_end/testcases/bug32866.dart.direct.transformed.expect @@ -0,0 +1,19 @@ +library; +import self as self; +import "dart:core" as core; + +abstract class B extends core::Object { + synthetic constructor •() → void + : super core::Object::•() + ; + abstract get f() → core::String; +} +class A extends core::Object implements self::B { + final field dynamic f; + constructor •(dynamic f) → void + : self::A::f = f, super core::Object::•() + ; +} +static field dynamic a = new self::A::•("foo"); +static method main() → dynamic + return core::print(self::a); diff --git a/pkg/front_end/testcases/bug32866.dart.outline.expect b/pkg/front_end/testcases/bug32866.dart.outline.expect new file mode 100644 index 000000000000..f524935824a1 --- /dev/null +++ b/pkg/front_end/testcases/bug32866.dart.outline.expect @@ -0,0 +1,17 @@ +library; +import self as self; +import "dart:core" as core; + +abstract class B extends core::Object { + synthetic constructor •() → void + ; + abstract get f() → core::String; +} +class A extends core::Object implements self::B { + final field dynamic f; + constructor •(dynamic f) → void + ; +} +static field dynamic a; +static method main() → dynamic + ; diff --git a/pkg/front_end/testcases/bug32866.dart.strong.expect b/pkg/front_end/testcases/bug32866.dart.strong.expect new file mode 100644 index 000000000000..a8afb38ac311 --- /dev/null +++ b/pkg/front_end/testcases/bug32866.dart.strong.expect @@ -0,0 +1,19 @@ +library; +import self as self; +import "dart:core" as core; + +abstract class B extends core::Object { + synthetic constructor •() → void + : super core::Object::•() + ; + abstract get f() → core::String; +} +class A extends core::Object implements self::B { + final field core::String f; + constructor •(core::String f) → void + : self::A::f = f, super core::Object::•() + ; +} +static field self::A a = new self::A::•("foo"); +static method main() → dynamic + return core::print(self::a); diff --git a/pkg/front_end/testcases/bug32866.dart.strong.transformed.expect b/pkg/front_end/testcases/bug32866.dart.strong.transformed.expect new file mode 100644 index 000000000000..a8afb38ac311 --- /dev/null +++ b/pkg/front_end/testcases/bug32866.dart.strong.transformed.expect @@ -0,0 +1,19 @@ +library; +import self as self; +import "dart:core" as core; + +abstract class B extends core::Object { + synthetic constructor •() → void + : super core::Object::•() + ; + abstract get f() → core::String; +} +class A extends core::Object implements self::B { + final field core::String f; + constructor •(core::String f) → void + : self::A::f = f, super core::Object::•() + ; +} +static field self::A a = new self::A::•("foo"); +static method main() → dynamic + return core::print(self::a);