mirror of
https://github.com/dart-lang/sdk
synced 2024-10-03 06:11:06 +00:00
Check contravariance of property gets that resolve to fields.
Fixes #32501 Change-Id: Ic3c5aca1d12b73e40e63c6cdd8304b95f54e5497 Reviewed-on: https://dart-review.googlesource.com/46002 Reviewed-by: Dmitry Stefantsov <dmitryas@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
This commit is contained in:
parent
60a2cfa219
commit
424ae0f5e4
|
@ -875,9 +875,12 @@ abstract class TypeInferrerImpl extends TypeInferrer {
|
|||
}
|
||||
desugaredGet?.dispatchCategory = callKind;
|
||||
bool checkReturn = false;
|
||||
if (callKind == DispatchCategory.interface &&
|
||||
interfaceMember is Procedure) {
|
||||
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) {
|
||||
|
|
|
@ -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>(T x);
|
||||
|
||||
class C<T> {
|
||||
F<T> /*@genericContravariant=true*/ y;
|
||||
void f() {
|
||||
var x = this. /*@callKind=this*/ y;
|
||||
}
|
||||
}
|
||||
|
||||
void g(C<num> c) {
|
||||
var x = c. /*@checkReturn=(num) -> void*/ y;
|
||||
}
|
||||
|
||||
void main() {}
|
|
@ -0,0 +1,18 @@
|
|||
library test;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
typedef F<T extends core::Object> = (T) → void;
|
||||
class C<T extends core::Object> 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<core::num> c) → void {
|
||||
dynamic x = c.y;
|
||||
}
|
||||
static method main() → void {}
|
|
@ -0,0 +1,16 @@
|
|||
library test;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
typedef F<T extends core::Object> = (T) → void;
|
||||
class C<T extends core::Object> extends core::Object {
|
||||
field (self::C::T) → void y;
|
||||
synthetic constructor •() → void
|
||||
;
|
||||
method f() → void
|
||||
;
|
||||
}
|
||||
static method g(self::C<core::num> c) → void
|
||||
;
|
||||
static method main() → void
|
||||
;
|
|
@ -0,0 +1,18 @@
|
|||
library test;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
typedef F<T extends core::Object> = (T) → void;
|
||||
class C<T extends core::Object> 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<core::num> c) → void {
|
||||
(core::num) → void x = c.{self::C::y} as{TypeError} (core::num) → void;
|
||||
}
|
||||
static method main() → void {}
|
Loading…
Reference in a new issue