[VM/runtime] Reland: Avoid comparing unfinalized type parameters.
This is done by simplifying the code looking for a type argument vector overlap between class and super class.
This is a reland of reverted https://dart-review.googlesource.com/c/sdk/+/184202
First patchset is the reverted CL.
A check for nullability was missing.
TEST=added regression test for the reland.
Change-Id: I77de3eded631d5223e9335ee9743b95878fe5bd7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/185202
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: RĂ©gis Crelier <regis@google.com>
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 8aa06a4..ef11697 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -3172,7 +3172,6 @@
// modified by finalization, only shifted to higher indices in the vector.
// The super type may not even be resolved yet. This is not necessary, since
// we only check for matching type parameters, which are resolved by default.
- const auto& type_params = TypeArguments::Handle(zone, type_parameters());
// Determine the maximum overlap of a prefix of the vector consisting of the
// type parameters of this class with a suffix of the vector consisting of the
// type arguments of the super type of this class.
@@ -3181,7 +3180,6 @@
// Attempt to overlap the whole vector of type parameters; reduce the size
// of the vector (keeping the first type parameter) until it fits or until
// its size is zero.
- auto& type_param = TypeParameter::Handle(zone);
auto& sup_type_arg = AbstractType::Handle(zone);
for (intptr_t num_overlapping_type_args =
(num_type_params < sup_type_args_length) ? num_type_params
@@ -3189,12 +3187,19 @@
num_overlapping_type_args > 0; num_overlapping_type_args--) {
intptr_t i = 0;
for (; i < num_overlapping_type_args; i++) {
- type_param ^= type_params.TypeAt(i);
- ASSERT(!type_param.IsNull());
sup_type_arg = sup_type_args.TypeAt(sup_type_args_length -
num_overlapping_type_args + i);
ASSERT(!sup_type_arg.IsNull());
- if (!type_param.Equals(sup_type_arg)) break;
+ if (!sup_type_arg.IsTypeParameter()) break;
+ // The only type parameters appearing in the type arguments of the super
+ // type are those declared by this class. Their finalized indices depend
+ // on the number of type arguments being computed here. Therefore, they
+ // cannot possibly be finalized yet.
+ ASSERT(!TypeParameter::Cast(sup_type_arg).IsFinalized());
+ if (TypeParameter::Cast(sup_type_arg).index() != i ||
+ TypeParameter::Cast(sup_type_arg).IsNullable()) {
+ break;
+ }
}
if (i == num_overlapping_type_args) {
// Overlap found.
@@ -21033,12 +21038,12 @@
return false;
}
const TypeParameter& other_type_param = TypeParameter::Cast(other);
+ ASSERT(IsFinalized() && other_type_param.IsFinalized());
// Compare index, name, bound, default argument, and flags.
if (IsFunctionTypeParameter()) {
if (!other_type_param.IsFunctionTypeParameter()) {
return false;
}
- ASSERT(IsFinalized() && other_type_param.IsFinalized());
if (kind == TypeEquality::kInSubtypeTest) {
// To be equivalent, the function type parameters should be declared
// at the same position in the generic function. Their index therefore
@@ -21105,7 +21110,6 @@
return false;
}
} else {
- ASSERT(IsFinalized() && other_type_param.IsFinalized());
if (index() != other_type_param.index()) {
return false;
}
diff --git a/tests/language/regress/regress179942377_test.dart b/tests/language/regress/regress179942377_test.dart
new file mode 100644
index 0000000..f9decac
--- /dev/null
+++ b/tests/language/regress/regress179942377_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2021, 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 for issue 179942377.
+
+import 'package:expect/expect.dart';
+
+class A<T> {
+ bool test() {
+ return null is T;
+ }
+}
+
+class B<T> extends A<T?> {}
+
+void main() {
+ Expect.isTrue(B<int>().test());
+}