Version 2.11.0-184.0.dev

Merge commit '3efed861472346c54e571d9bce61c0c791605ded' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index f088ab2..c38172a 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -755,6 +755,56 @@
     return false;
   }
 
+  /// A dynamic bounded type is either `dynamic` itself, or a type variable
+  /// whose bound is dynamic bounded, or an intersection (promoted type
+  /// parameter type) whose second operand is dynamic bounded.
+  bool isDynamicBounded(DartType type) {
+    if (identical(type, DynamicTypeImpl.instance)) {
+      return true;
+    }
+
+    if (type is TypeParameterTypeImpl) {
+      var bound = type.element.bound;
+      if (bound != null && isDynamicBounded(bound)) {
+        return true;
+      }
+
+      var promotedBound = type.promotedBound;
+      if (promotedBound != null && isDynamicBounded(promotedBound)) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /// A function bounded type is either `Function` itself, or a type variable
+  /// whose bound is function bounded, or an intersection (promoted type
+  /// parameter type) whose second operand is function bounded.
+  bool isFunctionBounded(DartType type) {
+    if (type is FunctionType) {
+      return type.nullabilitySuffix != NullabilitySuffix.question;
+    }
+
+    if (type is InterfaceType && type.isDartCoreFunction) {
+      return type.nullabilitySuffix != NullabilitySuffix.question;
+    }
+
+    if (type is TypeParameterTypeImpl) {
+      var bound = type.element.bound;
+      if (bound != null && isFunctionBounded(bound)) {
+        return true;
+      }
+
+      var promotedBound = type.promotedBound;
+      if (promotedBound != null && isFunctionBounded(promotedBound)) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
   /// Defines an (almost) total order on bottom and `Null` types. This does not
   /// currently consistently order two different type variables with the same
   /// bound.
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index 919f54d..2344a75 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -136,27 +136,14 @@
     }
 
     DartType receiverType = receiver.staticType;
-    receiverType = _resolveTypeParameter(receiverType);
 
-    if (_migratableAstInfoProvider.isMethodInvocationNullAware(node) &&
-        _typeSystem.isNonNullableByDefault) {
-      receiverType = _typeSystem.promoteToNonNull(receiverType);
-    }
-
-    if (receiverType is InterfaceType) {
-      _resolveReceiverInterfaceType(
-          node, receiver, receiverType, nameNode, name);
+    if (_typeSystem.isDynamicBounded(receiverType)) {
+      _resolveReceiverDynamicBounded(node);
       return;
     }
 
-    if (receiverType is DynamicTypeImpl) {
-      _resolveReceiverDynamic(node);
-      return;
-    }
-
-    if (receiverType is FunctionType) {
-      _resolveReceiverFunctionType(
-          node, receiver, receiverType, nameNode, name);
+    if (receiverType is NeverTypeImpl) {
+      _resolveReceiverNever(node, receiver, receiverType);
       return;
     }
 
@@ -165,10 +152,25 @@
       return;
     }
 
-    if (receiverType is NeverTypeImpl) {
-      _resolveReceiverNever(node, receiver, receiverType);
+    if (_migratableAstInfoProvider.isMethodInvocationNullAware(node) &&
+        _typeSystem.isNonNullableByDefault) {
+      receiverType = _typeSystem.promoteToNonNull(receiverType);
+    }
+
+    if (_typeSystem.isFunctionBounded(receiverType)) {
+      _resolveReceiverFunctionBounded(
+          node, receiver, receiverType, nameNode, name);
       return;
     }
+
+    _resolveReceiverType(
+      node: node,
+      receiver: receiver,
+      receiverType: receiverType,
+      nameNode: nameNode,
+      name: name,
+      receiverErrorNode: receiver,
+    );
   }
 
   bool _isCoreFunction(DartType type) {
@@ -382,7 +384,7 @@
     _setResolution(node, member.type);
   }
 
-  void _resolveReceiverDynamic(MethodInvocationImpl node) {
+  void _resolveReceiverDynamicBounded(MethodInvocation node) {
     var nameNode = node.methodName;
 
     var objectElement = _typeSystem.typeProvider.objectElement;
@@ -411,8 +413,13 @@
     node.argumentList.accept(_resolver);
   }
 
-  void _resolveReceiverFunctionType(MethodInvocation node, Expression receiver,
-      FunctionType receiverType, SimpleIdentifier nameNode, String name) {
+  void _resolveReceiverFunctionBounded(
+    MethodInvocation node,
+    Expression receiver,
+    DartType receiverType,
+    SimpleIdentifier nameNode,
+    String name,
+  ) {
     if (name == FunctionElement.CALL_METHOD_NAME) {
       _setResolution(node, receiverType);
       // TODO(scheglov) Replace this with using FunctionType directly.
@@ -432,18 +439,6 @@
     );
   }
 
-  void _resolveReceiverInterfaceType(MethodInvocation node, Expression receiver,
-      InterfaceType receiverType, SimpleIdentifier nameNode, String name) {
-    _resolveReceiverType(
-      node: node,
-      receiver: receiver,
-      receiverType: receiverType,
-      nameNode: nameNode,
-      name: name,
-      receiverErrorNode: receiver,
-    );
-  }
-
   void _resolveReceiverNever(
     MethodInvocation node,
     Expression receiver,
diff --git a/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
index 08ce229..48c20cd 100644
--- a/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
@@ -328,7 +328,6 @@
     }
 
     var targetType = target.staticType;
-    targetType = _resolveTypeParameter(targetType);
 
     if (targetType.isVoid) {
       _errorReporter.reportErrorForNode(
diff --git a/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
index f9ae35c..dcf0d9d 100644
--- a/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
@@ -8,7 +8,6 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
-import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:analyzer/src/dart/resolver/extension_member_resolver.dart';
@@ -71,9 +70,9 @@
     _nameErrorEntity = nameErrorEntity;
     _resetResult();
 
-    receiverType = _resolveTypeParameter(receiverType);
+    receiverType = _resolveTypeParameter(receiverType, ifLegacy: true);
 
-    if (receiverType is DynamicTypeImpl) {
+    if (_typeSystem.isDynamicBounded(receiverType)) {
       _lookupInterfaceType(_typeProvider.objectType);
       _needsGetterError = false;
       _needsSetterError = false;
@@ -100,29 +99,33 @@
       _reportedSetterError = true;
 
       // Recovery, get some resolution.
+      receiverType = _resolveTypeParameter(receiverType, ifNullSafe: true);
       if (receiverType is InterfaceType) {
         _lookupInterfaceType(receiverType);
       }
 
       return _toResult();
     } else {
-      if (receiverType is InterfaceType) {
-        _lookupInterfaceType(receiverType);
+      var receiverTypeResolved =
+          _resolveTypeParameter(receiverType, ifNullSafe: true);
+
+      if (receiverTypeResolved is InterfaceType) {
+        _lookupInterfaceType(receiverTypeResolved);
         if (_hasGetterOrSetter) {
           return _toResult();
         }
-        if (receiverType.isDartCoreFunction && _name == 'call') {
+        if (receiverTypeResolved.isDartCoreFunction && _name == 'call') {
           _needsGetterError = false;
           _needsSetterError = false;
           return _toResult();
         }
       }
 
-      if (receiverType is FunctionType && _name == 'call') {
+      if (receiverTypeResolved is FunctionType && _name == 'call') {
         return _toResult();
       }
 
-      if (receiverType is NeverType) {
+      if (receiverTypeResolved is NeverType) {
         _lookupInterfaceType(_typeProvider.objectType);
         _needsGetterError = false;
         _needsSetterError = false;
@@ -200,8 +203,22 @@
 
   /// If the given [type] is a type parameter, replace it with its bound.
   /// Otherwise, return the original type.
-  DartType _resolveTypeParameter(DartType type) {
-    return type?.resolveToBound(_typeProvider.objectType);
+  ///
+  /// See https://github.com/dart-lang/language/issues/1182
+  /// There was a bug in the analyzer (and CFE) - we were always resolving
+  /// types to bounds before searching for a property.  But  extensions should
+  /// be applied to original types.  Fixing this would be a breaking change,
+  /// so we fix it together with null safety.
+  DartType _resolveTypeParameter(
+    DartType type, {
+    bool ifLegacy = false,
+    bool ifNullSafe = false,
+  }) {
+    if (_typeSystem.isNonNullableByDefault ? ifNullSafe : ifLegacy) {
+      return type?.resolveToBound(_typeProvider.objectType);
+    } else {
+      return type;
+    }
   }
 
   ResolutionResult _toResult() {
diff --git a/pkg/analyzer/test/src/dart/element/test_all.dart b/pkg/analyzer/test/src/dart/element/test_all.dart
index f59885f..6efd3dd 100644
--- a/pkg/analyzer/test/src/dart/element/test_all.dart
+++ b/pkg/analyzer/test/src/dart/element/test_all.dart
@@ -22,6 +22,7 @@
 import 'subtype_test.dart' as subtype;
 import 'top_merge_test.dart' as top_merge;
 import 'type_algebra_test.dart' as type_algebra;
+import 'type_bounded_test.dart' as type_bounded;
 import 'type_constraint_gatherer_test.dart' as type_constraint_gatherer;
 import 'type_parameter_element_test.dart' as type_parameter_element;
 import 'type_visitor_test.dart' as type_visitor;
@@ -48,6 +49,7 @@
     subtype.main();
     top_merge.main();
     type_algebra.main();
+    type_bounded.main();
     type_constraint_gatherer.main();
     type_parameter_element.main();
     type_visitor.main();
diff --git a/pkg/analyzer/test/src/dart/element/type_bounded_test.dart b/pkg/analyzer/test/src/dart/element/type_bounded_test.dart
new file mode 100644
index 0000000..e851ca6
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/element/type_bounded_test.dart
@@ -0,0 +1,240 @@
+// Copyright (c) 2020, 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.
+
+import 'package:analyzer/dart/element/type.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../generated/type_system_test.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(DynamicBoundedTest);
+    defineReflectiveTests(FunctionBoundedTest);
+  });
+}
+
+@reflectiveTest
+class DynamicBoundedTest extends AbstractTypeSystemNullSafetyTest {
+  test_dynamic() {
+    _assertDynamicBounded(dynamicNone);
+  }
+
+  test_dynamic_typeParameter_hasBound_dynamic() {
+    var T = typeParameter('T', bound: dynamicNone);
+
+    _assertDynamicBounded(
+      typeParameterTypeNone(T),
+    );
+  }
+
+  test_dynamic_typeParameter_hasBound_notDynamic() {
+    var T = typeParameter('T', bound: intNone);
+
+    _assertNotDynamicBounded(
+      typeParameterTypeNone(T),
+    );
+  }
+
+  test_dynamic_typeParameter_hasPromotedBound_dynamic() {
+    var T = typeParameter('T');
+
+    _assertDynamicBounded(
+      typeParameterTypeNone(T, promotedBound: dynamicNone),
+    );
+  }
+
+  test_dynamic_typeParameter_hasPromotedBound_notDynamic() {
+    var T = typeParameter('T');
+
+    _assertNotDynamicBounded(
+      typeParameterTypeNone(T, promotedBound: intNone),
+    );
+  }
+
+  test_dynamic_typeParameter_noBound() {
+    var T = typeParameter('T');
+
+    _assertNotDynamicBounded(
+      typeParameterTypeNone(T),
+    );
+  }
+
+  test_functionType() {
+    _assertNotDynamicBounded(
+      functionTypeNone(returnType: voidNone),
+    );
+
+    _assertNotDynamicBounded(
+      functionTypeNone(returnType: dynamicNone),
+    );
+  }
+
+  test_interfaceType() {
+    _assertNotDynamicBounded(intNone);
+    _assertNotDynamicBounded(intQuestion);
+    _assertNotDynamicBounded(intStar);
+  }
+
+  test_never() {
+    _assertNotDynamicBounded(neverNone);
+    _assertNotDynamicBounded(neverQuestion);
+    _assertNotDynamicBounded(neverStar);
+  }
+
+  test_void() {
+    _assertNotDynamicBounded(voidNone);
+  }
+
+  void _assertDynamicBounded(DartType type) {
+    expect(typeSystem.isDynamicBounded(type), isTrue);
+  }
+
+  void _assertNotDynamicBounded(DartType type) {
+    expect(typeSystem.isDynamicBounded(type), isFalse);
+  }
+}
+
+@reflectiveTest
+class FunctionBoundedTest extends AbstractTypeSystemNullSafetyTest {
+  test_dynamic() {
+    _assertNotFunctionBounded(dynamicNone);
+  }
+
+  test_dynamic_typeParameter_hasBound_functionType_none() {
+    var T = typeParameter(
+      'T',
+      bound: functionTypeNone(returnType: voidNone),
+    );
+
+    _assertFunctionBounded(
+      typeParameterTypeNone(T),
+    );
+  }
+
+  test_dynamic_typeParameter_hasBound_functionType_question() {
+    var T = typeParameter(
+      'T',
+      bound: functionTypeQuestion(returnType: voidNone),
+    );
+
+    _assertNotFunctionBounded(
+      typeParameterTypeNone(T),
+    );
+  }
+
+  test_dynamic_typeParameter_hasBound_functionType_star() {
+    var T = typeParameter(
+      'T',
+      bound: functionTypeStar(returnType: voidNone),
+    );
+
+    _assertFunctionBounded(
+      typeParameterTypeStar(T),
+    );
+  }
+
+  test_dynamic_typeParameter_hasBound_notFunction() {
+    var T = typeParameter('T', bound: intNone);
+
+    _assertNotFunctionBounded(
+      typeParameterTypeNone(T),
+    );
+  }
+
+  test_dynamic_typeParameter_hasPromotedBound_functionType_none() {
+    var T = typeParameter('T');
+
+    _assertFunctionBounded(
+      typeParameterTypeNone(
+        T,
+        promotedBound: functionTypeNone(
+          returnType: voidNone,
+        ),
+      ),
+    );
+  }
+
+  test_dynamic_typeParameter_hasPromotedBound_functionType_question() {
+    var T = typeParameter('T');
+
+    _assertNotFunctionBounded(
+      typeParameterTypeStar(
+        T,
+        promotedBound: functionTypeQuestion(
+          returnType: voidNone,
+        ),
+      ),
+    );
+  }
+
+  test_dynamic_typeParameter_hasPromotedBound_functionType_star() {
+    var T = typeParameter('T');
+
+    _assertFunctionBounded(
+      typeParameterTypeStar(
+        T,
+        promotedBound: functionTypeStar(
+          returnType: voidNone,
+        ),
+      ),
+    );
+  }
+
+  test_dynamic_typeParameter_hasPromotedBound_notFunction() {
+    var T = typeParameter('T');
+
+    _assertNotFunctionBounded(
+      typeParameterTypeNone(T, promotedBound: intNone),
+    );
+  }
+
+  test_dynamic_typeParameter_noBound() {
+    var T = typeParameter('T');
+
+    _assertNotFunctionBounded(
+      typeParameterTypeNone(T),
+    );
+  }
+
+  test_functionType() {
+    _assertFunctionBounded(
+      functionTypeNone(returnType: voidNone),
+    );
+    _assertNotFunctionBounded(
+      functionTypeQuestion(returnType: voidNone),
+    );
+    _assertFunctionBounded(
+      functionTypeStar(returnType: voidNone),
+    );
+
+    _assertFunctionBounded(
+      functionTypeNone(returnType: dynamicNone),
+    );
+  }
+
+  test_interfaceType() {
+    _assertNotFunctionBounded(intNone);
+    _assertNotFunctionBounded(intQuestion);
+    _assertNotFunctionBounded(intStar);
+  }
+
+  test_never() {
+    _assertNotFunctionBounded(neverNone);
+    _assertNotFunctionBounded(neverQuestion);
+    _assertNotFunctionBounded(neverStar);
+  }
+
+  test_void() {
+    _assertNotFunctionBounded(voidNone);
+  }
+
+  void _assertFunctionBounded(DartType type) {
+    expect(typeSystem.isFunctionBounded(type), isTrue);
+  }
+
+  void _assertNotFunctionBounded(DartType type) {
+    expect(typeSystem.isFunctionBounded(type), isFalse);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
index 16de782..93ca075 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -2554,6 +2554,24 @@
     );
   }
 
+  test_hasReceiver_typeParameter_promotedToNonNullable() async {
+    await assertNoErrorsInCode('''
+void f<T>(T? t) {
+  if (t is int) {
+    t.abs();
+  }
+}
+''');
+
+    assertMethodInvocation2(
+      findNode.methodInvocation('t.abs()'),
+      element: intElement.getMethod('abs'),
+      typeArgumentTypes: [],
+      invokeType: 'int Function()',
+      type: 'int',
+    );
+  }
+
   test_nullShorting_cascade_firstMethodInvocation() async {
     await assertNoErrorsInCode(r'''
 class A {
diff --git a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
index ed5052e..9f951dc 100644
--- a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
@@ -440,6 +440,62 @@
     );
   }
 
+  test_targetTypeParameter_dynamicBounded() async {
+    await assertNoErrorsInCode('''
+class A<T extends dynamic> {
+  void f(T t) {
+    (t).foo;
+  }
+}
+''');
+
+    var propertyAccess = findNode.propertyAccess('.foo');
+    assertPropertyAccess2(
+      propertyAccess,
+      element: null,
+      type: 'dynamic',
+    );
+
+    assertSimpleIdentifier(
+      propertyAccess.propertyName,
+      readElement: null,
+      writeElement: null,
+      type: 'dynamic',
+    );
+  }
+
+  test_targetTypeParameter_noBound() async {
+    await resolveTestCode('''
+class C<T> {
+  void f(T t) {
+    (t).foo;
+  }
+}
+''');
+    assertErrorsInResult(expectedErrorsByNullability(
+      nullable: [
+        error(CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE, 33, 3),
+      ],
+      legacy: [
+        error(CompileTimeErrorCode.UNDEFINED_GETTER, 37, 3),
+      ],
+    ));
+
+    var propertyAccess = findNode.propertyAccess('.foo');
+    assertPropertyAccess2(
+      propertyAccess,
+      element: null,
+      type: 'dynamic',
+    );
+
+    assertSimpleIdentifier(
+      propertyAccess.propertyName,
+      readElement: null,
+      writeElement: null,
+      type: 'dynamic',
+    );
+  }
+
   test_tearOff_method() async {
     await assertNoErrorsInCode('''
 class A {
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/extension_methods_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/extension_methods_test.dart
index cf8638c..d9581ac 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/extension_methods_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/extension_methods_test.dart
@@ -6,15 +6,20 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../context_collection_resolution.dart';
+import '../resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ExtensionMethodsTest);
+    defineReflectiveTests(ExtensionMethodsWithNullSafetyTest);
   });
 }
 
 @reflectiveTest
-class ExtensionMethodsTest extends PubPackageResolutionTest {
+class ExtensionMethodsTest extends PubPackageResolutionTest
+    with ExtensionMethodsTestCases {}
+
+mixin ExtensionMethodsTestCases on ResolutionTest {
   test_implicit_getter() async {
     await assertNoErrorsInCode('''
 class A<T> {}
@@ -150,6 +155,118 @@
     );
   }
 
+  test_implicit_targetTypeParameter_hasBound_methodInvocation() async {
+    await assertNoErrorsInCode('''
+extension Test<T> on T {
+  T Function(T) test() => throw 0;
+}
+
+void f<S extends num>(S x) {
+  x.test();
+}
+''');
+
+    if (result.libraryElement.isNonNullableByDefault) {
+      assertMethodInvocation2(
+        findNode.methodInvocation('test();'),
+        element: elementMatcher(
+          findElement.method('test'),
+          substitution: {'T': 'S'},
+        ),
+        typeArgumentTypes: [],
+        invokeType: 'S Function(S) Function()',
+        type: 'S Function(S)',
+      );
+    } else {
+      assertMethodInvocation2(
+        findNode.methodInvocation('test();'),
+        element: elementMatcher(
+          findElement.method('test'),
+          substitution: {'T': 'num'},
+        ),
+        typeArgumentTypes: [],
+        invokeType: 'num Function(num) Function()',
+        type: 'num Function(num)',
+      );
+    }
+  }
+
+  test_implicit_targetTypeParameter_hasBound_propertyAccess_getter() async {
+    await assertNoErrorsInCode('''
+extension Test<T> on T {
+  T Function(T) get test => throw 0;
+}
+
+void f<S extends num>(S x) {
+  (x).test;
+}
+''');
+
+    if (result.libraryElement.isNonNullableByDefault) {
+      assertPropertyAccess2(
+        findNode.propertyAccess('.test'),
+        element: elementMatcher(
+          findElement.getter('test'),
+          substitution: {'T': 'S'},
+        ),
+        type: 'S Function(S)',
+      );
+    } else {
+      assertPropertyAccess2(
+        findNode.propertyAccess('.test'),
+        element: elementMatcher(
+          findElement.getter('test'),
+          substitution: {'T': 'num'},
+        ),
+        type: 'num Function(num)',
+      );
+    }
+  }
+
+  test_implicit_targetTypeParameter_hasBound_propertyAccess_setter() async {
+    await assertNoErrorsInCode('''
+extension Test<T> on T {
+  void set test(T _) {}
+}
+
+T g<T>() => throw 0;
+
+void f<S extends num>(S x) {
+  (x).test = g();
+}
+''');
+
+    if (result.libraryElement.isNonNullableByDefault) {
+      assertPropertyAccess2(
+        findNode.propertyAccess('.test'),
+        element: elementMatcher(
+          findElement.setter('test'),
+          substitution: {'T': 'S'},
+        ),
+        type: 'S',
+      );
+
+      assertTypeArgumentTypes(
+        findNode.methodInvocation('g()'),
+        ['S'],
+      );
+    } else {
+      assertPropertyAccess2(
+        findNode.propertyAccess('.test'),
+        element: elementMatcher(
+          findElement.setter('test'),
+          substitution: {'T': 'num'},
+        ),
+        type: 'num',
+      );
+
+      assertTypeArgumentTypes(
+        findNode.methodInvocation('g()'),
+        ['num'],
+      );
+    }
+  }
+
   test_override_downward_hasTypeArguments() async {
     await assertNoErrorsInCode('''
 extension E<T> on Set<T> {
@@ -425,3 +542,7 @@
     );
   }
 }
+
+@reflectiveTest
+class ExtensionMethodsWithNullSafetyTest extends PubPackageResolutionTest
+    with WithNullSafetyMixin, ExtensionMethodsTestCases {}
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 9c2d399..c5ec2e9 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -964,11 +964,6 @@
         js_ast.ClassExpression(
             _emitTemporaryId(mixinName), baseClass, forwardingMethodStubs)
       ]));
-      // Emit a deferred superclass statement for virtual mixin classes since
-      // dart.mixinOn requires the virtual object to have a valid prototype.
-      var virtualSupertype = baseClass ?? emitDeferredType(supertype);
-      body.add(
-          runtimeStatement('setBaseClass(#, #)', [mixinId, virtualSupertype]));
 
       emitMixinConstructors(mixinId, mixinType);
       hasUnnamedSuper = hasUnnamedSuper || _hasUnnamedConstructor(mixinClass);
diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
index 321cac5..340d7da 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
@@ -208,6 +208,9 @@
   "process": {
     ExperimentalFlag.nonNullable,
   },
+  "pub_semver": {
+    ExperimentalFlag.nonNullable,
+  },
   "sky_engine": {
     ExperimentalFlag.nonNullable,
   },
diff --git a/sdk/lib/_internal/allowed_experiments.json b/sdk/lib/_internal/allowed_experiments.json
index 8fe425f..c967d66 100644
--- a/sdk/lib/_internal/allowed_experiments.json
+++ b/sdk/lib/_internal/allowed_experiments.json
@@ -100,6 +100,9 @@
     "process": {
       "experimentSet": "nullSafety"
     },
+    "pub_semver": {
+      "experimentSet": "nullSafety"
+    },
     "sky_engine": {
       "experimentSet": "nullSafety"
     },
diff --git a/tests/language/mixin/regress_flutter_66859_test.dart b/tests/language/mixin/regress_flutter_66859_test.dart
deleted file mode 100644
index 544da53..0000000
--- a/tests/language/mixin/regress_flutter_66859_test.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2020, 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.
-
-// Verifies that mixin supertypes are properly maintained even if marked as
-// deferred (e.g., in a circular hierarchy).
-// Regression test for: https://github.com/flutter/flutter/issues/66859
-
-import "package:expect/expect.dart";
-
-mixin M {}
-
-mixin N {}
-
-class A extends B<C> with M, N {}
-
-class B<T> {}
-
-class C extends A {}
-
-class Z extends B<Z> with M {}
-
-main() {
-  var z = Z();
-  Expect.isTrue(z is B<Z>);
-  Expect.isTrue(z is M);
-  var a = A();
-  Expect.isTrue(a is M);
-  Expect.isTrue(a is N);
-  Expect.isTrue(a is B<C>);
-}
diff --git a/tools/VERSION b/tools/VERSION
index 590277c..c38dcce 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 11
 PATCH 0
-PRERELEASE 183
+PRERELEASE 184
 PRERELEASE_PATCH 0
\ No newline at end of file