[fasta] Allow super-bounded types as bounds of type variables
Change-Id: If1f10d8e5b6d6288696926dc3cab6ad8a3b8d446
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/79701
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
Reviewed-by: Aske Simon Christensen <askesc@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
index 151c074..6ad083c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
@@ -338,7 +338,7 @@
for (TypeParameter parameter in cls.typeParameters) {
List<TypeArgumentIssue> issues = findTypeArgumentIssues(
parameter.bound, typeEnvironment,
- allowSuperBounded: false);
+ allowSuperBounded: true);
if (issues != null) {
for (TypeArgumentIssue issue in issues) {
DartType argument = issue.argument;
@@ -923,9 +923,9 @@
library.addProblem(
templateOverrideTypeVariablesMismatch.withArguments(
"${declaredMember.enclosingClass.name}."
- "${declaredMember.name.name}",
+ "${declaredMember.name.name}",
"${interfaceMember.enclosingClass.name}."
- "${interfaceMember.name.name}"),
+ "${interfaceMember.name.name}"),
declaredMember.fileOffset,
noLength,
declaredMember.fileUri,
@@ -960,9 +960,9 @@
library.addProblem(
templateOverrideTypeVariablesMismatch.withArguments(
"${declaredMember.enclosingClass.name}."
- "${declaredMember.name.name}",
+ "${declaredMember.name.name}",
"${interfaceMember.enclosingClass.name}."
- "${interfaceMember.name.name}"),
+ "${interfaceMember.name.name}"),
declaredMember.fileOffset,
noLength,
declaredMember.fileUri,
@@ -1103,9 +1103,9 @@
library.addProblem(
templateOverrideFewerPositionalArguments.withArguments(
"${declaredMember.enclosingClass.name}."
- "${declaredMember.name.name}",
+ "${declaredMember.name.name}",
"${interfaceMember.enclosingClass.name}."
- "${interfaceMember.name.name}"),
+ "${interfaceMember.name.name}"),
declaredMember.fileOffset,
noLength,
declaredMember.fileUri,
@@ -1122,9 +1122,9 @@
library.addProblem(
templateOverrideMoreRequiredArguments.withArguments(
"${declaredMember.enclosingClass.name}."
- "${declaredMember.name.name}",
+ "${declaredMember.name.name}",
"${interfaceMember.enclosingClass.name}."
- "${interfaceMember.name.name}"),
+ "${interfaceMember.name.name}"),
declaredMember.fileOffset,
noLength,
declaredMember.fileUri,
@@ -1164,9 +1164,9 @@
library.addProblem(
templateOverrideFewerNamedArguments.withArguments(
"${declaredMember.enclosingClass.name}."
- "${declaredMember.name.name}",
+ "${declaredMember.name.name}",
"${interfaceMember.enclosingClass.name}."
- "${interfaceMember.name.name}"),
+ "${interfaceMember.name.name}"),
declaredMember.fileOffset,
noLength,
declaredMember.fileUri,
@@ -1201,10 +1201,10 @@
library.addProblem(
templateOverrideMismatchNamedParameter.withArguments(
"${declaredMember.enclosingClass.name}."
- "${declaredMember.name.name}",
+ "${declaredMember.name.name}",
interfaceNamedParameters.current.name,
"${interfaceMember.enclosingClass.name}."
- "${interfaceMember.name.name}"),
+ "${interfaceMember.name.name}"),
declaredMember.fileOffset,
noLength,
declaredMember.fileUri,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
index 706be15..80db2c8 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
@@ -1570,7 +1570,7 @@
for (TypeParameter parameter in typeParameters) {
checkBoundsInType(
parameter.bound, typeEnvironment, parameter.fileOffset,
- allowSuperBounded: false);
+ allowSuperBounded: true);
}
}
if (positionalParameters != null) {
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.expect
index dbf94d5..ce101a2 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.expect
@@ -7,12 +7,6 @@
// class Hest<X extends LinkedListEntry> {}
// ^
//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart:15:12: Error: Type argument 'LinkedListEntry<dynamic>' doesn't conform to the bound 'LinkedListEntry<E>' of the type variable 'E' on 'LinkedListEntry'.
-// - 'LinkedListEntry' is from 'dart:collection'.
-// Try changing type arguments so that they conform to the bounds.
-// class Hest<X extends LinkedListEntry> {}
-// ^
-//
import self as self;
import "dart:collection" as col;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.transformed.expect
index dbf94d5..ce101a2 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.transformed.expect
@@ -7,12 +7,6 @@
// class Hest<X extends LinkedListEntry> {}
// ^
//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart:15:12: Error: Type argument 'LinkedListEntry<dynamic>' doesn't conform to the bound 'LinkedListEntry<E>' of the type variable 'E' on 'LinkedListEntry'.
-// - 'LinkedListEntry' is from 'dart:collection'.
-// Try changing type arguments so that they conform to the bounds.
-// class Hest<X extends LinkedListEntry> {}
-// ^
-//
import self as self;
import "dart:collection" as col;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart
new file mode 100644
index 0000000..8ecef66
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2019, 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.
+
+class A<X extends Comparable<X>> {}
+
+class B<Y extends A<dynamic>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.hierarchy.expect
new file mode 100644
index 0000000..523e0f4
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.legacy.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.legacy.expect
new file mode 100644
index 0000000..6b8efb5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.legacy.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Comparable<self::A::X> = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B<Y extends self::A<dynamic> = dynamic> extends core::Object {
+ synthetic constructor •() → self::B<self::B::Y>
+ : super core::Object::•()
+ ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.legacy.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.legacy.transformed.expect
new file mode 100644
index 0000000..6b8efb5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.legacy.transformed.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Comparable<self::A::X> = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B<Y extends self::A<dynamic> = dynamic> extends core::Object {
+ synthetic constructor •() → self::B<self::B::Y>
+ : super core::Object::•()
+ ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.outline.expect
new file mode 100644
index 0000000..9a334ff
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.outline.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Comparable<self::A::X> = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ ;
+}
+class B<Y extends self::A<dynamic> = dynamic> extends core::Object {
+ synthetic constructor •() → self::B<self::B::Y>
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.strong.expect
new file mode 100644
index 0000000..88cbec9
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.strong.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Comparable<self::A::X> = core::Comparable<dynamic>> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B<Y extends self::A<dynamic> = self::A<dynamic>> extends core::Object {
+ synthetic constructor •() → self::B<self::B::Y>
+ : super core::Object::•()
+ ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.strong.transformed.expect
new file mode 100644
index 0000000..88cbec9
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Comparable<self::A::X> = core::Comparable<dynamic>> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B<Y extends self::A<dynamic> = self::A<dynamic>> extends core::Object {
+ synthetic constructor •() → self::B<self::B::Y>
+ : super core::Object::•()
+ ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 25584dc..0347606 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -660,6 +660,7 @@
instantiate_to_bound/non_simple_variables_from_same: TextSerializationFailure # Was: Pass
instantiate_to_bound/omitted_bound: TextSerializationFailure # Was: Pass
instantiate_to_bound/raw_in_bound: TextSerializationFailure # Was: Pass
+instantiate_to_bound/super_bounded_in_bound: TextSerializationFailure
instantiate_to_bound/super_bounded_type: TextSerializationFailure # Was: Pass
instantiate_to_bound/supertypes: TextSerializationFailure # Was: Pass
instantiate_to_bound/typedef_instantiated_in_outline: TextSerializationFailure # Was: Pass
@@ -922,8 +923,8 @@
regress/issue_36400: TextSerializationFailure
regress/issue_36647: TextSerializationFailure
regress/issue_36647_2: TextSerializationFailure
-regress/issue_36793: TextSerializationFailure
regress/issue_36669: TextSerializationFailure
+regress/issue_36793: TextSerializationFailure
reject_generic_function_types_in_bounds: TextSerializationFailure # Was: RuntimeError # Expected
return_with_unknown_type_in_context: TextSerializationFailure # Was: Pass
runtime_checks/call_kinds: TextSerializationFailure # Was: Pass