Skip to content

Commit cd709c2

Browse files
Dmitry Stefantsovcommit-bot@chromium.org
authored andcommitted
[fasta] Fix an issue with override inference and type parameters
The CL fixes how override-based inference works in the cases when the type of a parameter in the overriding method is omitted, and the type of this parameter in the overridden method contains a type parameter of the class. Basically, the type should be substituted in this case. Change-Id: I36d6c614d47e5cd68dc14eae1a2bbe4cd19d842b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/104784 Reviewed-by: Aske Simon Christensen <askesc@google.com>
1 parent 10a04a4 commit cd709c2

9 files changed

+174
-0
lines changed

pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,13 @@ class ClassHierarchyNodeBuilder {
737737
VariableDeclaration bParameter = bNamed[bCount];
738738
copyParameterCovariance(a.parent, aParameter, bParameter);
739739
DartType aType = aParameter.type;
740+
if (aSubstitution != null) {
741+
aType = aSubstitution.substituteType(aType);
742+
}
740743
DartType bType = bParameter.type;
744+
if (bSubstitution != null) {
745+
bType = bSubstitution.substituteType(bType);
746+
}
741747
if (substitution != null) {
742748
bType = substitution.substituteType(bType);
743749
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
abstract class A<X> {
6+
void foo({Iterable<X> x});
7+
}
8+
9+
class B<Y> implements A<Y> {
10+
void foo({x}) {}
11+
}
12+
13+
main() {}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
Object:
2+
superclasses:
3+
interfaces:
4+
classMembers:
5+
Object._haveSameRuntimeType
6+
Object.toString
7+
Object.runtimeType
8+
Object._toString
9+
Object._simpleInstanceOf
10+
Object._hashCodeRnd
11+
Object._instanceOf
12+
Object.noSuchMethod
13+
Object._objectHashCode
14+
Object._identityHashCode
15+
Object.hashCode
16+
Object._simpleInstanceOfFalse
17+
Object._simpleInstanceOfTrue
18+
Object.==
19+
classSetters:
20+
21+
A:
22+
superclasses:
23+
Object
24+
interfaces:
25+
classMembers:
26+
Object.toString
27+
Object.runtimeType
28+
Object._simpleInstanceOf
29+
Object._instanceOf
30+
A.foo
31+
Object.noSuchMethod
32+
Object._identityHashCode
33+
Object.hashCode
34+
Object._simpleInstanceOfFalse
35+
Object._simpleInstanceOfTrue
36+
Object.==
37+
classSetters:
38+
39+
B:
40+
Longest path to Object: 2
41+
superclasses:
42+
Object
43+
interfaces: A<Y>
44+
classMembers:
45+
Object.toString
46+
Object.runtimeType
47+
Object._simpleInstanceOf
48+
Object._instanceOf
49+
B.foo
50+
Object.noSuchMethod
51+
Object._identityHashCode
52+
Object.hashCode
53+
Object._simpleInstanceOfFalse
54+
Object._simpleInstanceOfTrue
55+
Object.==
56+
classSetters:
57+
interfaceMembers:
58+
Object.toString
59+
Object.runtimeType
60+
Object._simpleInstanceOf
61+
Object._instanceOf
62+
B.foo
63+
Object.noSuchMethod
64+
Object._identityHashCode
65+
Object.hashCode
66+
Object._simpleInstanceOfFalse
67+
Object._simpleInstanceOfTrue
68+
Object.==
69+
interfaceSetters:
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
abstract class A<X extends core::Object = dynamic> extends core::Object {
6+
synthetic constructor •() → self::A<self::A::X>
7+
: super core::Object::•()
8+
;
9+
abstract method foo({generic-covariant-impl core::Iterable<self::A::X> x = null}) → void;
10+
}
11+
class B<Y extends core::Object = dynamic> extends core::Object implements self::A<self::B::Y> {
12+
synthetic constructor •() → self::B<self::B::Y>
13+
: super core::Object::•()
14+
;
15+
method foo({generic-covariant-impl core::Iterable<self::B::Y> x = null}) → void {}
16+
}
17+
static method main() → dynamic {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
abstract class A<X extends core::Object = dynamic> extends core::Object {
6+
synthetic constructor •() → self::A<self::A::X>
7+
: super core::Object::•()
8+
;
9+
abstract method foo({generic-covariant-impl core::Iterable<self::A::X> x = null}) → void;
10+
}
11+
class B<Y extends core::Object = dynamic> extends core::Object implements self::A<self::B::Y> {
12+
synthetic constructor •() → self::B<self::B::Y>
13+
: super core::Object::•()
14+
;
15+
method foo({generic-covariant-impl core::Iterable<self::B::Y> x = null}) → void {}
16+
}
17+
static method main() → dynamic {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
abstract class A<X extends core::Object = dynamic> extends core::Object {
6+
synthetic constructor •() → self::A<self::A::X>
7+
;
8+
abstract method foo({generic-covariant-impl core::Iterable<self::A::X> x}) → void;
9+
}
10+
class B<Y extends core::Object = dynamic> extends core::Object implements self::A<self::B::Y> {
11+
synthetic constructor •() → self::B<self::B::Y>
12+
;
13+
method foo({generic-covariant-impl core::Iterable<self::B::Y> x}) → void
14+
;
15+
}
16+
static method main() → dynamic
17+
;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
abstract class A<X extends core::Object = dynamic> extends core::Object {
6+
synthetic constructor •() → self::A<self::A::X>
7+
: super core::Object::•()
8+
;
9+
abstract method foo({generic-covariant-impl core::Iterable<self::A::X> x = null}) → void;
10+
}
11+
class B<Y extends core::Object = dynamic> extends core::Object implements self::A<self::B::Y> {
12+
synthetic constructor •() → self::B<self::B::Y>
13+
: super core::Object::•()
14+
;
15+
method foo({generic-covariant-impl core::Iterable<self::B::Y> x = null}) → void {}
16+
}
17+
static method main() → dynamic {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
abstract class A<X extends core::Object = dynamic> extends core::Object {
6+
synthetic constructor •() → self::A<self::A::X>
7+
: super core::Object::•()
8+
;
9+
abstract method foo({generic-covariant-impl core::Iterable<self::A::X> x = null}) → void;
10+
}
11+
class B<Y extends core::Object = dynamic> extends core::Object implements self::A<self::B::Y> {
12+
synthetic constructor •() → self::B<self::B::Y>
13+
: super core::Object::•()
14+
;
15+
method foo({generic-covariant-impl core::Iterable<self::B::Y> x = null}) → void {}
16+
}
17+
static method main() → dynamic {}

pkg/front_end/testcases/text_serialization.status

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ inference/null_literal_should_not_infer_as_bottom: TextSerializationFailure # Wa
475475
inference/overloaded_int_operators: TextSerializationFailure # Was: Pass
476476
inference/override_equals: TextSerializationFailure # Was: RuntimeError
477477
inference/override_inference_depends_on_field_inference: TextSerializationFailure
478+
inference/override_inference_with_type_parameters: TextSerializationFailure
478479
inference/parameter_defaults_downwards: TextSerializationFailure # Was: Pass
479480
inference/parameter_defaults_upwards: TextSerializationFailure # Was: Pass
480481
inference/promote_bounds: TextSerializationFailure # Was: Pass

0 commit comments

Comments
 (0)