Version 2.18.0-223.0.dev

Merge commit 'bb104f07fcd4d379b003782264bfae327e034418' into 'dev'
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index d2719fc..eb3c52a 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -1085,22 +1085,14 @@
   ir.DartType visitSuperPropertyGet(ir.SuperPropertyGet node) {
     ir.DartType resultType;
     final interfaceTarget = node.interfaceTarget;
-    if (interfaceTarget == null) {
-      // TODO(johnniwinther): Resolve and set the target here.
-      resultType = const ir.DynamicType();
+    ir.Class declaringClass = interfaceTarget.enclosingClass!;
+    if (declaringClass.typeParameters.isEmpty) {
+      resultType = interfaceTarget.superGetterType;
     } else {
-      ir.Class declaringClass = interfaceTarget.enclosingClass!;
-      if (declaringClass.typeParameters.isEmpty) {
-        resultType = interfaceTarget.superGetterType;
-      } else {
-        ir.InterfaceType receiver = typeEnvironment.getTypeAsInstanceOf(
-            thisType,
-            declaringClass,
-            currentLibrary,
-            typeEnvironment.coreTypes)!;
-        resultType = ir.Substitution.fromInterfaceType(receiver)
-            .substituteType(interfaceTarget.superGetterType);
-      }
+      ir.InterfaceType receiver = typeEnvironment.getTypeAsInstanceOf(
+          thisType, declaringClass, currentLibrary, typeEnvironment.coreTypes)!;
+      resultType = ir.Substitution.fromInterfaceType(receiver)
+          .substituteType(interfaceTarget.superGetterType);
     }
     _staticTypeCache._expressionTypes[node] = resultType;
     handleSuperPropertyGet(node, resultType);
@@ -1125,19 +1117,14 @@
     ArgumentTypes argumentTypes = _visitArguments(node.arguments);
     ir.DartType returnType;
     final interfaceTarget = node.interfaceTarget;
-    if (interfaceTarget == null) {
-      // TODO(johnniwinther): Resolve and set the target here.
-      returnType = const ir.DynamicType();
-    } else {
-      ir.Class superclass = interfaceTarget.enclosingClass!;
-      ir.InterfaceType receiverType = typeEnvironment.getTypeAsInstanceOf(
-          thisType, superclass, currentLibrary, typeEnvironment.coreTypes)!;
-      returnType = ir.Substitution.fromInterfaceType(receiverType)
-          .substituteType(interfaceTarget.function.returnType);
-      returnType = ir.Substitution.fromPairs(
-              interfaceTarget.function.typeParameters, node.arguments.types)
-          .substituteType(returnType);
-    }
+    ir.Class superclass = interfaceTarget.enclosingClass!;
+    ir.InterfaceType receiverType = typeEnvironment.getTypeAsInstanceOf(
+        thisType, superclass, currentLibrary, typeEnvironment.coreTypes)!;
+    returnType = ir.Substitution.fromInterfaceType(receiverType)
+        .substituteType(interfaceTarget.function.returnType);
+    returnType = ir.Substitution.fromPairs(
+            interfaceTarget.function.typeParameters, node.arguments.types)
+        .substituteType(returnType);
     _staticTypeCache._expressionTypes[node] = returnType;
     handleSuperMethodInvocation(node, argumentTypes, returnType);
     return returnType;
diff --git a/pkg/compiler/lib/src/ir/util.dart b/pkg/compiler/lib/src/ir/util.dart
index 1dcc687..c9fa392 100644
--- a/pkg/compiler/lib/src/ir/util.dart
+++ b/pkg/compiler/lib/src/ir/util.dart
@@ -287,6 +287,11 @@
     if (target.stubKind == ir.ProcedureStubKind.ConcreteMixinStub) {
       return getEffectiveSuperTarget(target.stubTarget);
     }
+    // TODO(johnniwinther): Remove this when the CFE reports an error on
+    // missing concrete super targets.
+    if (target.isAbstract) {
+      return null;
+    }
   }
   return target;
 }
diff --git a/pkg/dart2wasm/lib/code_generator.dart b/pkg/dart2wasm/lib/code_generator.dart
index de13bd0..8671f20 100644
--- a/pkg/dart2wasm/lib/code_generator.dart
+++ b/pkg/dart2wasm/lib/code_generator.dart
@@ -1137,7 +1137,7 @@
   w.ValueType visitSuperMethodInvocation(
       SuperMethodInvocation node, w.ValueType expectedType) {
     Reference target =
-        _lookupSuperTarget(node.interfaceTarget!, setter: false).reference;
+        _lookupSuperTarget(node.interfaceTarget, setter: false).reference;
     w.BaseFunction targetFunction = translator.functions.getFunction(target);
     w.ValueType receiverType = targetFunction.type.inputs.first;
     w.ValueType thisType = visitThis(receiverType);
@@ -1515,7 +1515,7 @@
   @override
   w.ValueType visitSuperPropertyGet(
       SuperPropertyGet node, w.ValueType expectedType) {
-    Member target = _lookupSuperTarget(node.interfaceTarget!, setter: false);
+    Member target = _lookupSuperTarget(node.interfaceTarget, setter: false);
     if (target is Procedure && !target.isGetter) {
       throw "Not supported: Super tear-off at ${node.location}";
     }
@@ -1525,7 +1525,7 @@
   @override
   w.ValueType visitSuperPropertySet(
       SuperPropertySet node, w.ValueType expectedType) {
-    Member target = _lookupSuperTarget(node.interfaceTarget!, setter: true);
+    Member target = _lookupSuperTarget(node.interfaceTarget, setter: true);
     return _directSet(target, ThisExpression(), node.value,
         preserved: expectedType != voidMarker);
   }
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index f8e15fd..a90af23 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -4790,12 +4790,12 @@
   @override
   js_ast.Expression visitAbstractSuperPropertyGet(
       AbstractSuperPropertyGet node) {
-    return _emitSuperPropertyGet(node.interfaceTarget!);
+    return _emitSuperPropertyGet(node.interfaceTarget);
   }
 
   @override
   js_ast.Expression visitSuperPropertyGet(SuperPropertyGet node) {
-    return _emitSuperPropertyGet(node.interfaceTarget!);
+    return _emitSuperPropertyGet(node.interfaceTarget);
   }
 
   js_ast.Expression _emitSuperPropertyGet(Member target) {
@@ -4813,12 +4813,12 @@
   @override
   js_ast.Expression visitAbstractSuperPropertySet(
       AbstractSuperPropertySet node) {
-    return _emitSuperPropertySet(node.interfaceTarget!, node.value);
+    return _emitSuperPropertySet(node.interfaceTarget, node.value);
   }
 
   @override
   js_ast.Expression visitSuperPropertySet(SuperPropertySet node) {
-    return _emitSuperPropertySet(node.interfaceTarget!, node.value);
+    return _emitSuperPropertySet(node.interfaceTarget, node.value);
   }
 
   js_ast.Expression _emitSuperPropertySet(Member target, Expression value) {
@@ -5432,12 +5432,12 @@
   @override
   js_ast.Expression visitAbstractSuperMethodInvocation(
       AbstractSuperMethodInvocation node) {
-    return _emitSuperMethodInvocation(node.interfaceTarget!, node.arguments);
+    return _emitSuperMethodInvocation(node.interfaceTarget, node.arguments);
   }
 
   @override
   js_ast.Expression visitSuperMethodInvocation(SuperMethodInvocation node) {
-    return _emitSuperMethodInvocation(node.interfaceTarget!, node.arguments);
+    return _emitSuperMethodInvocation(node.interfaceTarget, node.arguments);
   }
 
   js_ast.Expression _emitSuperMethodInvocation(
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index 0c6c50e..39ecc43 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -836,11 +836,13 @@
   }
 
   Expression _createRead() {
+    Member? getter = this.getter;
     if (getter == null) {
       return _helper.buildUnresolvedError(name.text, fileOffset,
           isSuper: true, kind: UnresolvedKind.Getter);
+    } else {
+      return new SuperPropertyGet(name, getter)..fileOffset = fileOffset;
     }
-    return new SuperPropertyGet(name, getter)..fileOffset = fileOffset;
   }
 
   @override
@@ -849,13 +851,13 @@
   }
 
   Expression _createWrite(int offset, Expression value) {
+    Member? setter = this.setter;
     if (setter == null) {
       return _helper.buildUnresolvedError(name.text, fileOffset,
           rhs: value, isSuper: true, kind: UnresolvedKind.Setter);
+    } else {
+      return new SuperPropertySet(name, value, setter)..fileOffset = offset;
     }
-    SuperPropertySet write = new SuperPropertySet(name, value, setter)
-      ..fileOffset = offset;
-    return write;
   }
 
   @override
@@ -1227,6 +1229,7 @@
 
   @override
   Expression buildSimpleRead() {
+    Procedure? getter = this.getter;
     if (getter == null) {
       return _helper.buildUnresolvedError(indexGetName.text, fileOffset,
           isSuper: true,
@@ -1234,33 +1237,36 @@
               _helper.forest.createArguments(fileOffset, <Expression>[index]),
           kind: UnresolvedKind.Method,
           length: noLength);
+    } else {
+      return _helper.forest.createSuperMethodInvocation(
+          fileOffset,
+          indexGetName,
+          getter,
+          _helper.forest.createArguments(fileOffset, <Expression>[index]));
     }
-    return _helper.forest.createSuperMethodInvocation(
-        fileOffset,
-        indexGetName,
-        getter,
-        _helper.forest.createArguments(fileOffset, <Expression>[index]));
   }
 
   @override
   Expression buildAssignment(Expression value, {bool voidContext: false}) {
-    if (voidContext) {
-      if (setter == null) {
-        return _helper.buildUnresolvedError(indexSetName.text, fileOffset,
-            isSuper: true,
-            arguments: _helper.forest
-                .createArguments(fileOffset, <Expression>[index, value]),
-            kind: UnresolvedKind.Method,
-            length: noLength);
-      }
-      return _helper.forest.createSuperMethodInvocation(
-          fileOffset,
-          indexSetName,
-          setter,
-          _helper.forest
-              .createArguments(fileOffset, <Expression>[index, value]));
+    Procedure? setter = this.setter;
+    if (setter == null) {
+      return _helper.buildUnresolvedError(indexSetName.text, fileOffset,
+          isSuper: true,
+          arguments: _helper.forest
+              .createArguments(fileOffset, <Expression>[index, value]),
+          kind: UnresolvedKind.Method,
+          length: noLength);
     } else {
-      return new SuperIndexSet(setter, index, value)..fileOffset = fileOffset;
+      if (voidContext) {
+        return _helper.forest.createSuperMethodInvocation(
+            fileOffset,
+            indexSetName,
+            setter,
+            _helper.forest
+                .createArguments(fileOffset, <Expression>[index, value]));
+      } else {
+        return new SuperIndexSet(setter, index, value)..fileOffset = fileOffset;
+      }
     }
   }
 
@@ -1281,13 +1287,20 @@
       bool voidContext: false,
       bool isPreIncDec: false,
       bool isPostIncDec: false}) {
-    return new CompoundSuperIndexSet(
-        getter, setter, index, binaryOperator, value,
-        readOffset: fileOffset,
-        binaryOffset: offset,
-        writeOffset: fileOffset,
-        forEffect: voidContext,
-        forPostIncDec: isPostIncDec);
+    Procedure? getter = this.getter;
+    Procedure? setter = this.setter;
+    if (getter == null || setter == null) {
+      return buildAssignment(
+          buildBinaryOperation(token, binaryOperator, value));
+    } else {
+      return new CompoundSuperIndexSet(
+          getter, setter, index, binaryOperator, value,
+          readOffset: fileOffset,
+          binaryOffset: offset,
+          writeOffset: fileOffset,
+          forEffect: voidContext,
+          forPostIncDec: isPostIncDec);
+    }
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index 16a32f9..54be130 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -752,7 +752,7 @@
   }
 
   SuperMethodInvocation createSuperMethodInvocation(
-      int fileOffset, Name name, Procedure? procedure, Arguments arguments) {
+      int fileOffset, Name name, Procedure procedure, Arguments arguments) {
     // ignore: unnecessary_null_comparison
     assert(fileOffset != null);
     return new SuperMethodInvocation(name, arguments, procedure)
diff --git a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
index 73e8b41..bc654d8 100644
--- a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
@@ -2682,7 +2682,7 @@
 ///
 class SuperIndexSet extends InternalExpression {
   /// The []= member.
-  Member? setter;
+  Member setter;
 
   /// The index expression of the operation.
   Expression index;
@@ -3707,10 +3707,10 @@
 ///
 class CompoundSuperIndexSet extends InternalExpression {
   /// The [] member.
-  Member? getter;
+  Member getter;
 
   /// The []= member.
-  Member? setter;
+  Member setter;
 
   /// The index expression of the operation.
   Expression index;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
index 292f63b..1ff55fd 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
@@ -3521,10 +3521,9 @@
 
   ExpressionInferenceResult visitSuperIndexSet(
       SuperIndexSet node, DartType typeContext) {
-    ObjectAccessTarget indexSetTarget = node.setter != null
-        ? new ObjectAccessTarget.interfaceMember(node.setter!,
-            isPotentiallyNullable: false)
-        : const ObjectAccessTarget.missing();
+    ObjectAccessTarget indexSetTarget = new ObjectAccessTarget.interfaceMember(
+        node.setter,
+        isPotentiallyNullable: false);
 
     DartType indexType = getIndexKeyType(indexSetTarget, thisType!);
     DartType valueType = getIndexSetValueType(indexSetTarget, thisType!);
@@ -3560,20 +3559,16 @@
     // the type of the value parameter.
     DartType inferredType = valueResult.inferredType;
 
-    Expression assignment;
-    if (indexSetTarget.isMissing) {
-      assignment = createMissingSuperIndexSet(node.fileOffset, index, value);
-    } else {
-      assert(indexSetTarget.isInstanceMember || indexSetTarget.isObjectMember);
-      instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
-          new InstrumentationValueForMember(node.setter!));
-      assignment = new SuperMethodInvocation(
-          indexSetName,
-          new Arguments(<Expression>[index, value])
-            ..fileOffset = node.fileOffset,
-          indexSetTarget.member as Procedure)
-        ..fileOffset = node.fileOffset;
-    }
+    assert(indexSetTarget.isInstanceMember || indexSetTarget.isObjectMember,
+        'Unexpected index set target $indexSetTarget.');
+    instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
+        new InstrumentationValueForMember(node.setter));
+    Expression assignment = new SuperMethodInvocation(
+        indexSetName,
+        new Arguments(<Expression>[index, value])..fileOffset = node.fileOffset,
+        indexSetTarget.member as Procedure)
+      ..fileOffset = node.fileOffset;
+
     VariableDeclaration assignmentVariable =
         createVariable(assignment, const VoidType());
     Expression replacement = createLet(assignmentVariable, returnedValue);
@@ -3886,23 +3881,17 @@
     writeIndex =
         ensureAssignable(writeIndexType, indexResult.inferredType, writeIndex);
 
-    Expression read;
-
-    if (readTarget.isMissing) {
-      read = createMissingSuperIndexGet(node.readOffset, readIndex);
-    } else {
-      assert(readTarget.isInstanceMember || readTarget.isObjectMember);
-      instrumentation?.record(uriForInstrumentation, node.readOffset, 'target',
-          new InstrumentationValueForMember(node.getter!));
-      read = new SuperMethodInvocation(
-          indexGetName,
-          new Arguments(<Expression>[
-            readIndex,
-          ])
-            ..fileOffset = node.readOffset,
-          readTarget.member as Procedure)
-        ..fileOffset = node.readOffset;
-    }
+    assert(readTarget.isInstanceMember || readTarget.isObjectMember);
+    instrumentation?.record(uriForInstrumentation, node.readOffset, 'target',
+        new InstrumentationValueForMember(node.getter!));
+    Expression read = new SuperMethodInvocation(
+        indexGetName,
+        new Arguments(<Expression>[
+          readIndex,
+        ])
+          ..fileOffset = node.readOffset,
+        readTarget.member as Procedure)
+      ..fileOffset = node.readOffset;
 
     flowAnalysis.ifNullExpression_rightBegin(read, readType);
     ExpressionInferenceResult valueResult =
@@ -3927,21 +3916,15 @@
       returnedValue = createVariableGet(valueVariable);
     }
 
-    Expression write;
-
-    if (writeTarget.isMissing) {
-      write = createMissingSuperIndexSet(node.writeOffset, writeIndex, value);
-    } else {
-      assert(writeTarget.isInstanceMember || writeTarget.isObjectMember);
-      instrumentation?.record(uriForInstrumentation, node.writeOffset, 'target',
-          new InstrumentationValueForMember(node.setter!));
-      write = new SuperMethodInvocation(
-          indexSetName,
-          new Arguments(<Expression>[writeIndex, value])
-            ..fileOffset = node.writeOffset,
-          writeTarget.member as Procedure)
-        ..fileOffset = node.writeOffset;
-    }
+    assert(writeTarget.isInstanceMember || writeTarget.isObjectMember);
+    instrumentation?.record(uriForInstrumentation, node.writeOffset, 'target',
+        new InstrumentationValueForMember(node.setter!));
+    Expression write = new SuperMethodInvocation(
+        indexSetName,
+        new Arguments(<Expression>[writeIndex, value])
+          ..fileOffset = node.writeOffset,
+        writeTarget.member as Procedure)
+      ..fileOffset = node.writeOffset;
 
     Expression replacement;
     if (node.forEffect) {
@@ -5387,10 +5370,9 @@
 
   ExpressionInferenceResult visitCompoundSuperIndexSet(
       CompoundSuperIndexSet node, DartType typeContext) {
-    ObjectAccessTarget readTarget = node.getter != null
-        ? new ObjectAccessTarget.interfaceMember(node.getter!,
-            isPotentiallyNullable: false)
-        : const ObjectAccessTarget.missing();
+    ObjectAccessTarget readTarget = new ObjectAccessTarget.interfaceMember(
+        node.getter,
+        isPotentiallyNullable: false);
 
     DartType readType = getReturnType(readTarget, thisType!);
     DartType readIndexType = getIndexKeyType(readTarget, thisType!);
@@ -5412,22 +5394,17 @@
     readIndex =
         ensureAssignable(readIndexType, indexResult.inferredType, readIndex);
 
-    Expression read;
-    if (readTarget.isMissing) {
-      read = createMissingSuperIndexGet(node.readOffset, readIndex);
-    } else {
-      assert(readTarget.isInstanceMember || readTarget.isObjectMember);
-      instrumentation?.record(uriForInstrumentation, node.readOffset, 'target',
-          new InstrumentationValueForMember(node.getter!));
-      read = new SuperMethodInvocation(
-          indexGetName,
-          new Arguments(<Expression>[
-            readIndex,
-          ])
-            ..fileOffset = node.readOffset,
-          readTarget.member as Procedure)
-        ..fileOffset = node.readOffset;
-    }
+    assert(readTarget.isInstanceMember || readTarget.isObjectMember);
+    instrumentation?.record(uriForInstrumentation, node.readOffset, 'target',
+        new InstrumentationValueForMember(node.getter));
+    Expression read = new SuperMethodInvocation(
+        indexGetName,
+        new Arguments(<Expression>[
+          readIndex,
+        ])
+          ..fileOffset = node.readOffset,
+        readTarget.member as Procedure)
+      ..fileOffset = node.readOffset;
 
     VariableDeclaration? leftVariable;
     Expression left;
@@ -5439,10 +5416,9 @@
     } else {
       left = read;
     }
-    ObjectAccessTarget writeTarget = node.setter != null
-        ? new ObjectAccessTarget.interfaceMember(node.setter!,
-            isPotentiallyNullable: false)
-        : const ObjectAccessTarget.missing();
+    ObjectAccessTarget writeTarget = new ObjectAccessTarget.interfaceMember(
+        node.setter,
+        isPotentiallyNullable: false);
 
     DartType writeIndexType = getIndexKeyType(writeTarget, thisType!);
 
@@ -5474,21 +5450,15 @@
       valueExpression = createVariableGet(valueVariable);
     }
 
-    Expression write;
-    if (writeTarget.isMissing) {
-      write = createMissingSuperIndexSet(
-          node.writeOffset, writeIndex, valueExpression);
-    } else {
-      assert(writeTarget.isInstanceMember || writeTarget.isObjectMember);
-      instrumentation?.record(uriForInstrumentation, node.writeOffset, 'target',
-          new InstrumentationValueForMember(node.setter!));
-      write = new SuperMethodInvocation(
-          indexSetName,
-          new Arguments(<Expression>[writeIndex, valueExpression])
-            ..fileOffset = node.writeOffset,
-          writeTarget.member as Procedure)
-        ..fileOffset = node.writeOffset;
-    }
+    assert(writeTarget.isInstanceMember || writeTarget.isObjectMember);
+    instrumentation?.record(uriForInstrumentation, node.writeOffset, 'target',
+        new InstrumentationValueForMember(node.setter));
+    Expression write = new SuperMethodInvocation(
+        indexSetName,
+        new Arguments(<Expression>[writeIndex, valueExpression])
+          ..fileOffset = node.writeOffset,
+        writeTarget.member as Procedure)
+      ..fileOffset = node.writeOffset;
 
     Expression replacement;
     if (node.forEffect) {
@@ -6145,11 +6115,8 @@
   @override
   ExpressionInferenceResult visitAbstractSuperMethodInvocation(
       AbstractSuperMethodInvocation node, DartType typeContext) {
-    if (node.interfaceTarget != null) {
-      instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
-          new InstrumentationValueForMember(node.interfaceTarget!));
-    }
-    assert(node.interfaceTarget == null || node.interfaceTarget is Procedure);
+    instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
+        new InstrumentationValueForMember(node.interfaceTarget));
     return inferSuperMethodInvocation(this, node, node.name,
         node.arguments as ArgumentsImpl, typeContext, node.interfaceTarget);
   }
@@ -6157,11 +6124,8 @@
   @override
   ExpressionInferenceResult visitSuperMethodInvocation(
       SuperMethodInvocation node, DartType typeContext) {
-    if (node.interfaceTarget != null) {
-      instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
-          new InstrumentationValueForMember(node.interfaceTarget!));
-    }
-    assert(node.interfaceTarget == null || node.interfaceTarget is Procedure);
+    instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
+        new InstrumentationValueForMember(node.interfaceTarget));
     return inferSuperMethodInvocation(this, node, node.name,
         node.arguments as ArgumentsImpl, typeContext, node.interfaceTarget);
   }
@@ -6169,10 +6133,8 @@
   @override
   ExpressionInferenceResult visitAbstractSuperPropertyGet(
       AbstractSuperPropertyGet node, DartType typeContext) {
-    if (node.interfaceTarget != null) {
-      instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
-          new InstrumentationValueForMember(node.interfaceTarget!));
-    }
+    instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
+        new InstrumentationValueForMember(node.interfaceTarget));
     return inferSuperPropertyGet(
         node, node.name, typeContext, node.interfaceTarget);
   }
@@ -6180,10 +6142,8 @@
   @override
   ExpressionInferenceResult visitSuperPropertyGet(
       SuperPropertyGet node, DartType typeContext) {
-    if (node.interfaceTarget != null) {
-      instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
-          new InstrumentationValueForMember(node.interfaceTarget!));
-    }
+    instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
+        new InstrumentationValueForMember(node.interfaceTarget));
     return inferSuperPropertyGet(
         node, node.name, typeContext, node.interfaceTarget);
   }
@@ -6194,15 +6154,12 @@
     DartType receiverType = classHierarchy.getTypeAsInstanceOf(thisType!,
         thisType!.classNode.supertype!.classNode, libraryBuilder.library)!;
 
-    ObjectAccessTarget writeTarget = node.interfaceTarget != null
-        ? new ObjectAccessTarget.interfaceMember(node.interfaceTarget!,
-            isPotentiallyNullable: false)
-        : const ObjectAccessTarget.missing();
+    ObjectAccessTarget writeTarget = new ObjectAccessTarget.interfaceMember(
+        node.interfaceTarget,
+        isPotentiallyNullable: false);
     DartType writeContext = getSetterType(writeTarget, receiverType);
-    if (node.interfaceTarget != null) {
-      writeContext = computeTypeFromSuperClass(
-          node.interfaceTarget!.enclosingClass!, writeContext);
-    }
+    writeContext = computeTypeFromSuperClass(
+        node.interfaceTarget.enclosingClass!, writeContext);
     ExpressionInferenceResult rhsResult =
         inferExpression(node.value, writeContext, true, isVoidAllowed: true);
     rhsResult = ensureAssignableResult(writeContext, rhsResult,
@@ -6218,15 +6175,12 @@
     DartType receiverType = classHierarchy.getTypeAsInstanceOf(thisType!,
         thisType!.classNode.supertype!.classNode, libraryBuilder.library)!;
 
-    ObjectAccessTarget writeTarget = node.interfaceTarget != null
-        ? new ObjectAccessTarget.interfaceMember(node.interfaceTarget!,
-            isPotentiallyNullable: false)
-        : const ObjectAccessTarget.missing();
+    ObjectAccessTarget writeTarget = new ObjectAccessTarget.interfaceMember(
+        node.interfaceTarget,
+        isPotentiallyNullable: false);
     DartType writeContext = getSetterType(writeTarget, receiverType);
-    if (node.interfaceTarget != null) {
-      writeContext = computeTypeFromSuperClass(
-          node.interfaceTarget!.enclosingClass!, writeContext);
-    }
+    writeContext = computeTypeFromSuperClass(
+        node.interfaceTarget.enclosingClass!, writeContext);
     ExpressionInferenceResult rhsResult =
         inferExpression(node.value, writeContext, true, isVoidAllowed: true);
     rhsResult = ensureAssignableResult(writeContext, rhsResult,
@@ -7167,9 +7121,7 @@
         receiverType, superPropertySet.name, superPropertySet.fileOffset,
         callSiteAccessKind: CallSiteAccessKind.setterInvocation,
         instrumented: true);
-    if (writeTarget.isInstanceMember || writeTarget.isObjectMember) {
-      superPropertySet.interfaceTarget = writeTarget.member;
-    }
+    assert(writeTarget.isInstanceMember || writeTarget.isObjectMember);
     return _writeType = visitor.getSetterType(writeTarget, receiverType);
   }
 
@@ -7207,9 +7159,7 @@
         receiverType, superPropertySet.name, superPropertySet.fileOffset,
         callSiteAccessKind: CallSiteAccessKind.setterInvocation,
         instrumented: true);
-    if (writeTarget.isInstanceMember || writeTarget.isObjectMember) {
-      superPropertySet.interfaceTarget = writeTarget.member;
-    }
+    assert(writeTarget.isInstanceMember || writeTarget.isObjectMember);
     return _writeType = visitor.getSetterType(writeTarget, receiverType);
   }
 
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index dc4fdbe..fb520a1 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -4500,35 +4500,6 @@
     return false;
   }
 
-  Expression createMissingSuperIndexGet(int fileOffset, Expression index) {
-    if (isTopLevel) {
-      return engine.forest.createSuperMethodInvocation(fileOffset, indexGetName,
-          null, engine.forest.createArguments(fileOffset, <Expression>[index]));
-    } else {
-      return helper.buildProblem(
-          templateSuperclassHasNoMethod.withArguments(indexGetName.text),
-          fileOffset,
-          noLength);
-    }
-  }
-
-  Expression createMissingSuperIndexSet(
-      int fileOffset, Expression index, Expression value) {
-    if (isTopLevel) {
-      return engine.forest.createSuperMethodInvocation(
-          fileOffset,
-          indexSetName,
-          null,
-          engine.forest
-              .createArguments(fileOffset, <Expression>[index, value]));
-    } else {
-      return helper.buildProblem(
-          templateSuperclassHasNoMethod.withArguments(indexSetName.text),
-          fileOffset,
-          noLength);
-    }
-  }
-
   /// Creates an expression the represents the invalid invocation of [name] on
   /// [receiver] with [arguments].
   ///
diff --git a/pkg/front_end/test/comments_on_certain_arguments_tool.dart b/pkg/front_end/test/comments_on_certain_arguments_tool.dart
index c588afc..b8fd17e 100644
--- a/pkg/front_end/test/comments_on_certain_arguments_tool.dart
+++ b/pkg/front_end/test/comments_on_certain_arguments_tool.dart
@@ -197,7 +197,7 @@
   @override
   void visitSuperMethodInvocation(SuperMethodInvocation node) {
     super.visitSuperMethodInvocation(node);
-    note(node.interfaceTargetReference!.node!, node.arguments, node);
+    note(node.interfaceTargetReference.node!, node.arguments, node);
   }
 
   @override
diff --git a/pkg/front_end/testcases/general/abstract_super_application.dart b/pkg/front_end/testcases/general/abstract_super_application.dart
new file mode 100644
index 0000000..f714955
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_super_application.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2022, 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 Super {
+  void method() {}
+  int property = 42;
+}
+
+mixin Mixin on Super {
+  void method() {
+    super.method();
+  }
+
+  int get property {
+    return super.property;
+  }
+
+  void set property(int value) {
+    super.property = value;
+  }
+}
+
+class Class1 extends Super with Mixin {}
+
+class Class2 with Mixin implements Super {}
diff --git a/pkg/front_end/testcases/general/abstract_super_application.dart.textual_outline.expect b/pkg/front_end/testcases/general/abstract_super_application.dart.textual_outline.expect
new file mode 100644
index 0000000..b04a16b
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_super_application.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class Super {
+  void method() {}
+  int property = 42;
+}
+
+mixin Mixin on Super {
+  void method() {}
+  int get property {}
+  void set property(int value) {}
+}
+
+class Class1 extends Super with Mixin {}
+
+class Class2 with Mixin implements Super {}
diff --git a/pkg/front_end/testcases/general/abstract_super_application.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/abstract_super_application.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..778e062
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_super_application.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class Class1 extends Super with Mixin {}
+
+class Class2 with Mixin implements Super {}
+
+class Super {
+  int property = 42;
+  void method() {}
+}
+
+mixin Mixin on Super {
+  int get property {}
+  void method() {}
+  void set property(int value) {}
+}
diff --git a/pkg/front_end/testcases/general/abstract_super_application.dart.weak.expect b/pkg/front_end/testcases/general/abstract_super_application.dart.weak.expect
new file mode 100644
index 0000000..c9780cd
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_super_application.dart.weak.expect
@@ -0,0 +1,64 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/abstract_super_application.dart:26:7: Error: 'Object' doesn't implement 'Super' so it can't be used with 'Mixin'.
+//  - 'Object' is from 'dart:core'.
+//  - 'Super' is from 'pkg/front_end/testcases/general/abstract_super_application.dart'.
+//  - 'Mixin' is from 'pkg/front_end/testcases/general/abstract_super_application.dart'.
+// class Class2 with Mixin implements Super {}
+//       ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Super extends core::Object {
+  field core::int property = 42;
+  synthetic constructor •() → self::Super
+    : super core::Object::•()
+    ;
+  method method() → void {}
+}
+abstract class Mixin extends self::Super /*isMixinDeclaration*/  {
+  method method() → void {
+    super.{self::Super::method}();
+  }
+  get property() → core::int {
+    return super.{self::Super::property};
+  }
+  set property(core::int value) → void {
+    super.{self::Super::property} = value;
+  }
+}
+abstract class _Class1&Super&Mixin = self::Super with self::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class1&Super&Mixin
+    : super self::Super::•()
+    ;
+  mixin-super-stub get property() → core::int
+    return super.{self::Mixin::property};
+  mixin-super-stub set property(core::int value) → void
+    return super.{self::Mixin::property} = value;
+  mixin-super-stub method method() → void
+    return super.{self::Mixin::method}();
+}
+class Class1 extends self::_Class1&Super&Mixin {
+  synthetic constructor •() → self::Class1
+    : super self::_Class1&Super&Mixin::•()
+    ;
+}
+abstract class _Class2&Object&Mixin = core::Object with self::Mixin /*isAnonymousMixin,hasConstConstructor*/  {
+  const synthetic constructor •() → self::_Class2&Object&Mixin
+    : super core::Object::•()
+    ;
+  mixin-super-stub get property() → core::int
+    return super.{self::Mixin::property};
+  mixin-super-stub set property(core::int value) → void
+    return super.{self::Mixin::property} = value;
+  mixin-super-stub method method() → void
+    return super.{self::Mixin::method}();
+}
+class Class2 extends self::_Class2&Object&Mixin implements self::Super {
+  synthetic constructor •() → self::Class2
+    : super self::_Class2&Object&Mixin::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/general/abstract_super_application.dart.weak.modular.expect b/pkg/front_end/testcases/general/abstract_super_application.dart.weak.modular.expect
new file mode 100644
index 0000000..c9780cd
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_super_application.dart.weak.modular.expect
@@ -0,0 +1,64 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/abstract_super_application.dart:26:7: Error: 'Object' doesn't implement 'Super' so it can't be used with 'Mixin'.
+//  - 'Object' is from 'dart:core'.
+//  - 'Super' is from 'pkg/front_end/testcases/general/abstract_super_application.dart'.
+//  - 'Mixin' is from 'pkg/front_end/testcases/general/abstract_super_application.dart'.
+// class Class2 with Mixin implements Super {}
+//       ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Super extends core::Object {
+  field core::int property = 42;
+  synthetic constructor •() → self::Super
+    : super core::Object::•()
+    ;
+  method method() → void {}
+}
+abstract class Mixin extends self::Super /*isMixinDeclaration*/  {
+  method method() → void {
+    super.{self::Super::method}();
+  }
+  get property() → core::int {
+    return super.{self::Super::property};
+  }
+  set property(core::int value) → void {
+    super.{self::Super::property} = value;
+  }
+}
+abstract class _Class1&Super&Mixin = self::Super with self::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class1&Super&Mixin
+    : super self::Super::•()
+    ;
+  mixin-super-stub get property() → core::int
+    return super.{self::Mixin::property};
+  mixin-super-stub set property(core::int value) → void
+    return super.{self::Mixin::property} = value;
+  mixin-super-stub method method() → void
+    return super.{self::Mixin::method}();
+}
+class Class1 extends self::_Class1&Super&Mixin {
+  synthetic constructor •() → self::Class1
+    : super self::_Class1&Super&Mixin::•()
+    ;
+}
+abstract class _Class2&Object&Mixin = core::Object with self::Mixin /*isAnonymousMixin,hasConstConstructor*/  {
+  const synthetic constructor •() → self::_Class2&Object&Mixin
+    : super core::Object::•()
+    ;
+  mixin-super-stub get property() → core::int
+    return super.{self::Mixin::property};
+  mixin-super-stub set property(core::int value) → void
+    return super.{self::Mixin::property} = value;
+  mixin-super-stub method method() → void
+    return super.{self::Mixin::method}();
+}
+class Class2 extends self::_Class2&Object&Mixin implements self::Super {
+  synthetic constructor •() → self::Class2
+    : super self::_Class2&Object&Mixin::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/general/abstract_super_application.dart.weak.outline.expect b/pkg/front_end/testcases/general/abstract_super_application.dart.weak.outline.expect
new file mode 100644
index 0000000..6caa0cc
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_super_application.dart.weak.outline.expect
@@ -0,0 +1,59 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/abstract_super_application.dart:26:7: Error: 'Object' doesn't implement 'Super' so it can't be used with 'Mixin'.
+//  - 'Object' is from 'dart:core'.
+//  - 'Super' is from 'pkg/front_end/testcases/general/abstract_super_application.dart'.
+//  - 'Mixin' is from 'pkg/front_end/testcases/general/abstract_super_application.dart'.
+// class Class2 with Mixin implements Super {}
+//       ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Super extends core::Object {
+  field core::int property;
+  synthetic constructor •() → self::Super
+    ;
+  method method() → void
+    ;
+}
+abstract class Mixin extends self::Super /*isMixinDeclaration*/  {
+  method method() → void
+    ;
+  get property() → core::int
+    ;
+  set property(core::int value) → void
+    ;
+}
+abstract class _Class1&Super&Mixin = self::Super with self::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class1&Super&Mixin
+    : super self::Super::•()
+    ;
+  mixin-super-stub get property() → core::int
+    return super.{self::Mixin::property};
+  mixin-super-stub set property(core::int value) → void
+    return super.{self::Mixin::property} = value;
+  mixin-super-stub method method() → void
+    return super.{self::Mixin::method}();
+}
+class Class1 extends self::_Class1&Super&Mixin {
+  synthetic constructor •() → self::Class1
+    ;
+}
+abstract class _Class2&Object&Mixin = core::Object with self::Mixin /*isAnonymousMixin,hasConstConstructor*/  {
+  const synthetic constructor •() → self::_Class2&Object&Mixin
+    : super core::Object::•()
+    ;
+  mixin-super-stub get property() → core::int
+    return super.{self::Mixin::property};
+  mixin-super-stub set property(core::int value) → void
+    return super.{self::Mixin::property} = value;
+  mixin-super-stub method method() → void
+    return super.{self::Mixin::method}();
+}
+class Class2 extends self::_Class2&Object&Mixin implements self::Super {
+  synthetic constructor •() → self::Class2
+    ;
+}
diff --git a/pkg/front_end/testcases/general/abstract_super_application.dart.weak.transformed.expect b/pkg/front_end/testcases/general/abstract_super_application.dart.weak.transformed.expect
new file mode 100644
index 0000000..5418053
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_super_application.dart.weak.transformed.expect
@@ -0,0 +1,70 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/abstract_super_application.dart:26:7: Error: 'Object' doesn't implement 'Super' so it can't be used with 'Mixin'.
+//  - 'Object' is from 'dart:core'.
+//  - 'Super' is from 'pkg/front_end/testcases/general/abstract_super_application.dart'.
+//  - 'Mixin' is from 'pkg/front_end/testcases/general/abstract_super_application.dart'.
+// class Class2 with Mixin implements Super {}
+//       ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Super extends core::Object {
+  field core::int property = 42;
+  synthetic constructor •() → self::Super
+    : super core::Object::•()
+    ;
+  method method() → void {}
+}
+abstract class Mixin extends self::Super /*isMixinDeclaration*/  {
+  method method() → void {
+    super.{self::Super::method}();
+  }
+  get property() → core::int {
+    return super.{self::Super::property};
+  }
+  set property(core::int value) → void {
+    super.{self::Super::property} = value;
+  }
+}
+abstract class _Class1&Super&Mixin extends self::Super implements self::Mixin /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class1&Super&Mixin
+    : super self::Super::•()
+    ;
+  get property() → core::int {
+    return super.{self::Super::property};
+  }
+  set property(core::int value) → void {
+    super.{self::Super::property} = value;
+  }
+  method method() → void {
+    super.{self::Super::method}();
+  }
+}
+class Class1 extends self::_Class1&Super&Mixin {
+  synthetic constructor •() → self::Class1
+    : super self::_Class1&Super&Mixin::•()
+    ;
+}
+abstract class _Class2&Object&Mixin extends core::Object implements self::Mixin /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/  {
+  const synthetic constructor •() → self::_Class2&Object&Mixin
+    : super core::Object::•()
+    ;
+  get property() → core::int {
+    return super.{self::Super::property};
+  }
+  set property(core::int value) → void {
+    super.{self::Super::property} = value;
+  }
+  method method() → void {
+    super.{self::Super::method}();
+  }
+}
+class Class2 extends self::_Class2&Object&Mixin implements self::Super {
+  synthetic constructor •() → self::Class2
+    : super self::_Class2&Object&Mixin::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/inference/unresolved_super.dart b/pkg/front_end/testcases/inference/unresolved_super.dart
index ef5108d..c8bbcea 100644
--- a/pkg/front_end/testcases/inference/unresolved_super.dart
+++ b/pkg/front_end/testcases/inference/unresolved_super.dart
@@ -13,7 +13,7 @@
     var /*@type=dynamic*/ v2 = super.bar;
     var /*@type=dynamic*/ v3 = super[0];
     var /*@type=dynamic*/ v4 = super.bar = /*@typeArgs=dynamic*/ f();*/
-    var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
+    var /*@type=invalid-type*/ v5 = super[0] = f();
   }
 }
 
diff --git a/pkg/front_end/testcases/inference/unresolved_super.dart.weak.expect b/pkg/front_end/testcases/inference/unresolved_super.dart.weak.expect
index e3758d3..cd24891 100644
--- a/pkg/front_end/testcases/inference/unresolved_super.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/unresolved_super.dart.weak.expect
@@ -2,9 +2,9 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
-//     var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
-//                                     ^
+// pkg/front_end/testcases/inference/unresolved_super.dart:16:42: Error: Superclass has no method named '[]='.
+//     var /*@type=invalid-type*/ v5 = super[0] = f();
+//                                          ^
 //
 import self as self;
 import "dart:core" as core;
@@ -14,9 +14,9 @@
     : super core::Object::•()
     ;
   method test() → void {
-    dynamic v5 = let final core::int* #t1 = 0 in let final dynamic #t2 = self::f<dynamic>() in let final void #t3 = invalid-expression "pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
-    var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
-                                    ^" in #t2;
+    invalid-type v5 = invalid-expression "pkg/front_end/testcases/inference/unresolved_super.dart:16:42: Error: Superclass has no method named '[]='.
+    var /*@type=invalid-type*/ v5 = super[0] = f();
+                                         ^";
   }
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
   abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
diff --git a/pkg/front_end/testcases/inference/unresolved_super.dart.weak.modular.expect b/pkg/front_end/testcases/inference/unresolved_super.dart.weak.modular.expect
index e3758d3..cd24891 100644
--- a/pkg/front_end/testcases/inference/unresolved_super.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/unresolved_super.dart.weak.modular.expect
@@ -2,9 +2,9 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
-//     var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
-//                                     ^
+// pkg/front_end/testcases/inference/unresolved_super.dart:16:42: Error: Superclass has no method named '[]='.
+//     var /*@type=invalid-type*/ v5 = super[0] = f();
+//                                          ^
 //
 import self as self;
 import "dart:core" as core;
@@ -14,9 +14,9 @@
     : super core::Object::•()
     ;
   method test() → void {
-    dynamic v5 = let final core::int* #t1 = 0 in let final dynamic #t2 = self::f<dynamic>() in let final void #t3 = invalid-expression "pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
-    var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
-                                    ^" in #t2;
+    invalid-type v5 = invalid-expression "pkg/front_end/testcases/inference/unresolved_super.dart:16:42: Error: Superclass has no method named '[]='.
+    var /*@type=invalid-type*/ v5 = super[0] = f();
+                                         ^";
   }
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
   abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
diff --git a/pkg/front_end/testcases/inference/unresolved_super.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/unresolved_super.dart.weak.transformed.expect
index e3758d3..cd24891 100644
--- a/pkg/front_end/testcases/inference/unresolved_super.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/unresolved_super.dart.weak.transformed.expect
@@ -2,9 +2,9 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
-//     var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
-//                                     ^
+// pkg/front_end/testcases/inference/unresolved_super.dart:16:42: Error: Superclass has no method named '[]='.
+//     var /*@type=invalid-type*/ v5 = super[0] = f();
+//                                          ^
 //
 import self as self;
 import "dart:core" as core;
@@ -14,9 +14,9 @@
     : super core::Object::•()
     ;
   method test() → void {
-    dynamic v5 = let final core::int* #t1 = 0 in let final dynamic #t2 = self::f<dynamic>() in let final void #t3 = invalid-expression "pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
-    var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
-                                    ^" in #t2;
+    invalid-type v5 = invalid-expression "pkg/front_end/testcases/inference/unresolved_super.dart:16:42: Error: Superclass has no method named '[]='.
+    var /*@type=invalid-type*/ v5 = super[0] = f();
+                                         ^";
   }
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
   abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.outline.expect
index e218902..ec6a7f6 100644
--- a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.outline.expect
@@ -28,19 +28,19 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:770:13 -> SymbolConstant(#then)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:770:13 -> SymbolConstant(#onError)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:814:13 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:814:13 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:814:13 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:865:13 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:865:13 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:865:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:909:13 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:909:13 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:909:13 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:763:13 -> SymbolConstant(#then)
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:763:13 -> SymbolConstant(#onError)
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:874:13 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:874:13 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:874:13 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:874:13 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 61, effectively constant: 15
diff --git a/pkg/front_end/testcases/rasta/unresolved_recovery.dart.weak.expect b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.weak.expect
index 69f78c4..254123f 100644
--- a/pkg/front_end/testcases/rasta/unresolved_recovery.dart.weak.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.weak.expect
@@ -6,10 +6,6 @@
 //     super[4] = 42;
 //          ^
 //
-// pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
-//     return super[2];
-//                 ^
-//
 // pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]'.
 //     super[4] += 5;
 //          ^
@@ -18,6 +14,10 @@
 //     super[4] += 5;
 //          ^
 //
+// pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
+//     return super[2];
+//                 ^
+//
 // pkg/front_end/testcases/rasta/unresolved_recovery.dart:20:3: Error: 'on' isn't a type.
 //   on Exception catch (e) { }
 //   ^^
@@ -54,7 +54,7 @@
     invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:7:10: Error: Superclass has no method named '[]='.
     super[4] = 42;
          ^";
-    let final core::int #t1 = 4 in invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]='.
+    invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]='.
     super[4] += 5;
          ^";
     return invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
diff --git a/pkg/front_end/testcases/rasta/unresolved_recovery.dart.weak.modular.expect b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.weak.modular.expect
index 69f78c4..254123f 100644
--- a/pkg/front_end/testcases/rasta/unresolved_recovery.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.weak.modular.expect
@@ -6,10 +6,6 @@
 //     super[4] = 42;
 //          ^
 //
-// pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
-//     return super[2];
-//                 ^
-//
 // pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]'.
 //     super[4] += 5;
 //          ^
@@ -18,6 +14,10 @@
 //     super[4] += 5;
 //          ^
 //
+// pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
+//     return super[2];
+//                 ^
+//
 // pkg/front_end/testcases/rasta/unresolved_recovery.dart:20:3: Error: 'on' isn't a type.
 //   on Exception catch (e) { }
 //   ^^
@@ -54,7 +54,7 @@
     invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:7:10: Error: Superclass has no method named '[]='.
     super[4] = 42;
          ^";
-    let final core::int #t1 = 4 in invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]='.
+    invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]='.
     super[4] += 5;
          ^";
     return invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
diff --git a/pkg/front_end/testcases/rasta/unresolved_recovery.dart.weak.transformed.expect b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.weak.transformed.expect
index 69f78c4..254123f 100644
--- a/pkg/front_end/testcases/rasta/unresolved_recovery.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.weak.transformed.expect
@@ -6,10 +6,6 @@
 //     super[4] = 42;
 //          ^
 //
-// pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
-//     return super[2];
-//                 ^
-//
 // pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]'.
 //     super[4] += 5;
 //          ^
@@ -18,6 +14,10 @@
 //     super[4] += 5;
 //          ^
 //
+// pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
+//     return super[2];
+//                 ^
+//
 // pkg/front_end/testcases/rasta/unresolved_recovery.dart:20:3: Error: 'on' isn't a type.
 //   on Exception catch (e) { }
 //   ^^
@@ -54,7 +54,7 @@
     invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:7:10: Error: Superclass has no method named '[]='.
     super[4] = 42;
          ^";
-    let final core::int #t1 = 4 in invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]='.
+    invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]='.
     super[4] += 5;
          ^";
     return invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index 8d76bd1..db38412 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -602,8 +602,8 @@
   Byte tag = 22;
   FileOffset fileOffset;
   Name name;
-  MemberReference interfaceTarget; // May be NullReference.
-  MemberReference interfaceTargetOrigin; // May be NullReference.
+  MemberReference interfaceTarget;
+  MemberReference interfaceTargetOrigin;
 }
 
 type AbstractSuperPropertySet extends Expression {
@@ -611,16 +611,16 @@
   FileOffset fileOffset;
   Name name;
   Expression value;
-  MemberReference interfaceTarget; // May be NullReference.
-  MemberReference interfaceTargetOrigin; // May be NullReference.
+  MemberReference interfaceTarget;
+  MemberReference interfaceTargetOrigin;
 }
 
 type SuperPropertyGet extends Expression {
   Byte tag = 24;
   FileOffset fileOffset;
   Name name;
-  MemberReference interfaceTarget; // May be NullReference.
-  MemberReference interfaceTargetOrigin; // May be NullReference.
+  MemberReference interfaceTarget;
+  MemberReference interfaceTargetOrigin;
 }
 
 type SuperPropertySet extends Expression {
@@ -628,8 +628,8 @@
   FileOffset fileOffset;
   Name name;
   Expression value;
-  MemberReference interfaceTarget; // May be NullReference.
-  MemberReference interfaceTargetOrigin; // May be NullReference.
+  MemberReference interfaceTarget;
+  MemberReference interfaceTargetOrigin;
 }
 
 /*
@@ -842,8 +842,8 @@
   FileOffset fileOffset;
   Name name;
   Arguments arguments;
-  MemberReference interfaceTarget; // May be NullReference.
-  MemberReference interfaceTargetOrigin; // May be NullReference.
+  MemberReference interfaceTarget;
+  MemberReference interfaceTargetOrigin;
 }
 
 type SuperMethodInvocation extends Expression {
@@ -851,8 +851,8 @@
   FileOffset fileOffset;
   Name name;
   Arguments arguments;
-  MemberReference interfaceTarget; // May be NullReference.
-  MemberReference interfaceTargetOrigin; // May be NullReference.
+  MemberReference interfaceTarget;
+  MemberReference interfaceTargetOrigin;
 }
 
 type StaticInvocation extends Expression {
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 0e63341..37c8e79 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -4827,28 +4827,23 @@
 class AbstractSuperPropertyGet extends Expression {
   Name name;
 
-  Reference? interfaceTargetReference;
+  Reference interfaceTargetReference;
 
-  AbstractSuperPropertyGet(Name name, [Member? interfaceTarget])
-      : this.byReference(name, getMemberReferenceGetter(interfaceTarget));
+  AbstractSuperPropertyGet(Name name, Member interfaceTarget)
+      : this.byReference(
+            name, getNonNullableMemberReferenceGetter(interfaceTarget));
 
   AbstractSuperPropertyGet.byReference(
       this.name, this.interfaceTargetReference);
 
-  Member? get interfaceTarget => interfaceTargetReference?.asMember;
+  Member get interfaceTarget => interfaceTargetReference.asMember;
 
-  void set interfaceTarget(Member? member) {
-    interfaceTargetReference = getMemberReferenceGetter(member);
+  void set interfaceTarget(Member member) {
+    interfaceTargetReference = getNonNullableMemberReferenceGetter(member);
   }
 
   @override
   DartType getStaticTypeInternal(StaticTypeContext context) {
-    Member? interfaceTarget = this.interfaceTarget;
-    if (interfaceTarget == null) {
-      // TODO(johnniwinther): SuperPropertyGet without a target should be
-      // replaced by invalid expressions.
-      return const DynamicType();
-    }
     Class declaringClass = interfaceTarget.enclosingClass!;
     if (declaringClass.typeParameters.isEmpty) {
       return interfaceTarget.getterType;
@@ -4869,7 +4864,7 @@
 
   @override
   void visitChildren(Visitor v) {
-    interfaceTarget?.acceptReference(v);
+    interfaceTarget.acceptReference(v);
     name.accept(v);
   }
 
@@ -4897,27 +4892,22 @@
 class SuperPropertyGet extends Expression {
   Name name;
 
-  Reference? interfaceTargetReference;
+  Reference interfaceTargetReference;
 
-  SuperPropertyGet(Name name, [Member? interfaceTarget])
-      : this.byReference(name, getMemberReferenceGetter(interfaceTarget));
+  SuperPropertyGet(Name name, Member interfaceTarget)
+      : this.byReference(
+            name, getNonNullableMemberReferenceGetter(interfaceTarget));
 
   SuperPropertyGet.byReference(this.name, this.interfaceTargetReference);
 
-  Member? get interfaceTarget => interfaceTargetReference?.asMember;
+  Member get interfaceTarget => interfaceTargetReference.asMember;
 
-  void set interfaceTarget(Member? member) {
-    interfaceTargetReference = getMemberReferenceGetter(member);
+  void set interfaceTarget(Member member) {
+    interfaceTargetReference = getNonNullableMemberReferenceGetter(member);
   }
 
   @override
   DartType getStaticTypeInternal(StaticTypeContext context) {
-    Member? interfaceTarget = this.interfaceTarget;
-    if (interfaceTarget == null) {
-      // TODO(johnniwinther): SuperPropertyGet without a target should be
-      // replaced by invalid expressions.
-      return const DynamicType();
-    }
     Class declaringClass = interfaceTarget.enclosingClass!;
     if (declaringClass.typeParameters.isEmpty) {
       return interfaceTarget.getterType;
@@ -4938,7 +4928,7 @@
 
   @override
   void visitChildren(Visitor v) {
-    interfaceTarget?.acceptReference(v);
+    interfaceTarget.acceptReference(v);
     name.accept(v);
   }
 
@@ -4990,21 +4980,21 @@
   Name name;
   Expression value;
 
-  Reference? interfaceTargetReference;
+  Reference interfaceTargetReference;
 
-  AbstractSuperPropertySet(Name name, Expression value, Member? interfaceTarget)
+  AbstractSuperPropertySet(Name name, Expression value, Member interfaceTarget)
       : this.byReference(
-            name, value, getMemberReferenceSetter(interfaceTarget));
+            name, value, getNonNullableMemberReferenceSetter(interfaceTarget));
 
   AbstractSuperPropertySet.byReference(
       this.name, this.value, this.interfaceTargetReference) {
     value.parent = this;
   }
 
-  Member? get interfaceTarget => interfaceTargetReference?.asMember;
+  Member get interfaceTarget => interfaceTargetReference.asMember;
 
-  void set interfaceTarget(Member? member) {
-    interfaceTargetReference = getMemberReferenceSetter(member);
+  void set interfaceTarget(Member member) {
+    interfaceTargetReference = getNonNullableMemberReferenceSetter(member);
   }
 
   @override
@@ -5020,7 +5010,7 @@
 
   @override
   void visitChildren(Visitor v) {
-    interfaceTarget?.acceptReference(v);
+    interfaceTarget.acceptReference(v);
     name.accept(v);
     value.accept(v);
   }
@@ -5066,21 +5056,21 @@
   Name name;
   Expression value;
 
-  Reference? interfaceTargetReference;
+  Reference interfaceTargetReference;
 
-  SuperPropertySet(Name name, Expression value, Member? interfaceTarget)
+  SuperPropertySet(Name name, Expression value, Member interfaceTarget)
       : this.byReference(
-            name, value, getMemberReferenceSetter(interfaceTarget));
+            name, value, getNonNullableMemberReferenceSetter(interfaceTarget));
 
   SuperPropertySet.byReference(
       this.name, this.value, this.interfaceTargetReference) {
     value.parent = this;
   }
 
-  Member? get interfaceTarget => interfaceTargetReference?.asMember;
+  Member get interfaceTarget => interfaceTargetReference.asMember;
 
-  void set interfaceTarget(Member? member) {
-    interfaceTargetReference = getMemberReferenceSetter(member);
+  void set interfaceTarget(Member member) {
+    interfaceTargetReference = getNonNullableMemberReferenceSetter(member);
   }
 
   @override
@@ -5096,7 +5086,7 @@
 
   @override
   void visitChildren(Visitor v) {
-    interfaceTarget?.acceptReference(v);
+    interfaceTarget.acceptReference(v);
     name.accept(v);
     value.accept(v);
   }
@@ -6406,32 +6396,30 @@
   @override
   Arguments arguments;
 
-  Reference? interfaceTargetReference;
+  Reference interfaceTargetReference;
 
-  AbstractSuperMethodInvocation(Name name, Arguments arguments,
-      [Procedure? interfaceTarget])
+  AbstractSuperMethodInvocation(
+      Name name, Arguments arguments, Procedure interfaceTarget)
       : this.byReference(
             name,
             arguments,
             // An invocation doesn't refer to the setter.
-            getMemberReferenceGetter(interfaceTarget));
+            getNonNullableMemberReferenceGetter(interfaceTarget));
 
   AbstractSuperMethodInvocation.byReference(
       this.name, this.arguments, this.interfaceTargetReference) {
     arguments.parent = this;
   }
 
-  Procedure? get interfaceTarget => interfaceTargetReference?.asProcedure;
+  Procedure get interfaceTarget => interfaceTargetReference.asProcedure;
 
-  void set interfaceTarget(Procedure? target) {
+  void set interfaceTarget(Procedure target) {
     // An invocation doesn't refer to the setter.
-    interfaceTargetReference = getMemberReferenceGetter(target);
+    interfaceTargetReference = getNonNullableMemberReferenceGetter(target);
   }
 
   @override
   DartType getStaticTypeInternal(StaticTypeContext context) {
-    Procedure? interfaceTarget = this.interfaceTarget;
-    if (interfaceTarget == null) return const DynamicType();
     Class superclass = interfaceTarget.enclosingClass!;
     List<DartType>? receiverTypeArguments = context.typeEnvironment
         .getTypeArgumentsAsInstanceOf(context.thisType!, superclass);
@@ -6453,7 +6441,7 @@
 
   @override
   void visitChildren(Visitor v) {
-    interfaceTarget?.acceptReference(v);
+    interfaceTarget.acceptReference(v);
     name.accept(v);
     arguments.accept(v);
   }
@@ -6499,32 +6487,30 @@
   @override
   Arguments arguments;
 
-  Reference? interfaceTargetReference;
+  Reference interfaceTargetReference;
 
-  SuperMethodInvocation(Name name, Arguments arguments,
-      [Procedure? interfaceTarget])
+  SuperMethodInvocation(
+      Name name, Arguments arguments, Procedure interfaceTarget)
       : this.byReference(
             name,
             arguments,
             // An invocation doesn't refer to the setter.
-            getMemberReferenceGetter(interfaceTarget));
+            getNonNullableMemberReferenceGetter(interfaceTarget));
 
   SuperMethodInvocation.byReference(
       this.name, this.arguments, this.interfaceTargetReference) {
     arguments.parent = this;
   }
 
-  Procedure? get interfaceTarget => interfaceTargetReference?.asProcedure;
+  Procedure get interfaceTarget => interfaceTargetReference.asProcedure;
 
-  void set interfaceTarget(Procedure? target) {
+  void set interfaceTarget(Procedure target) {
     // An invocation doesn't refer to the setter.
-    interfaceTargetReference = getMemberReferenceGetter(target);
+    interfaceTargetReference = getNonNullableMemberReferenceGetter(target);
   }
 
   @override
   DartType getStaticTypeInternal(StaticTypeContext context) {
-    Procedure? interfaceTarget = this.interfaceTarget;
-    if (interfaceTarget == null) return const DynamicType();
     Class superclass = interfaceTarget.enclosingClass!;
     List<DartType>? receiverTypeArguments = context.typeEnvironment
         .getTypeArgumentsAsInstanceOf(context.thisType!, superclass);
@@ -6545,7 +6531,7 @@
 
   @override
   void visitChildren(Visitor v) {
-    interfaceTarget?.acceptReference(v);
+    interfaceTarget.acceptReference(v);
     name.accept(v);
     arguments.accept(v);
   }
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 756b1b9..cc22844 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -2219,7 +2219,7 @@
     int offset = readOffset();
     addTransformerFlag(TransformerFlag.superCalls);
     return new AbstractSuperPropertyGet.byReference(
-        readName(), readNullableInstanceMemberReference())
+        readName(), readNonNullInstanceMemberReference())
       ..fileOffset = offset;
   }
 
@@ -2227,7 +2227,7 @@
     int offset = readOffset();
     addTransformerFlag(TransformerFlag.superCalls);
     return new AbstractSuperPropertySet.byReference(
-        readName(), readExpression(), readNullableInstanceMemberReference())
+        readName(), readExpression(), readNonNullInstanceMemberReference())
       ..fileOffset = offset;
   }
 
@@ -2235,7 +2235,7 @@
     int offset = readOffset();
     addTransformerFlag(TransformerFlag.superCalls);
     return new SuperPropertyGet.byReference(
-        readName(), readNullableInstanceMemberReference())
+        readName(), readNonNullInstanceMemberReference())
       ..fileOffset = offset;
   }
 
@@ -2243,7 +2243,7 @@
     int offset = readOffset();
     addTransformerFlag(TransformerFlag.superCalls);
     return new SuperPropertySet.byReference(
-        readName(), readExpression(), readNullableInstanceMemberReference())
+        readName(), readExpression(), readNonNullInstanceMemberReference())
       ..fileOffset = offset;
   }
 
@@ -2373,7 +2373,7 @@
     int offset = readOffset();
     addTransformerFlag(TransformerFlag.superCalls);
     return new AbstractSuperMethodInvocation.byReference(
-        readName(), readArguments(), readNullableInstanceMemberReference())
+        readName(), readArguments(), readNonNullInstanceMemberReference())
       ..fileOffset = offset;
   }
 
@@ -2381,7 +2381,7 @@
     int offset = readOffset();
     addTransformerFlag(TransformerFlag.superCalls);
     return new SuperMethodInvocation.byReference(
-        readName(), readArguments(), readNullableInstanceMemberReference())
+        readName(), readArguments(), readNonNullInstanceMemberReference())
       ..fileOffset = offset;
   }
 
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 4d8d015..781c8ba 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -1634,7 +1634,7 @@
     writeByte(Tag.AbstractSuperPropertyGet);
     writeOffset(node.fileOffset);
     writeName(node.name);
-    writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
+    writeNonNullInstanceMemberReference(node.interfaceTargetReference);
   }
 
   @override
@@ -1643,7 +1643,7 @@
     writeOffset(node.fileOffset);
     writeName(node.name);
     writeNode(node.value);
-    writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
+    writeNonNullInstanceMemberReference(node.interfaceTargetReference);
   }
 
   @override
@@ -1651,7 +1651,7 @@
     writeByte(Tag.SuperPropertyGet);
     writeOffset(node.fileOffset);
     writeName(node.name);
-    writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
+    writeNonNullInstanceMemberReference(node.interfaceTargetReference);
   }
 
   @override
@@ -1660,7 +1660,7 @@
     writeOffset(node.fileOffset);
     writeName(node.name);
     writeNode(node.value);
-    writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
+    writeNonNullInstanceMemberReference(node.interfaceTargetReference);
   }
 
   @override
@@ -1791,7 +1791,7 @@
     writeOffset(node.fileOffset);
     writeName(node.name);
     writeArgumentsNode(node.arguments);
-    writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
+    writeNonNullInstanceMemberReference(node.interfaceTargetReference);
   }
 
   @override
@@ -1800,7 +1800,7 @@
     writeOffset(node.fileOffset);
     writeName(node.name);
     writeArgumentsNode(node.arguments);
-    writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
+    writeNonNullInstanceMemberReference(node.interfaceTargetReference);
   }
 
   @override
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
index 22e011b..d8f5c67b 100644
--- a/pkg/kernel/lib/clone.dart
+++ b/pkg/kernel/lib/clone.dart
@@ -1060,8 +1060,10 @@
   SuperMethodInvocation visitSuperMethodInvocation(SuperMethodInvocation node) {
     SuperMethodInvocation cloned =
         super.visitSuperMethodInvocation(node) as SuperMethodInvocation;
-    cloned.interfaceTarget =
-        _findSuperMember(node.name, isSetter: false) as Procedure?;
+    cloned.interfaceTarget = _findSuperMember(node.name, isSetter: false)
+            as Procedure? ??
+        // TODO(johnniwinther): Remove this when an error is reported instead.
+        cloned.interfaceTarget;
     return cloned;
   }
 
@@ -1069,7 +1071,9 @@
   SuperPropertyGet visitSuperPropertyGet(SuperPropertyGet node) {
     SuperPropertyGet cloned =
         super.visitSuperPropertyGet(node) as SuperPropertyGet;
-    cloned.interfaceTarget = _findSuperMember(node.name, isSetter: false);
+    cloned.interfaceTarget = _findSuperMember(node.name, isSetter: false) ??
+        // TODO(johnniwinther): Remove this when an error is reported instead.
+        cloned.interfaceTarget;
     return cloned;
   }
 
@@ -1077,7 +1081,9 @@
   SuperPropertySet visitSuperPropertySet(SuperPropertySet node) {
     SuperPropertySet cloned =
         super.visitSuperPropertySet(node) as SuperPropertySet;
-    cloned.interfaceTarget = _findSuperMember(node.name, isSetter: true);
+    cloned.interfaceTarget = _findSuperMember(node.name, isSetter: true) ??
+        // TODO(johnniwinther): Remove this when an error is reported instead.
+        cloned.interfaceTarget;
     return cloned;
   }
 }
diff --git a/pkg/kernel/lib/src/node_creator.dart b/pkg/kernel/lib/src/node_creator.dart
index d51a1bb..51fc5d4 100644
--- a/pkg/kernel/lib/src/node_creator.dart
+++ b/pkg/kernel/lib/src/node_creator.dart
@@ -861,7 +861,8 @@
         return StringLiteral('foo');
       case ExpressionKind.AbstractSuperMethodInvocation:
         return _createOneOf(_pendingExpressions, kind, index, [
-          () => AbstractSuperMethodInvocation(_createName(), _createArguments())
+          () => AbstractSuperMethodInvocation(
+              _createName(), _createArguments(), _needProcedure())
             ..fileOffset = _needFileOffset(),
           () => AbstractSuperMethodInvocation(
               _createName(), _createArguments(), _needProcedure())
@@ -869,7 +870,8 @@
         ]);
       case ExpressionKind.SuperMethodInvocation:
         return _createOneOf(_pendingExpressions, kind, index, [
-          () => SuperMethodInvocation(_createName(), _createArguments())
+          () => SuperMethodInvocation(
+              _createName(), _createArguments(), _needProcedure())
             ..fileOffset = _needFileOffset(),
           () => SuperMethodInvocation(
               _createName(), _createArguments(), _needProcedure())
@@ -877,29 +879,31 @@
         ]);
       case ExpressionKind.AbstractSuperPropertyGet:
         return _createOneOf(_pendingExpressions, kind, index, [
-          () => AbstractSuperPropertyGet(_createName())
+          () => AbstractSuperPropertyGet(_createName(), _needProcedure())
             ..fileOffset = _needFileOffset(),
           () => AbstractSuperPropertyGet(_createName(), _needField())
             ..fileOffset = _needFileOffset(),
         ]);
       case ExpressionKind.AbstractSuperPropertySet:
         return _createOneOf(_pendingExpressions, kind, index, [
-          () =>
-              AbstractSuperPropertySet(_createName(), _createExpression(), null)
-                ..fileOffset = _needFileOffset(),
+          () => AbstractSuperPropertySet(
+              _createName(), _createExpression(), _needProcedure())
+            ..fileOffset = _needFileOffset(),
           () => AbstractSuperPropertySet(
               _createName(), _createExpression(), _needField())
             ..fileOffset = _needFileOffset(),
         ]);
       case ExpressionKind.SuperPropertyGet:
         return _createOneOf(_pendingExpressions, kind, index, [
-          () => SuperPropertyGet(_createName())..fileOffset = _needFileOffset(),
+          () => SuperPropertyGet(_createName(), _needProcedure())
+            ..fileOffset = _needFileOffset(),
           () => SuperPropertyGet(_createName(), _needField())
             ..fileOffset = _needFileOffset(),
         ]);
       case ExpressionKind.SuperPropertySet:
         return _createOneOf(_pendingExpressions, kind, index, [
-          () => SuperPropertySet(_createName(), _createExpression(), null)
+          () => SuperPropertySet(
+              _createName(), _createExpression(), _needProcedure())
             ..fileOffset = _needFileOffset(),
           () =>
               SuperPropertySet(_createName(), _createExpression(), _needField())
diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart
index 6e44499..38dec89 100644
--- a/pkg/kernel/lib/type_checker.dart
+++ b/pkg/kernel/lib/type_checker.dart
@@ -755,77 +755,49 @@
   @override
   DartType visitAbstractSuperMethodInvocation(
       AbstractSuperMethodInvocation node) {
-    Member? target = node.interfaceTarget;
-    if (target == null) {
-      checkUnresolvedInvocation(currentThisType!, node);
-      return handleDynamicCall(currentThisType!, node.arguments);
-    } else {
-      return handleCall(node.arguments, target.superGetterType,
-          receiver: getSuperReceiverType(target));
-    }
+    Member target = node.interfaceTarget;
+    return handleCall(node.arguments, target.superGetterType,
+        receiver: getSuperReceiverType(target));
   }
 
   @override
   DartType visitSuperMethodInvocation(SuperMethodInvocation node) {
-    Member? target = node.interfaceTarget;
-    if (target == null) {
-      checkUnresolvedInvocation(currentThisType!, node);
-      return handleDynamicCall(currentThisType!, node.arguments);
-    } else {
-      return handleCall(node.arguments, target.superGetterType,
-          receiver: getSuperReceiverType(target));
-    }
+    Member target = node.interfaceTarget;
+    return handleCall(node.arguments, target.superGetterType,
+        receiver: getSuperReceiverType(target));
   }
 
   @override
   DartType visitAbstractSuperPropertyGet(AbstractSuperPropertyGet node) {
-    Member? target = node.interfaceTarget;
-    if (target == null) {
-      checkUnresolvedInvocation(currentThisType!, node);
-      return const DynamicType();
-    } else {
-      Substitution receiver = getSuperReceiverType(target);
-      return receiver.substituteType(target.superGetterType);
-    }
+    Member target = node.interfaceTarget;
+    Substitution receiver = getSuperReceiverType(target);
+    return receiver.substituteType(target.superGetterType);
   }
 
   @override
   DartType visitAbstractSuperPropertySet(AbstractSuperPropertySet node) {
-    Member? target = node.interfaceTarget;
+    Member target = node.interfaceTarget;
     DartType value = visitExpression(node.value);
-    if (target != null) {
-      Substitution receiver = getSuperReceiverType(target);
-      checkAssignable(node.value, value,
-          receiver.substituteType(target.superSetterType, contravariant: true));
-    } else {
-      checkUnresolvedInvocation(currentThisType!, node);
-    }
+    Substitution receiver = getSuperReceiverType(target);
+    checkAssignable(node.value, value,
+        receiver.substituteType(target.superSetterType, contravariant: true));
     return value;
   }
 
   @override
   DartType visitSuperPropertyGet(SuperPropertyGet node) {
-    Member? target = node.interfaceTarget;
-    if (target == null) {
-      checkUnresolvedInvocation(currentThisType!, node);
-      return const DynamicType();
-    } else {
-      Substitution receiver = getSuperReceiverType(target);
-      return receiver.substituteType(target.superGetterType);
-    }
+    Member target = node.interfaceTarget;
+    Substitution receiver = getSuperReceiverType(target);
+    return receiver.substituteType(target.superGetterType);
   }
 
   @override
   DartType visitSuperPropertySet(SuperPropertySet node) {
-    Member? target = node.interfaceTarget;
+    Member target = node.interfaceTarget;
     DartType value = visitExpression(node.value);
-    if (target != null) {
-      Substitution receiver = getSuperReceiverType(target);
-      checkAssignable(node.value, value,
-          receiver.substituteType(target.superSetterType, contravariant: true));
-    } else {
-      checkUnresolvedInvocation(currentThisType!, node);
-    }
+    Substitution receiver = getSuperReceiverType(target);
+    checkAssignable(node.value, value,
+        receiver.substituteType(target.superSetterType, contravariant: true));
     return value;
   }
 
diff --git a/pkg/vm/lib/transformations/mixin_deduplication.dart b/pkg/vm/lib/transformations/mixin_deduplication.dart
index 61f008b..6ea5178 100644
--- a/pkg/vm/lib/transformations/mixin_deduplication.dart
+++ b/pkg/vm/lib/transformations/mixin_deduplication.dart
@@ -196,20 +196,20 @@
 
   @override
   visitSuperPropertyGet(SuperPropertyGet node) {
-    node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
+    node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget)!;
     super.visitSuperPropertyGet(node);
   }
 
   @override
   visitSuperPropertySet(SuperPropertySet node) {
-    node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
+    node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget)!;
     super.visitSuperPropertySet(node);
   }
 
   @override
   visitSuperMethodInvocation(SuperMethodInvocation node) {
     node.interfaceTarget =
-        _resolveNewInterfaceTarget(node.interfaceTarget) as Procedure?;
+        _resolveNewInterfaceTarget(node.interfaceTarget) as Procedure;
     super.visitSuperMethodInvocation(node);
   }
 
diff --git a/pkg/vm/lib/transformations/to_string_transformer.dart b/pkg/vm/lib/transformations/to_string_transformer.dart
index 824282d..bf16900 100644
--- a/pkg/vm/lib/transformations/to_string_transformer.dart
+++ b/pkg/vm/lib/transformations/to_string_transformer.dart
@@ -75,11 +75,21 @@
         _isInTargetPackage(node) &&
         !_hasKeepAnnotation(node) &&
         !_hasInheritedKeepAnnotation(node.enclosingClass!)) {
+      Procedure findSuperMethod(Class cls) {
+        for (Procedure procedure in cls.procedures) {
+          if (procedure.name.text == 'toString' && !procedure.isAbstract) {
+            return procedure;
+          }
+        }
+        return findSuperMethod(cls.superclass!);
+      }
+
       node.function.body!.replaceWith(
         ReturnStatement(
           SuperMethodInvocation(
             node.name,
             Arguments(<Expression>[]),
+            findSuperMethod(node.enclosingClass!.superclass!),
           ),
         ),
       );
diff --git a/pkg/vm/lib/transformations/type_flow/signature_shaking.dart b/pkg/vm/lib/transformations/type_flow/signature_shaking.dart
index b4d7687..a23bf58 100644
--- a/pkg/vm/lib/transformations/type_flow/signature_shaking.dart
+++ b/pkg/vm/lib/transformations/type_flow/signature_shaking.dart
@@ -309,10 +309,7 @@
 
   @override
   void visitSuperMethodInvocation(SuperMethodInvocation node) {
-    final interfaceTarget = node.interfaceTarget;
-    if (interfaceTarget != null) {
-      collectCall(interfaceTarget, node.arguments);
-    }
+    collectCall(node.interfaceTarget, node.arguments);
     super.visitSuperMethodInvocation(node);
   }
 
@@ -649,10 +646,7 @@
   @override
   void visitSuperMethodInvocation(SuperMethodInvocation node) {
     super.visitSuperMethodInvocation(node);
-    final interfaceTarget = node.interfaceTarget;
-    if (interfaceTarget != null) {
-      transformCall(interfaceTarget, node, null, node.arguments);
-    }
+    transformCall(node.interfaceTarget, node, null, node.arguments);
   }
 
   @override
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 0b3a78c..bae97d9 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -1348,10 +1348,8 @@
       return _makeUnreachableCall(_flattenArguments(node.arguments));
     } else {
       node.interfaceTarget = fieldMorpher
-          .adjustInstanceCallTarget(node.interfaceTarget) as Procedure?;
-      if (node.interfaceTarget != null) {
-        shaker.addUsedMember(node.interfaceTarget!);
-      }
+          .adjustInstanceCallTarget(node.interfaceTarget) as Procedure;
+      shaker.addUsedMember(node.interfaceTarget);
       return node;
     }
   }
@@ -1364,10 +1362,8 @@
       return _makeUnreachableCall([]);
     } else {
       node.interfaceTarget =
-          fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
-      if (node.interfaceTarget != null) {
-        shaker.addUsedMember(node.interfaceTarget!);
-      }
+          fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget)!;
+      shaker.addUsedMember(node.interfaceTarget);
       return node;
     }
   }
@@ -1380,10 +1376,8 @@
       return _makeUnreachableCall([node.value]);
     } else {
       node.interfaceTarget = fieldMorpher
-          .adjustInstanceCallTarget(node.interfaceTarget, isSetter: true);
-      if (node.interfaceTarget != null) {
-        shaker.addUsedMember(node.interfaceTarget!);
-      }
+          .adjustInstanceCallTarget(node.interfaceTarget, isSetter: true)!;
+      shaker.addUsedMember(node.interfaceTarget);
       return node;
     }
   }
diff --git a/pkg/vm/testcases/transformations/to_string_transformer/transformed.expect b/pkg/vm/testcases/transformations/to_string_transformer/transformed.expect
index d48dc28..010e2fe 100644
--- a/pkg/vm/testcases/transformations/to_string_transformer/transformed.expect
+++ b/pkg/vm/testcases/transformations/to_string_transformer/transformed.expect
@@ -17,7 +17,7 @@
     ;
   @#C1
   method toString() → core::String
-    return super.toString();
+    return super.{core::Object::toString}();
 }
 class FooEnum extends core::_Enum /*isEnum*/  {
   static const field core::List<self::FooEnum> values = #C11;
diff --git a/runtime/tests/vm/dart/causal_stacks/utils.dart b/runtime/tests/vm/dart/causal_stacks/utils.dart
index 4356953..2269e31 100644
--- a/runtime/tests/vm/dart/causal_stacks/utils.dart
+++ b/runtime/tests/vm/dart/causal_stacks/utils.dart
@@ -205,26 +205,21 @@
 
   // Use the DWARF stack decoder if we're running in --dwarf-stack-traces mode
   // and in precompiled mode (otherwise --dwarf-stack-traces has no effect).
-  bool usingDwarf = false;
-  if (debugInfoFilename != null) {
-    try {
-      final dwarf = Dwarf.fromFile(debugInfoFilename)!;
-      usingDwarf = true;
-      frames = await Stream.fromIterable(original)
-          .transform(DwarfStackTraceDecoder(dwarf))
-          .where(_lineRE.hasMatch)
-          .toList();
-    } on FileSystemException {
-      // We're not running in precompiled mode, so the file doesn't exist and
-      // we can continue normally.
-    }
+  final decodeTrace = frames.first.startsWith('Warning:');
+  if (decodeTrace) {
+    Expect.isNotNull(debugInfoFilename);
+    final dwarf = Dwarf.fromFile(debugInfoFilename!)!;
+    frames = await Stream.fromIterable(original)
+        .transform(DwarfStackTraceDecoder(dwarf))
+        .where(_lineRE.hasMatch)
+        .toList();
   }
 
   void printFrameInformation() {
     print('RegExps for expected stack:');
     expects.forEach((s) => print('"${s}"'));
     print('');
-    if (usingDwarf) {
+    if (decodeTrace) {
       print('Non-symbolic actual stack:');
       original.forEach(print);
       print('');
diff --git a/runtime/tests/vm/dart_2/causal_stacks/utils.dart b/runtime/tests/vm/dart_2/causal_stacks/utils.dart
index ec673b5..d7c80d1 100644
--- a/runtime/tests/vm/dart_2/causal_stacks/utils.dart
+++ b/runtime/tests/vm/dart_2/causal_stacks/utils.dart
@@ -207,26 +207,21 @@
 
   // Use the DWARF stack decoder if we're running in --dwarf-stack-traces mode
   // and in precompiled mode (otherwise --dwarf-stack-traces has no effect).
-  bool usingDwarf = false;
-  if (debugInfoFilename != null) {
-    try {
-      final dwarf = Dwarf.fromFile(debugInfoFilename);
-      usingDwarf = true;
-      frames = await Stream.fromIterable(original)
-          .transform(DwarfStackTraceDecoder(dwarf))
-          .where(_lineRE.hasMatch)
-          .toList();
-    } on FileSystemException {
-      // We're not running in precompiled mode, so the file doesn't exist and
-      // we can continue normally.
-    }
+  final decodeTrace = frames.first.startsWith('Warning:');
+  if (decodeTrace) {
+    Expect.isNotNull(debugInfoFilename);
+    final dwarf = Dwarf.fromFile(debugInfoFilename);
+    frames = await Stream.fromIterable(original)
+        .transform(DwarfStackTraceDecoder(dwarf))
+        .where(_lineRE.hasMatch)
+        .toList();
   }
 
   void printFrameInformation() {
     print('RegExps for expected stack:');
     expects.forEach((s) => print('"${s}"'));
     print('');
-    if (usingDwarf) {
+    if (decodeTrace) {
       print('Non-symbolic actual stack:');
       original.forEach(print);
       print('');
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 84694a6..d20cf54 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -1739,6 +1739,13 @@
   // how the vm_tag (kEmbedderTagId) can be set, these tags need to
   // move to the OSThread structure.
   set_user_tag(UserTags::kDefaultUserTag);
+
+  if (group()->obfuscate()) {
+    OS::PrintErr(
+        "Warning: This VM has been configured to obfuscate symbol information "
+        "which violates the Dart standard.\n"
+        "         See dartbug.com/30524 for more information.\n");
+  }
 }
 
 #undef REUSABLE_HANDLE_SCOPE_INIT
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 8814320..47633fe 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -25878,6 +25878,12 @@
         isolate_instructions_image.instructions_relocated_address();
     auto const vm_relocated_address =
         vm_instructions_image.instructions_relocated_address();
+    // The Dart standard requires the output of StackTrace.toString to include
+    // all pending activations with precise source locations (i.e., to expand
+    // inlined frames and provide line and column numbers).
+    buffer.Printf(
+        "Warning: This VM has been configured to produce stack traces "
+        "that violate the Dart standard.\n");
     // This prologue imitates Android's debuggerd to make it possible to paste
     // the stack trace into ndk-stack.
     buffer.Printf(
diff --git a/sdk/lib/async/async.dart b/sdk/lib/async/async.dart
index ca05fc6..bd41381 100644
--- a/sdk/lib/async/async.dart
+++ b/sdk/lib/async/async.dart
@@ -110,7 +110,6 @@
         checkNotNullable,
         EmptyIterator,
         IterableElementError,
-        nullFuture,
         printToZone,
         printToConsole,
         Since,
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index f83386d..908e5e1 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -223,13 +223,6 @@
 /// it's very clearly documented.
 @pragma("wasm:entry-point")
 abstract class Future<T> {
-  /// A `Future<Null>` completed with `null`.
-  ///
-  /// Currently shared with `dart:internal`.
-  /// If that future can be removed, then change this back to
-  /// `_Future<Null>.zoneValue(null, _rootZone);`
-  static final _Future<Null> _nullFuture = nullFuture as _Future<Null>;
-
   /// A `Future<bool>` completed with `false`.
   static final _Future<bool> _falseFuture =
       new _Future<bool>.zoneValue(false, _rootZone);
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 038c3bb..117465c 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -515,7 +515,7 @@
       controller
         ..onCancel = () {
           timer.cancel();
-          return Future._nullFuture;
+          return Zone._current._nullFuture;
         }
         ..onPause = () {
           watch.stop();
diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart
index 2baf008..1f34d76 100644
--- a/sdk/lib/async/stream_controller.dart
+++ b/sdk/lib/async/stream_controller.dart
@@ -588,7 +588,10 @@
   Future<void> get done => _ensureDoneFuture();
 
   Future<void> _ensureDoneFuture() =>
-      _doneFuture ??= _isCanceled ? Future._nullFuture : _Future<void>();
+      _doneFuture ??
+      (_isCanceled
+          ? Zone._current._nullFuture as Future<void>
+          : _doneFuture = _Future<void>());
 
   /// Send or enqueue a data event.
   void add(T value) {
@@ -919,7 +922,7 @@
     var cancel = addSubscription.cancel();
     if (cancel == null) {
       addStreamFuture._asyncComplete(null);
-      return Future._nullFuture;
+      return Zone._current._nullFuture;
     }
     return cancel.whenComplete(() {
       addStreamFuture._asyncComplete(null);
diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart
index b4fb5d8..b5a40cb 100644
--- a/sdk/lib/async/stream_impl.dart
+++ b/sdk/lib/async/stream_impl.dart
@@ -197,7 +197,7 @@
     if (!_isCanceled) {
       _cancel();
     }
-    return _cancelFuture ?? Future._nullFuture;
+    return _cancelFuture ?? Zone._current._nullFuture;
   }
 
   Future<E> asFuture<E>([E? futureValue]) {
@@ -217,7 +217,7 @@
     };
     _onError = (Object error, StackTrace stackTrace) {
       Future cancelFuture = cancel();
-      if (!identical(cancelFuture, Future._nullFuture)) {
+      if (!identical(Zone._current._nullFuture, cancelFuture)) {
         cancelFuture.whenComplete(() {
           result._completeError(error, stackTrace);
         });
@@ -297,7 +297,7 @@
   // Hooks called when the input is paused, unpaused or canceled.
   // These must not throw. If overwritten to call user code, include suitable
   // try/catch wrapping and send any errors to
-  // [_Zone.current.handleUncaughtError].
+  // [Zone._current.handleUncaughtError].
   void _onPause() {
     assert(_isInputPaused);
   }
@@ -352,7 +352,6 @@
       // future to finish we must not report the error.
       if (_isCanceled && !_waitsForCancel) return;
       _state |= _STATE_IN_CALLBACK;
-      // TODO(floitsch): this dynamic should be 'void'.
       var onError = _onError;
       if (onError is void Function(Object, StackTrace)) {
         _zone.runBinaryGuarded<Object, StackTrace>(onError, error, stackTrace);
@@ -367,7 +366,7 @@
       _cancel();
       var cancelFuture = _cancelFuture;
       if (cancelFuture != null &&
-          !identical(cancelFuture, Future._nullFuture)) {
+          !identical(Zone._current._nullFuture, cancelFuture)) {
         cancelFuture.whenComplete(sendError);
       } else {
         sendError();
@@ -396,7 +395,8 @@
     _cancel();
     _state |= _STATE_WAIT_FOR_CANCEL;
     var cancelFuture = _cancelFuture;
-    if (cancelFuture != null && !identical(cancelFuture, Future._nullFuture)) {
+    if (cancelFuture != null &&
+        !identical(Zone._current._nullFuture, cancelFuture)) {
       cancelFuture.whenComplete(sendDone);
     } else {
       sendDone();
@@ -672,7 +672,7 @@
     }
   }
 
-  Future cancel() => Future._nullFuture;
+  Future cancel() => Zone._current._nullFuture;
 
   Future<E> asFuture<E>([E? futureValue]) {
     E resultValue;
@@ -819,7 +819,7 @@
 
   Future cancel() {
     _stream._cancelSubscription();
-    return Future._nullFuture;
+    return Zone._current._nullFuture;
   }
 
   bool get isPaused {
@@ -963,7 +963,7 @@
       }
       return subscription.cancel();
     }
-    return Future._nullFuture;
+    return Zone._current._nullFuture;
   }
 
   void _onData(T data) {
diff --git a/sdk/lib/async/stream_pipe.dart b/sdk/lib/async/stream_pipe.dart
index cd707be..2caa84b 100644
--- a/sdk/lib/async/stream_pipe.dart
+++ b/sdk/lib/async/stream_pipe.dart
@@ -26,7 +26,8 @@
 void _cancelAndError(StreamSubscription subscription, _Future future,
     Object error, StackTrace stackTrace) {
   var cancelFuture = subscription.cancel();
-  if (cancelFuture != null && !identical(cancelFuture, Future._nullFuture)) {
+  if (cancelFuture != null &&
+      !identical(Zone._current._nullFuture, cancelFuture)) {
     cancelFuture.whenComplete(() => future._completeError(error, stackTrace));
   } else {
     future._completeError(error, stackTrace);
@@ -55,7 +56,8 @@
   before completing with a value. */
 void _cancelAndValue(StreamSubscription subscription, _Future future, value) {
   var cancelFuture = subscription.cancel();
-  if (cancelFuture != null && !identical(cancelFuture, Future._nullFuture)) {
+  if (cancelFuture != null &&
+      !identical(Zone._current._nullFuture, cancelFuture)) {
     cancelFuture.whenComplete(() => future._complete(value));
   } else {
     future._complete(value);
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index b9bcd19..42e0c76 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -1078,6 +1078,28 @@
           implZone, e, identical(error, e) ? stackTrace : s);
     }
   }
+
+  /// A reusable `null`-valued future per zone used by `dart:async`.
+  ///
+  /// **DO NOT USE.**
+  ///
+  /// This future is used in situations where a future is expected,
+  /// but no asynchronous computation actually happens,
+  /// like cancelling a stream from a controller with no `onCancel` callback.
+  /// *Some code depends on recognizing this future in order to react
+  /// synchronously.*
+  /// It does so to avoid changing event interleaving during the null safety
+  /// migration where, for example, the [StreamSubscription.cancel] method
+  /// stopped being able to return `null`.
+  /// The code that would be broken by such a timing change is fragile,
+  /// but we are not able to simply change it.
+  /// For better or worse, code depends on the precise timing
+  /// that our libraries have so far exhibited.
+  ///
+  /// This future will be removed again if we can ever do so.
+  /// Do not use it for anything other than preserving timing
+  /// during the null safety migration.
+  _Future<Null> get _nullFuture;
 }
 
 class _CustomZone extends _Zone {
@@ -1105,6 +1127,9 @@
   /// The parent zone.
   final _Zone parent;
 
+  /// Cached value for [_nullFuture];
+  _Future<Null>? _nullFutureCache;
+
   /// The zone's scoped value declaration map.
   ///
   /// This is always a [HashMap].
@@ -1196,6 +1221,18 @@
   /// parent's error-zone.
   Zone get errorZone => _handleUncaughtError.zone;
 
+  _Future<Null> get _nullFuture {
+    _Future<Null>? result = _nullFutureCache;
+    if (result != null) return result;
+    // We only care about the zone of the null future
+    // because of the zone it schedules microtasks in.
+    var microtaskZone = _scheduleMicrotask.zone;
+    if (!identical(microtaskZone, this)) {
+      return _nullFutureCache = microtaskZone._nullFuture;
+    }
+    return _nullFutureCache = _Future<Null>.value(null);
+  }
+
   void runGuarded(void f()) {
     try {
       run(f);
@@ -1509,6 +1546,8 @@
 }
 
 class _RootZone extends _Zone {
+  static final _nullFutureCache = _Future<Null>.zoneValue(null, _rootZone);
+
   const _RootZone();
 
   _ZoneFunction<RunHandler> get _run =>
@@ -1547,6 +1586,8 @@
   // The parent zone.
   _Zone? get parent => null;
 
+  _Future<Null> get _nullFuture => _nullFutureCache;
+
   /// The zone's scoped value declaration map.
   ///
   /// This is always a [HashMap].
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 671f68a..91224f6 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -37302,13 +37302,13 @@
   }
 
   Future cancel() {
-    if (_canceled) return nullFuture;
-
-    _unlisten();
-    // Clear out the target to indicate this is complete.
-    _target = null;
-    _onData = null;
-    return nullFuture;
+    if (!_canceled) {
+      _unlisten();
+      // Clear out the target to indicate this is complete.
+      _target = null;
+      _onData = null;
+    }
+    return Future<void>.value(null);
   }
 
   bool get _canceled => _target == null;
diff --git a/sdk/lib/internal/internal.dart b/sdk/lib/internal/internal.dart
index ff3d890..0353c71 100644
--- a/sdk/lib/internal/internal.dart
+++ b/sdk/lib/internal/internal.dart
@@ -136,27 +136,7 @@
   return digit1 * 16 + digit2 - (digit2 & 256);
 }
 
-/// A reusable `null`-valued future used by `dart:async`.
-///
-/// **DO NOT USE.**
-///
-/// This future is used in situations where a future is expected,
-/// but no asynchronous computation actually happens,
-/// like cancelling a stream from a controller with no `onCancel` callback.
-/// *Some code depends on recognizing this future in order to react
-/// synchronously.*
-/// It does so to avoid changing event interleaving during the null safety
-/// migration where, for example, the [StreamSubscription.cancel] method
-/// stopped being able to return `null`.
-/// The code that would be broken by such a timing change is fragile,
-/// but we are not able to simply change it.
-/// For better or worse, code depends on the precise timing that our libraries
-/// have so far exhibited.
-///
-/// This future will be removed again if we can ever do so.
-/// Do not use it for anything other than preserving timing
-/// during the null safety migration.
-final Future<Null> nullFuture = Zone.root.run(() => Future<Null>.value(null));
+final Expando<Future<Null>> _nullFutures = Expando<Future<Null>>();
 
 /// A default hash function used by the platform in various places.
 ///
diff --git a/tests/lib/async/null_future_zone_test.dart b/tests/lib/async/null_future_zone_test.dart
index 9a266be..34201e7 100644
--- a/tests/lib/async/null_future_zone_test.dart
+++ b/tests/lib/async/null_future_zone_test.dart
@@ -13,21 +13,32 @@
     Expect.isFalse(await it.moveNext());
 
     late Future nullFuture;
+
+    bool nullFutureZoneUsed = false;
+    runZoned(() {
+      nullFuture = (new StreamController()..stream.listen(null).cancel()).done;
+    }, zoneSpecification: new ZoneSpecification(scheduleMicrotask:
+        (Zone self, ZoneDelegate parent, Zone zone, void f()) {
+      Expect.identical(zone, self);
+      nullFutureZoneUsed = true;
+      parent.scheduleMicrotask(zone, f);
+    }));
+
+    nullFuture.then((value) {
+      Expect.isNull(value);
+      Expect.isTrue(nullFutureZoneUsed);
+      asyncEnd();
+    });
+
     late Future falseFuture;
 
     runZoned(() {
-      nullFuture = (new StreamController()..stream.listen(null).cancel()).done;
       falseFuture = it.moveNext();
     }, zoneSpecification: new ZoneSpecification(scheduleMicrotask:
         (Zone self, ZoneDelegate parent, Zone zone, void f()) {
       Expect.fail("Should not be called");
     }));
 
-    nullFuture.then((value) {
-      Expect.isNull(value);
-      asyncEnd();
-    });
-
     falseFuture.then((value) {
       Expect.isFalse(value);
       asyncEnd();
diff --git a/tests/lib_2/async/null_future_zone_test.dart b/tests/lib_2/async/null_future_zone_test.dart
index 3322916..77cb1b7 100644
--- a/tests/lib_2/async/null_future_zone_test.dart
+++ b/tests/lib_2/async/null_future_zone_test.dart
@@ -15,21 +15,32 @@
     Expect.isFalse(await it.moveNext());
 
     Future nullFuture;
+
+    bool nullFutureZoneUsed = false;
+    runZoned(() {
+      nullFuture = (new StreamController()..stream.listen(null).cancel()).done;
+    }, zoneSpecification: new ZoneSpecification(scheduleMicrotask:
+        (Zone self, ZoneDelegate parent, Zone zone, void f()) {
+      Expect.identical(zone, self);
+      nullFutureZoneUsed = true;
+      parent.scheduleMicrotask(zone, f);
+    }));
+
+    nullFuture.then((value) {
+      Expect.isNull(value);
+      Expect.isTrue(nullFutureZoneUsed);
+      asyncEnd();
+    });
+
     Future falseFuture;
 
     runZoned(() {
-      nullFuture = (new StreamController()..stream.listen(null).cancel()).done;
       falseFuture = it.moveNext();
     }, zoneSpecification: new ZoneSpecification(scheduleMicrotask:
         (Zone self, ZoneDelegate parent, Zone zone, void f()) {
       Expect.fail("Should not be called");
     }));
 
-    nullFuture.then((value) {
-      Expect.isNull(value);
-      asyncEnd();
-    });
-
     falseFuture.then((value) {
       Expect.isFalse(value);
       asyncEnd();
diff --git a/tools/VERSION b/tools/VERSION
index 45f4e4d..157fc8a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 18
 PATCH 0
-PRERELEASE 222
+PRERELEASE 223
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/dom/src/EventStreamProvider.dart b/tools/dom/src/EventStreamProvider.dart
index 90b19aa..1ae6268 100644
--- a/tools/dom/src/EventStreamProvider.dart
+++ b/tools/dom/src/EventStreamProvider.dart
@@ -248,13 +248,13 @@
   }
 
   Future cancel() {
-    if (_canceled) return nullFuture;
-
-    _unlisten();
-    // Clear out the target to indicate this is complete.
-    _target = null;
-    _onData = null;
-    return nullFuture;
+    if (!_canceled) {
+      _unlisten();
+      // Clear out the target to indicate this is complete.
+      _target = null;
+      _onData = null;
+    }
+    return Future<void>.value(null);
   }
 
   bool get _canceled => _target == null;