diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart index 8dccab22438..b43d97614f0 100644 --- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart +++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart @@ -875,9 +875,12 @@ abstract class TypeInferrerImpl extends TypeInferrer { } desugaredGet?.dispatchCategory = callKind; bool checkReturn = false; - if (callKind == DispatchCategory.interface && - interfaceMember is Procedure) { - checkReturn = interfaceMember.isGenericContravariant; + if (callKind == DispatchCategory.interface) { + if (interfaceMember is Procedure) { + checkReturn = interfaceMember.isGenericContravariant; + } else if (interfaceMember is Field) { + checkReturn = interfaceMember.isGenericContravariant; + } } var replacedExpression = desugaredGet ?? expression; if (checkReturn) { diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_field.dart b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart new file mode 100644 index 00000000000..73392ad9eff --- /dev/null +++ b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart @@ -0,0 +1,21 @@ +// 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. + +/*@testedFeatures=checks*/ +library test; + +typedef void F(T x); + +class C { + F /*@genericContravariant=true*/ y; + void f() { + var x = this. /*@callKind=this*/ y; + } +} + +void g(C c) { + var x = c. /*@checkReturn=(num) -> void*/ y; +} + +void main() {} diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.direct.expect b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.direct.expect new file mode 100644 index 00000000000..cd8a1ec9dbd --- /dev/null +++ b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.direct.expect @@ -0,0 +1,18 @@ +library test; +import self as self; +import "dart:core" as core; + +typedef F = (T) → void; +class C extends core::Object { + field (self::C::T) → void y = null; + synthetic constructor •() → void + : super core::Object::•() + ; + method f() → void { + dynamic x = this.{self::C::y}; + } +} +static method g(self::C c) → void { + dynamic x = c.y; +} +static method main() → void {} diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.outline.expect new file mode 100644 index 00000000000..27f223be077 --- /dev/null +++ b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.outline.expect @@ -0,0 +1,16 @@ +library test; +import self as self; +import "dart:core" as core; + +typedef F = (T) → void; +class C extends core::Object { + field (self::C::T) → void y; + synthetic constructor •() → void + ; + method f() → void + ; +} +static method g(self::C c) → void + ; +static method main() → void + ; diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.strong.expect new file mode 100644 index 00000000000..c2e5212e5bd --- /dev/null +++ b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.strong.expect @@ -0,0 +1,18 @@ +library test; +import self as self; +import "dart:core" as core; + +typedef F = (T) → void; +class C extends core::Object { + generic-contravariant field (self::C::T) → void y = null; + synthetic constructor •() → void + : super core::Object::•() + ; + method f() → void { + (self::C::T) → void x = this.{self::C::y}; + } +} +static method g(self::C c) → void { + (core::num) → void x = c.{self::C::y} as{TypeError} (core::num) → void; +} +static method main() → void {}