Version 2.13.0-42.0.dev

Merge commit '4d5f027ccb2d998771677067a621bdd582ddfaf6' into 'dev'
diff --git a/pkg/analysis_server/test/src/domains/completion/get_suggestion_details_test.dart b/pkg/analysis_server/test/src/domains/completion/get_suggestion_details_test.dart
index 7ed929c..7876489 100644
--- a/pkg/analysis_server/test/src/domains/completion/get_suggestion_details_test.dart
+++ b/pkg/analysis_server/test/src/domains/completion/get_suggestion_details_test.dart
@@ -115,6 +115,104 @@
 ''');
   }
 
+  Future<void> test_newImport_afterLibraryBeforeFirstImportsAnnotation() async {
+    // Annotations are only treated as being for the file if they are on the first
+    // directive of the file.
+    addTestFile(r'''
+library foo;
+
+@myAnnotation
+import 'package:zzz';
+
+main() {} // ref
+''');
+
+    var mathSet = await waitForSetWithUri('dart:math');
+    var result = await _getSuggestionDetails(
+      _buildRequest(
+        id: mathSet.id,
+        label: 'sin',
+        offset: testCode.indexOf('} // ref'),
+      ),
+    );
+
+    expect(result.completion, 'sin');
+    _assertTestFileChange(result.change, r'''
+library foo;
+
+import 'dart:math';
+
+@myAnnotation
+import 'package:zzz';
+
+main() {} // ref
+''');
+  }
+
+  Future<void> test_newImport_betweenAnnotationAndFirstImport() async {
+    // Annotations attached to the first import in a file are considered
+    // to be for the file, so if an import is inserted in the top position, it
+    // should go after the annotation.
+    addTestFile(r'''
+@myAnnotation
+
+import 'package:zzz';
+
+main() {} // ref
+''');
+
+    var mathSet = await waitForSetWithUri('dart:math');
+    var result = await _getSuggestionDetails(
+      _buildRequest(
+        id: mathSet.id,
+        label: 'sin',
+        offset: testCode.indexOf('} // ref'),
+      ),
+    );
+
+    expect(result.completion, 'sin');
+    _assertTestFileChange(result.change, r'''
+@myAnnotation
+
+import 'dart:math';
+
+import 'package:zzz';
+
+main() {} // ref
+''');
+  }
+
+  Future<void> test_newImport_notBetweenAnnotationAndNonFirstImport() async {
+    // Annotations on non-first directives should not be kept above the newly
+    // imported imports (opposite of test_newImport_betweenAnnotationAndFirstImport).
+    addTestFile(r'''
+import 'dart:async';
+@myAnnotation
+import 'package:zzz';
+
+main() {} // ref
+''');
+
+    var mathSet = await waitForSetWithUri('dart:math');
+    var result = await _getSuggestionDetails(
+      _buildRequest(
+        id: mathSet.id,
+        label: 'sin',
+        offset: testCode.indexOf('} // ref'),
+      ),
+    );
+
+    expect(result.completion, 'sin');
+    _assertTestFileChange(result.change, r'''
+import 'dart:async';
+import 'dart:math';
+@myAnnotation
+import 'package:zzz';
+
+main() {} // ref
+''');
+  }
+
   Future<void> test_newImport_part() async {
     var partCode = r'''
 part of 'test.dart';
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index 83c5b04..6f0ab75 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -1515,7 +1515,14 @@
               writeImport(builder, import);
             });
           } else {
-            var offset = next.offset;
+            // Annotations attached to the first directive should remain above
+            // the newly inserted import, as they are treated as being for the
+            // file.
+            var isFirst =
+                next == (next.parent as CompilationUnit).directives.first;
+            var offset = isFirst && next is AnnotatedNode
+                ? next.firstTokenAfterCommentAndMetadata.offset
+                : next.offset;
             addInsertion(offset, (EditBuilder builder) {
               writeImport(builder, import);
               builder.writeln();
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());
+}
diff --git a/tools/VERSION b/tools/VERSION
index 0933579..7b6bfe1 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 41
+PRERELEASE 42
 PRERELEASE_PATCH 0
\ No newline at end of file