Version 2.15.0-152.0.dev

Merge commit 'bb1640eec2db34c1da83a9d962a27bc9088fa251' into 'dev'
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index 118aac8..301bfab 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -160,8 +160,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        labels.hashCode,
+        file,
+        labels,
       );
 }
 
@@ -234,8 +234,8 @@
 
   @override
   int get hashCode => Object.hash(
-        error.hashCode,
-        fixes.hashCode,
+        error,
+        fixes,
       );
 }
 
@@ -315,8 +315,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        errors.hashCode,
+        file,
+        errors,
       );
 }
 
@@ -459,8 +459,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        regions.hashCode,
+        file,
+        regions,
       );
 }
 
@@ -664,8 +664,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
+        file,
+        offset,
       );
 }
 
@@ -826,9 +826,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        length.hashCode,
+        file,
+        offset,
+        length,
       );
 }
 
@@ -1019,8 +1019,8 @@
 
   @override
   int get hashCode => Object.hash(
-        libraries.hashCode,
-        packageMap.hashCode,
+        libraries,
+        packageMap,
       );
 }
 
@@ -1110,9 +1110,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        length.hashCode,
+        file,
+        offset,
+        length,
       );
 }
 
@@ -1217,9 +1217,9 @@
 
   @override
   int get hashCode => Object.hash(
-        files.hashCode,
-        targets.hashCode,
-        regions.hashCode,
+        files,
+        targets,
+        regions,
       );
 }
 
@@ -1432,8 +1432,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
+        file,
+        offset,
       );
 }
 
@@ -1536,9 +1536,9 @@
 
   @override
   int get hashCode => Object.hash(
-        name.hashCode,
-        parameters.hashCode,
-        dartdoc.hashCode,
+        name,
+        parameters,
+        dartdoc,
       );
 }
 
@@ -1622,8 +1622,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        regions.hashCode,
+        file,
+        regions,
       );
 }
 
@@ -1722,9 +1722,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        classes.hashCode,
-        members.hashCode,
+        file,
+        classes,
+        members,
       );
 }
 
@@ -1824,10 +1824,10 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        length.hashCode,
-        delta.hashCode,
+        file,
+        offset,
+        length,
+        delta,
       );
 }
 
@@ -1946,10 +1946,10 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        regions.hashCode,
-        targets.hashCode,
-        files.hashCode,
+        file,
+        regions,
+        targets,
+        files,
       );
 }
 
@@ -2030,8 +2030,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        occurrences.hashCode,
+        file,
+        occurrences,
       );
 }
 
@@ -2216,14 +2216,14 @@
 
   @override
   int get hashCode => Object.hash(
-        enableAsync.hashCode,
-        enableDeferredLoading.hashCode,
-        enableEnums.hashCode,
-        enableNullAwareOperators.hashCode,
-        enableSuperMixins.hashCode,
-        generateDart2jsHints.hashCode,
-        generateHints.hashCode,
-        generateLints.hashCode,
+        enableAsync,
+        enableDeferredLoading,
+        enableEnums,
+        enableNullAwareOperators,
+        enableSuperMixins,
+        generateDart2jsHints,
+        generateHints,
+        generateLints,
       );
 }
 
@@ -2329,10 +2329,10 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        kind.hashCode,
-        libraryName.hashCode,
-        outline.hashCode,
+        file,
+        kind,
+        libraryName,
+        outline,
       );
 }
 
@@ -2412,8 +2412,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        overrides.hashCode,
+        file,
+        overrides,
       );
 }
 
@@ -2667,9 +2667,9 @@
 
   @override
   int get hashCode => Object.hash(
-        included.hashCode,
-        excluded.hashCode,
-        packageRoots.hashCode,
+        included,
+        excluded,
+        packageRoots,
       );
 }
 
@@ -3039,8 +3039,8 @@
 
   @override
   int get hashCode => Object.hash(
-        isAnalyzing.hashCode,
-        analysisTarget.hashCode,
+        isAnalyzing,
+        analysisTarget,
       );
 }
 
@@ -3586,8 +3586,8 @@
 
   @override
   int get hashCode => Object.hash(
-        event.hashCode,
-        millis.hashCode,
+        event,
+        millis,
       );
 }
 
@@ -3806,15 +3806,15 @@
 
   @override
   int get hashCode => Object.hash(
-        label.hashCode,
-        declaringLibraryUri.hashCode,
-        element.hashCode,
-        defaultArgumentListString.hashCode,
-        defaultArgumentListTextRanges.hashCode,
-        parameterNames.hashCode,
-        parameterTypes.hashCode,
-        relevanceTags.hashCode,
-        requiredParameterCount.hashCode,
+        label,
+        declaringLibraryUri,
+        element,
+        defaultArgumentListString,
+        defaultArgumentListTextRanges,
+        parameterNames,
+        parameterTypes,
+        relevanceTags,
+        requiredParameterCount,
       );
 }
 
@@ -3896,9 +3896,9 @@
 
   @override
   int get hashCode => Object.hash(
-        id.hashCode,
-        uri.hashCode,
-        items.hashCode,
+        id,
+        uri,
+        items,
       );
 }
 
@@ -3969,8 +3969,8 @@
 
   @override
   int get hashCode => Object.hash(
-        path.hashCode,
-        fixes.hashCode,
+        path,
+        fixes,
       );
 }
 
@@ -4036,8 +4036,8 @@
 
   @override
   int get hashCode => Object.hash(
-        code.hashCode,
-        occurrences.hashCode,
+        code,
+        occurrences,
       );
 }
 
@@ -4115,9 +4115,9 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
-        label.hashCode,
+        offset,
+        length,
+        label,
       );
 }
 
@@ -4210,8 +4210,8 @@
 
   @override
   int get hashCode => Object.hash(
-        changedLibraries.hashCode,
-        removedLibraries.hashCode,
+        changedLibraries,
+        removedLibraries,
       );
 }
 
@@ -4287,8 +4287,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        imports.hashCode,
+        file,
+        imports,
       );
 }
 
@@ -4391,10 +4391,10 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        id.hashCode,
-        label.hashCode,
-        offset.hashCode,
+        file,
+        id,
+        label,
+        offset,
       );
 }
 
@@ -4476,8 +4476,8 @@
 
   @override
   int get hashCode => Object.hash(
-        completion.hashCode,
-        change.hashCode,
+        completion,
+        change,
       );
 }
 
@@ -4552,8 +4552,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
+        file,
+        offset,
       );
 }
 
@@ -4946,15 +4946,15 @@
 
   @override
   int get hashCode => Object.hash(
-        id.hashCode,
-        replacementOffset.hashCode,
-        replacementLength.hashCode,
-        results.hashCode,
-        isLast.hashCode,
-        libraryFile.hashCode,
-        includedSuggestionSets.hashCode,
-        includedElementKinds.hashCode,
-        includedSuggestionRelevanceTags.hashCode,
+        id,
+        replacementOffset,
+        replacementLength,
+        results,
+        isLast,
+        libraryFile,
+        includedSuggestionSets,
+        includedElementKinds,
+        includedSuggestionRelevanceTags,
       );
 }
 
@@ -5210,11 +5210,11 @@
 
   @override
   int get hashCode => Object.hash(
-        name.hashCode,
-        explicitFileCount.hashCode,
-        implicitFileCount.hashCode,
-        workItemQueueLength.hashCode,
-        cacheEntryExceptions.hashCode,
+        name,
+        explicitFileCount,
+        implicitFileCount,
+        workItemQueueLength,
+        cacheEntryExceptions,
       );
 }
 
@@ -5555,8 +5555,8 @@
 
   @override
   int get hashCode => Object.hash(
-        included.hashCode,
-        inTestMode.hashCode,
+        included,
+        inTestMode,
       );
 }
 
@@ -5643,8 +5643,8 @@
 
   @override
   int get hashCode => Object.hash(
-        edits.hashCode,
-        details.hashCode,
+        edits,
+        details,
       );
 }
 
@@ -5749,10 +5749,10 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        selectionOffset.hashCode,
-        selectionLength.hashCode,
-        lineLength.hashCode,
+        file,
+        selectionOffset,
+        selectionLength,
+        lineLength,
       );
 }
 
@@ -5849,9 +5849,9 @@
 
   @override
   int get hashCode => Object.hash(
-        edits.hashCode,
-        selectionOffset.hashCode,
-        selectionLength.hashCode,
+        edits,
+        selectionOffset,
+        selectionLength,
       );
 }
 
@@ -5938,9 +5938,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        length.hashCode,
+        file,
+        offset,
+        length,
       );
 }
 
@@ -6097,9 +6097,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        length.hashCode,
+        file,
+        offset,
+        length,
       );
 }
 
@@ -6243,8 +6243,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
+        file,
+        offset,
       );
 }
 
@@ -6400,9 +6400,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        key.hashCode,
-        offset.hashCode,
+        file,
+        key,
+        offset,
       );
 }
 
@@ -6604,12 +6604,12 @@
 
   @override
   int get hashCode => Object.hash(
-        kind.hashCode,
-        file.hashCode,
-        offset.hashCode,
-        length.hashCode,
-        validateOnly.hashCode,
-        options.hashCode,
+        kind,
+        file,
+        offset,
+        length,
+        validateOnly,
+        options,
       );
 }
 
@@ -6784,12 +6784,12 @@
 
   @override
   int get hashCode => Object.hash(
-        initialProblems.hashCode,
-        optionsProblems.hashCode,
-        finalProblems.hashCode,
-        feedback.hashCode,
-        change.hashCode,
-        potentialEdits.hashCode,
+        initialProblems,
+        optionsProblems,
+        finalProblems,
+        feedback,
+        change,
+        potentialEdits,
       );
 }
 
@@ -6864,8 +6864,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
+        file,
+        offset,
       );
 }
 
@@ -6945,8 +6945,8 @@
 
   @override
   int get hashCode => Object.hash(
-        change.hashCode,
-        whitespaceOnly.hashCode,
+        change,
+        whitespaceOnly,
       );
 }
 
@@ -7043,9 +7043,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        elements.hashCode,
-        offset.hashCode,
+        file,
+        elements,
+        offset,
       );
 }
 
@@ -7202,9 +7202,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        key.hashCode,
-        offset.hashCode,
+        file,
+        key,
+        offset,
       );
 }
 
@@ -7814,17 +7814,17 @@
 
   @override
   int get hashCode => Object.hash(
-        name.hashCode,
-        kind.hashCode,
-        fileIndex.hashCode,
-        offset.hashCode,
-        line.hashCode,
-        column.hashCode,
-        codeOffset.hashCode,
-        codeLength.hashCode,
-        className.hashCode,
-        mixinName.hashCode,
-        parameters.hashCode,
+        name,
+        kind,
+        fileIndex,
+        offset,
+        line,
+        column,
+        codeOffset,
+        codeLength,
+        className,
+        mixinName,
+        parameters,
       );
 }
 
@@ -7889,8 +7889,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        kind.hashCode,
+        file,
+        kind,
       );
 }
 
@@ -8335,12 +8335,12 @@
 
   @override
   int get hashCode => Object.hash(
-        code.hashCode,
-        offset.hashCode,
-        contextFile.hashCode,
-        contextOffset.hashCode,
-        variables.hashCode,
-        expressions.hashCode,
+        code,
+        offset,
+        contextFile,
+        contextOffset,
+        variables,
+        expressions,
       );
 }
 
@@ -8449,8 +8449,8 @@
 
   @override
   int get hashCode => Object.hash(
-        suggestions.hashCode,
-        expressions.hashCode,
+        suggestions,
+        expressions,
       );
 }
 
@@ -8546,9 +8546,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        kind.hashCode,
-        referencedFiles.hashCode,
+        file,
+        kind,
+        referencedFiles,
       );
 }
 
@@ -8635,9 +8635,9 @@
 
   @override
   int get hashCode => Object.hash(
-        id.hashCode,
-        file.hashCode,
-        uri.hashCode,
+        id,
+        file,
+        uri,
       );
 }
 
@@ -8717,8 +8717,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        uri.hashCode,
+        file,
+        uri,
       );
 }
 
@@ -8921,8 +8921,8 @@
 
   @override
   int get hashCode => Object.hash(
-        uri.hashCode,
-        elements.hashCode,
+        uri,
+        elements,
       );
 }
 
@@ -8994,8 +8994,8 @@
 
   @override
   int get hashCode => Object.hash(
-        elements.hashCode,
-        imports.hashCode,
+        elements,
+        imports,
       );
 }
 
@@ -9119,11 +9119,11 @@
 
   @override
   int get hashCode => Object.hash(
-        coveringExpressionOffsets.hashCode,
-        coveringExpressionLengths.hashCode,
-        names.hashCode,
-        offsets.hashCode,
-        lengths.hashCode,
+        coveringExpressionOffsets,
+        coveringExpressionLengths,
+        names,
+        offsets,
+        lengths,
       );
 }
 
@@ -9198,8 +9198,8 @@
 
   @override
   int get hashCode => Object.hash(
-        name.hashCode,
-        extractAll.hashCode,
+        name,
+        extractAll,
       );
 }
 
@@ -9361,14 +9361,14 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
-        returnType.hashCode,
-        names.hashCode,
-        canCreateGetter.hashCode,
-        parameters.hashCode,
-        offsets.hashCode,
-        lengths.hashCode,
+        offset,
+        length,
+        returnType,
+        names,
+        canCreateGetter,
+        parameters,
+        offsets,
+        lengths,
       );
 }
 
@@ -9503,11 +9503,11 @@
 
   @override
   int get hashCode => Object.hash(
-        returnType.hashCode,
-        createGetter.hashCode,
-        name.hashCode,
-        parameters.hashCode,
-        extractAll.hashCode,
+        returnType,
+        createGetter,
+        name,
+        parameters,
+        extractAll,
       );
 }
 
@@ -9728,8 +9728,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
+        file,
+        offset,
       );
 }
 
@@ -10045,18 +10045,18 @@
 
   @override
   int get hashCode => Object.hash(
-        kind.hashCode,
-        offset.hashCode,
-        length.hashCode,
-        codeOffset.hashCode,
-        codeLength.hashCode,
-        label.hashCode,
-        dartElement.hashCode,
-        attributes.hashCode,
-        className.hashCode,
-        parentAssociationLabel.hashCode,
-        variableName.hashCode,
-        children.hashCode,
+        kind,
+        offset,
+        length,
+        codeOffset,
+        codeLength,
+        label,
+        dartElement,
+        attributes,
+        className,
+        parentAssociationLabel,
+        variableName,
+        children,
       );
 }
 
@@ -10209,13 +10209,13 @@
 
   @override
   int get hashCode => Object.hash(
-        name.hashCode,
-        label.hashCode,
-        literalValueBoolean.hashCode,
-        literalValueInteger.hashCode,
-        literalValueString.hashCode,
-        nameLocation.hashCode,
-        valueLocation.hashCode,
+        name,
+        label,
+        literalValueBoolean,
+        literalValueInteger,
+        literalValueString,
+        nameLocation,
+        valueLocation,
       );
 }
 
@@ -10377,8 +10377,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        outline.hashCode,
+        file,
+        outline,
       );
 }
 
@@ -10608,8 +10608,8 @@
 
   @override
   int get hashCode => Object.hash(
-        id.hashCode,
-        value.hashCode,
+        id,
+        value,
       );
 }
 
@@ -10867,15 +10867,15 @@
 
   @override
   int get hashCode => Object.hash(
-        documentation.hashCode,
-        expression.hashCode,
-        id.hashCode,
-        isRequired.hashCode,
-        isSafeToUpdate.hashCode,
-        name.hashCode,
-        children.hashCode,
-        editor.hashCode,
-        value.hashCode,
+        documentation,
+        expression,
+        id,
+        isRequired,
+        isSafeToUpdate,
+        name,
+        children,
+        editor,
+        value,
       );
 }
 
@@ -10952,8 +10952,8 @@
 
   @override
   int get hashCode => Object.hash(
-        kind.hashCode,
-        enumItems.hashCode,
+        kind,
+        enumItems,
       );
 }
 
@@ -11178,12 +11178,12 @@
 
   @override
   int get hashCode => Object.hash(
-        boolValue.hashCode,
-        doubleValue.hashCode,
-        intValue.hashCode,
-        stringValue.hashCode,
-        enumValue.hashCode,
-        expression.hashCode,
+        boolValue,
+        doubleValue,
+        intValue,
+        stringValue,
+        enumValue,
+        expression,
       );
 }
 
@@ -11284,10 +11284,10 @@
 
   @override
   int get hashCode => Object.hash(
-        libraryUri.hashCode,
-        className.hashCode,
-        name.hashCode,
-        documentation.hashCode,
+        libraryUri,
+        className,
+        name,
+        documentation,
       );
 }
 
@@ -11580,18 +11580,18 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
-        containingLibraryPath.hashCode,
-        containingLibraryName.hashCode,
-        containingClassDescription.hashCode,
-        dartdoc.hashCode,
-        elementDescription.hashCode,
-        elementKind.hashCode,
-        isDeprecated.hashCode,
-        parameter.hashCode,
-        propagatedType.hashCode,
-        staticType.hashCode,
+        offset,
+        length,
+        containingLibraryPath,
+        containingLibraryName,
+        containingClassDescription,
+        dartdoc,
+        elementDescription,
+        elementKind,
+        isDeprecated,
+        parameter,
+        propagatedType,
+        staticType,
       );
 }
 
@@ -11655,8 +11655,8 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
+        offset,
+        length,
       );
 }
 
@@ -11720,8 +11720,8 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
+        offset,
+        length,
       );
 }
 
@@ -11802,9 +11802,9 @@
 
   @override
   int get hashCode => Object.hash(
-        strings.hashCode,
-        uris.hashCode,
-        names.hashCode,
+        strings,
+        uris,
+        names,
       );
 }
 
@@ -11883,9 +11883,9 @@
 
   @override
   int get hashCode => Object.hash(
-        path.hashCode,
-        prefix.hashCode,
-        elements.hashCode,
+        path,
+        prefix,
+        elements,
       );
 }
 
@@ -11953,8 +11953,8 @@
 
   @override
   int get hashCode => Object.hash(
-        tag.hashCode,
-        relevanceBoost.hashCode,
+        tag,
+        relevanceBoost,
       );
 }
 
@@ -12042,9 +12042,9 @@
 
   @override
   int get hashCode => Object.hash(
-        id.hashCode,
-        relevance.hashCode,
-        displayUri.hashCode,
+        id,
+        relevance,
+        displayUri,
       );
 }
 
@@ -12110,8 +12110,8 @@
 
   @override
   int get hashCode => Object.hash(
-        name.hashCode,
-        occurrences.hashCode,
+        name,
+        occurrences,
       );
 }
 
@@ -12212,9 +12212,9 @@
 
   @override
   int get hashCode => Object.hash(
-        className.hashCode,
-        methodName.hashCode,
-        isDeclaration.hashCode,
+        className,
+        methodName,
+        isDeclaration,
       );
 }
 
@@ -12288,8 +12288,8 @@
 
   @override
   int get hashCode => Object.hash(
-        deleteSource.hashCode,
-        inlineAll.hashCode,
+        deleteSource,
+        inlineAll,
       );
 }
 
@@ -12440,8 +12440,8 @@
 
   @override
   int get hashCode => Object.hash(
-        entries.hashCode,
-        files.hashCode,
+        entries,
+        files,
       );
 }
 
@@ -12511,8 +12511,8 @@
 
   @override
   int get hashCode => Object.hash(
-        scope.hashCode,
-        libraryPaths.hashCode,
+        scope,
+        libraryPaths,
       );
 }
 
@@ -12652,8 +12652,8 @@
 
   @override
   int get hashCode => Object.hash(
-        element.hashCode,
-        className.hashCode,
+        element,
+        className,
       );
 }
 
@@ -12759,10 +12759,10 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
-        superclassMember.hashCode,
-        interfaceMembers.hashCode,
+        offset,
+        length,
+        superclassMember,
+        interfaceMembers,
       );
 }
 
@@ -12839,9 +12839,9 @@
 
   @override
   int get hashCode => Object.hash(
-        name.hashCode,
-        key.hashCode,
-        example.hashCode,
+        name,
+        key,
+        example,
       );
 }
 
@@ -13058,10 +13058,10 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
-        elementKindName.hashCode,
-        oldName.hashCode,
+        offset,
+        length,
+        elementKindName,
+        oldName,
       );
 }
 
@@ -13201,9 +13201,9 @@
 
   @override
   int get hashCode => Object.hash(
-        code.hashCode,
-        message.hashCode,
-        stackTrace.hashCode,
+        code,
+        message,
+        stackTrace,
       );
 }
 
@@ -13633,9 +13633,9 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
-        type.hashCode,
+        offset,
+        length,
+        type,
       );
 }
 
@@ -13817,13 +13817,13 @@
 
   @override
   int get hashCode => Object.hash(
-        libraryPath.hashCode,
-        kind.hashCode,
-        name.hashCode,
-        typeArguments.hashCode,
-        returnType.hashCode,
-        parameterTypes.hashCode,
-        parameterNames.hashCode,
+        libraryPath,
+        kind,
+        name,
+        typeArguments,
+        returnType,
+        parameterTypes,
+        parameterNames,
       );
 }
 
@@ -13949,8 +13949,8 @@
 
   @override
   int get hashCode => Object.hash(
-        name.hashCode,
-        type.hashCode,
+        name,
+        type,
       );
 }
 
@@ -14042,9 +14042,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        includePotential.hashCode,
+        file,
+        offset,
+        includePotential,
       );
 }
 
@@ -14130,8 +14130,8 @@
 
   @override
   int get hashCode => Object.hash(
-        id.hashCode,
-        element.hashCode,
+        id,
+        element,
       );
 }
 
@@ -14609,9 +14609,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        pattern.hashCode,
-        maxResults.hashCode,
+        file,
+        pattern,
+        maxResults,
       );
 }
 
@@ -14696,8 +14696,8 @@
 
   @override
   int get hashCode => Object.hash(
-        declarations.hashCode,
-        files.hashCode,
+        declarations,
+        files,
       );
 }
 
@@ -14789,9 +14789,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        superOnly.hashCode,
+        file,
+        offset,
+        superOnly,
       );
 }
 
@@ -14972,10 +14972,10 @@
 
   @override
   int get hashCode => Object.hash(
-        location.hashCode,
-        kind.hashCode,
-        isPotential.hashCode,
-        path.hashCode,
+        location,
+        kind,
+        isPotential,
+        path,
       );
 }
 
@@ -15158,9 +15158,9 @@
 
   @override
   int get hashCode => Object.hash(
-        id.hashCode,
-        results.hashCode,
-        isLast.hashCode,
+        id,
+        results,
+        isLast,
       );
 }
 
@@ -15234,8 +15234,8 @@
 
   @override
   int get hashCode => Object.hash(
-        version.hashCode,
-        pid.hashCode,
+        version,
+        pid,
       );
 }
 
@@ -15326,9 +15326,9 @@
 
   @override
   int get hashCode => Object.hash(
-        isFatal.hashCode,
-        message.hashCode,
-        stackTrace.hashCode,
+        isFatal,
+        message,
+        stackTrace,
       );
 }
 
@@ -15495,9 +15495,9 @@
 
   @override
   int get hashCode => Object.hash(
-        time.hashCode,
-        kind.hashCode,
-        data.hashCode,
+        time,
+        kind,
+        data,
       );
 }
 
@@ -15914,8 +15914,8 @@
 
   @override
   int get hashCode => Object.hash(
-        analysis.hashCode,
-        pub.hashCode,
+        analysis,
+        pub,
       );
 }
 
@@ -16077,12 +16077,12 @@
 
   @override
   int get hashCode => Object.hash(
-        classElement.hashCode,
-        displayName.hashCode,
-        memberElement.hashCode,
-        superclass.hashCode,
-        interfaces.hashCode,
-        mixins.hashCode,
-        subclasses.hashCode,
+        classElement,
+        displayName,
+        memberElement,
+        superclass,
+        interfaces,
+        mixins,
+        subclasses,
       );
 }
diff --git a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
index c3c4f3c..0339409 100644
--- a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
+++ b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
@@ -647,14 +647,15 @@
           if (field.value != null) {
             return field.value.hashCode.toString();
           } else {
-            return '${field.name}.hashCode';
+            return field.name;
           }
         }).toList();
 
         if (items.isEmpty) {
           writeln('0');
         } else if (items.length == 1) {
-          writeln(items.single);
+          write(items.single);
+          write('.hashCode');
         } else {
           writeln('Object.hash(');
           for (var field in items) {
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart
index 96c6d1b..4289f41 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart
@@ -67,7 +67,7 @@
   @override
   int get hashCode => Object.hash(
         704418402,
-        content.hashCode,
+        content,
       );
 }
 
@@ -250,15 +250,15 @@
 
   @override
   int get hashCode => Object.hash(
-        severity.hashCode,
-        type.hashCode,
-        location.hashCode,
-        message.hashCode,
-        correction.hashCode,
-        code.hashCode,
-        url.hashCode,
-        contextMessages.hashCode,
-        hasFix.hashCode,
+        severity,
+        type,
+        location,
+        message,
+        correction,
+        code,
+        url,
+        contextMessages,
+        hasFix,
       );
 }
 
@@ -474,7 +474,7 @@
   @override
   int get hashCode => Object.hash(
         873118866,
-        edits.hashCode,
+        edits,
       );
 }
 
@@ -912,29 +912,29 @@
 
   @override
   int get hashCode => Object.hashAll([
-        kind.hashCode,
-        relevance.hashCode,
-        completion.hashCode,
-        displayText.hashCode,
-        replacementOffset.hashCode,
-        replacementLength.hashCode,
-        selectionOffset.hashCode,
-        selectionLength.hashCode,
-        isDeprecated.hashCode,
-        isPotential.hashCode,
-        docSummary.hashCode,
-        docComplete.hashCode,
-        declaringType.hashCode,
-        defaultArgumentListString.hashCode,
-        defaultArgumentListTextRanges.hashCode,
-        element.hashCode,
-        returnType.hashCode,
-        parameterNames.hashCode,
-        parameterTypes.hashCode,
-        requiredParameterCount.hashCode,
-        hasNamedParameters.hashCode,
-        parameterName.hashCode,
-        parameterType.hashCode,
+        kind,
+        relevance,
+        completion,
+        displayText,
+        replacementOffset,
+        replacementLength,
+        selectionOffset,
+        selectionLength,
+        isDeprecated,
+        isPotential,
+        docSummary,
+        docComplete,
+        declaringType,
+        defaultArgumentListString,
+        defaultArgumentListTextRanges,
+        element,
+        returnType,
+        parameterNames,
+        parameterTypes,
+        requiredParameterCount,
+        hasNamedParameters,
+        parameterName,
+        parameterType,
       ]);
 }
 
@@ -1131,8 +1131,8 @@
 
   @override
   int get hashCode => Object.hash(
-        message.hashCode,
-        location.hashCode,
+        message,
+        location,
       );
 }
 
@@ -1337,14 +1337,14 @@
 
   @override
   int get hashCode => Object.hash(
-        kind.hashCode,
-        name.hashCode,
-        location.hashCode,
-        flags.hashCode,
-        parameters.hashCode,
-        returnType.hashCode,
-        typeParameters.hashCode,
-        aliasedType.hashCode,
+        kind,
+        name,
+        location,
+        flags,
+        parameters,
+        returnType,
+        typeParameters,
+        aliasedType,
       );
 }
 
@@ -1741,9 +1741,9 @@
 
   @override
   int get hashCode => Object.hash(
-        kind.hashCode,
-        offset.hashCode,
-        length.hashCode,
+        kind,
+        offset,
+        length,
       );
 }
 
@@ -1821,9 +1821,9 @@
 
   @override
   int get hashCode => Object.hash(
-        type.hashCode,
-        offset.hashCode,
-        length.hashCode,
+        type,
+        offset,
+        length,
       );
 }
 
@@ -2529,11 +2529,11 @@
 
   @override
   int get hashCode => Object.hash(
-        source.hashCode,
-        kind.hashCode,
-        target.hashCode,
-        fact.hashCode,
-        value.hashCode,
+        source,
+        kind,
+        target,
+        fact,
+        value,
       );
 }
 
@@ -2641,11 +2641,11 @@
 
   @override
   int get hashCode => Object.hash(
-        signature.hashCode,
-        corpus.hashCode,
-        root.hashCode,
-        path.hashCode,
-        language.hashCode,
+        signature,
+        corpus,
+        root,
+        path,
+        language,
       );
 }
 
@@ -2750,9 +2750,9 @@
 
   @override
   int get hashCode => Object.hash(
-        positions.hashCode,
-        length.hashCode,
-        suggestions.hashCode,
+        positions,
+        length,
+        suggestions,
       );
 }
 
@@ -2817,8 +2817,8 @@
 
   @override
   int get hashCode => Object.hash(
-        value.hashCode,
-        kind.hashCode,
+        value,
+        kind,
       );
 }
 
@@ -3019,13 +3019,13 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        length.hashCode,
-        startLine.hashCode,
-        startColumn.hashCode,
-        endLine.hashCode,
-        endColumn.hashCode,
+        file,
+        offset,
+        length,
+        startLine,
+        startColumn,
+        endLine,
+        endColumn,
       );
 }
 
@@ -3105,9 +3105,9 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
-        targets.hashCode,
+        offset,
+        length,
+        targets,
       );
 }
 
@@ -3259,14 +3259,14 @@
 
   @override
   int get hashCode => Object.hash(
-        kind.hashCode,
-        fileIndex.hashCode,
-        offset.hashCode,
-        length.hashCode,
-        startLine.hashCode,
-        startColumn.hashCode,
-        codeOffset.hashCode,
-        codeLength.hashCode,
+        kind,
+        fileIndex,
+        offset,
+        length,
+        startLine,
+        startColumn,
+        codeOffset,
+        codeLength,
       );
 }
 
@@ -3345,9 +3345,9 @@
 
   @override
   int get hashCode => Object.hash(
-        element.hashCode,
-        offsets.hashCode,
-        length.hashCode,
+        element,
+        offsets,
+        length,
       );
 }
 
@@ -3477,12 +3477,12 @@
 
   @override
   int get hashCode => Object.hash(
-        element.hashCode,
-        offset.hashCode,
-        length.hashCode,
-        codeOffset.hashCode,
-        codeLength.hashCode,
-        children.hashCode,
+        element,
+        offset,
+        length,
+        codeOffset,
+        codeLength,
+        children,
       );
 }
 
@@ -3575,10 +3575,10 @@
 
   @override
   int get hashCode => Object.hash(
-        kind.hashCode,
-        name.hashCode,
-        type.hashCode,
-        defaultValue.hashCode,
+        kind,
+        name,
+        type,
+        defaultValue,
       );
 }
 
@@ -3712,8 +3712,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
+        file,
+        offset,
       );
 }
 
@@ -3925,11 +3925,11 @@
 
   @override
   int get hashCode => Object.hash(
-        id.hashCode,
-        kind.hashCode,
-        type.hashCode,
-        name.hashCode,
-        parameters.hashCode,
+        id,
+        kind,
+        type,
+        name,
+        parameters,
       );
 }
 
@@ -4071,9 +4071,9 @@
 
   @override
   int get hashCode => Object.hash(
-        severity.hashCode,
-        message.hashCode,
-        location.hashCode,
+        severity,
+        message,
+        location,
       );
 }
 
@@ -4205,7 +4205,7 @@
   }
 
   @override
-  int get hashCode => 114870849;
+  int get hashCode => 114870849.hashCode;
 }
 
 /// SourceChange
@@ -4351,11 +4351,11 @@
 
   @override
   int get hashCode => Object.hash(
-        message.hashCode,
-        edits.hashCode,
-        linkedEditGroups.hashCode,
-        selection.hashCode,
-        id.hashCode,
+        message,
+        edits,
+        linkedEditGroups,
+        selection,
+        id,
       );
 }
 
@@ -4464,10 +4464,10 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
-        replacement.hashCode,
-        id.hashCode,
+        offset,
+        length,
+        replacement,
+        id,
       );
 }
 
@@ -4560,8 +4560,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        fileStamp.hashCode,
-        edits.hashCode,
+        file,
+        fileStamp,
+        edits,
       );
 }
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
index ee185f6..616ff13 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
@@ -160,8 +160,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        labels.hashCode,
+        file,
+        labels,
       );
 }
 
@@ -234,8 +234,8 @@
 
   @override
   int get hashCode => Object.hash(
-        error.hashCode,
-        fixes.hashCode,
+        error,
+        fixes,
       );
 }
 
@@ -315,8 +315,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        errors.hashCode,
+        file,
+        errors,
       );
 }
 
@@ -459,8 +459,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        regions.hashCode,
+        file,
+        regions,
       );
 }
 
@@ -664,8 +664,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
+        file,
+        offset,
       );
 }
 
@@ -826,9 +826,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        length.hashCode,
+        file,
+        offset,
+        length,
       );
 }
 
@@ -1019,8 +1019,8 @@
 
   @override
   int get hashCode => Object.hash(
-        libraries.hashCode,
-        packageMap.hashCode,
+        libraries,
+        packageMap,
       );
 }
 
@@ -1110,9 +1110,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        length.hashCode,
+        file,
+        offset,
+        length,
       );
 }
 
@@ -1217,9 +1217,9 @@
 
   @override
   int get hashCode => Object.hash(
-        files.hashCode,
-        targets.hashCode,
-        regions.hashCode,
+        files,
+        targets,
+        regions,
       );
 }
 
@@ -1432,8 +1432,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
+        file,
+        offset,
       );
 }
 
@@ -1536,9 +1536,9 @@
 
   @override
   int get hashCode => Object.hash(
-        name.hashCode,
-        parameters.hashCode,
-        dartdoc.hashCode,
+        name,
+        parameters,
+        dartdoc,
       );
 }
 
@@ -1622,8 +1622,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        regions.hashCode,
+        file,
+        regions,
       );
 }
 
@@ -1722,9 +1722,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        classes.hashCode,
-        members.hashCode,
+        file,
+        classes,
+        members,
       );
 }
 
@@ -1824,10 +1824,10 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        length.hashCode,
-        delta.hashCode,
+        file,
+        offset,
+        length,
+        delta,
       );
 }
 
@@ -1946,10 +1946,10 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        regions.hashCode,
-        targets.hashCode,
-        files.hashCode,
+        file,
+        regions,
+        targets,
+        files,
       );
 }
 
@@ -2030,8 +2030,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        occurrences.hashCode,
+        file,
+        occurrences,
       );
 }
 
@@ -2216,14 +2216,14 @@
 
   @override
   int get hashCode => Object.hash(
-        enableAsync.hashCode,
-        enableDeferredLoading.hashCode,
-        enableEnums.hashCode,
-        enableNullAwareOperators.hashCode,
-        enableSuperMixins.hashCode,
-        generateDart2jsHints.hashCode,
-        generateHints.hashCode,
-        generateLints.hashCode,
+        enableAsync,
+        enableDeferredLoading,
+        enableEnums,
+        enableNullAwareOperators,
+        enableSuperMixins,
+        generateDart2jsHints,
+        generateHints,
+        generateLints,
       );
 }
 
@@ -2329,10 +2329,10 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        kind.hashCode,
-        libraryName.hashCode,
-        outline.hashCode,
+        file,
+        kind,
+        libraryName,
+        outline,
       );
 }
 
@@ -2412,8 +2412,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        overrides.hashCode,
+        file,
+        overrides,
       );
 }
 
@@ -2667,9 +2667,9 @@
 
   @override
   int get hashCode => Object.hash(
-        included.hashCode,
-        excluded.hashCode,
-        packageRoots.hashCode,
+        included,
+        excluded,
+        packageRoots,
       );
 }
 
@@ -3039,8 +3039,8 @@
 
   @override
   int get hashCode => Object.hash(
-        isAnalyzing.hashCode,
-        analysisTarget.hashCode,
+        isAnalyzing,
+        analysisTarget,
       );
 }
 
@@ -3586,8 +3586,8 @@
 
   @override
   int get hashCode => Object.hash(
-        event.hashCode,
-        millis.hashCode,
+        event,
+        millis,
       );
 }
 
@@ -3806,15 +3806,15 @@
 
   @override
   int get hashCode => Object.hash(
-        label.hashCode,
-        declaringLibraryUri.hashCode,
-        element.hashCode,
-        defaultArgumentListString.hashCode,
-        defaultArgumentListTextRanges.hashCode,
-        parameterNames.hashCode,
-        parameterTypes.hashCode,
-        relevanceTags.hashCode,
-        requiredParameterCount.hashCode,
+        label,
+        declaringLibraryUri,
+        element,
+        defaultArgumentListString,
+        defaultArgumentListTextRanges,
+        parameterNames,
+        parameterTypes,
+        relevanceTags,
+        requiredParameterCount,
       );
 }
 
@@ -3896,9 +3896,9 @@
 
   @override
   int get hashCode => Object.hash(
-        id.hashCode,
-        uri.hashCode,
-        items.hashCode,
+        id,
+        uri,
+        items,
       );
 }
 
@@ -3969,8 +3969,8 @@
 
   @override
   int get hashCode => Object.hash(
-        path.hashCode,
-        fixes.hashCode,
+        path,
+        fixes,
       );
 }
 
@@ -4036,8 +4036,8 @@
 
   @override
   int get hashCode => Object.hash(
-        code.hashCode,
-        occurrences.hashCode,
+        code,
+        occurrences,
       );
 }
 
@@ -4115,9 +4115,9 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
-        label.hashCode,
+        offset,
+        length,
+        label,
       );
 }
 
@@ -4210,8 +4210,8 @@
 
   @override
   int get hashCode => Object.hash(
-        changedLibraries.hashCode,
-        removedLibraries.hashCode,
+        changedLibraries,
+        removedLibraries,
       );
 }
 
@@ -4287,8 +4287,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        imports.hashCode,
+        file,
+        imports,
       );
 }
 
@@ -4391,10 +4391,10 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        id.hashCode,
-        label.hashCode,
-        offset.hashCode,
+        file,
+        id,
+        label,
+        offset,
       );
 }
 
@@ -4476,8 +4476,8 @@
 
   @override
   int get hashCode => Object.hash(
-        completion.hashCode,
-        change.hashCode,
+        completion,
+        change,
       );
 }
 
@@ -4552,8 +4552,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
+        file,
+        offset,
       );
 }
 
@@ -4946,15 +4946,15 @@
 
   @override
   int get hashCode => Object.hash(
-        id.hashCode,
-        replacementOffset.hashCode,
-        replacementLength.hashCode,
-        results.hashCode,
-        isLast.hashCode,
-        libraryFile.hashCode,
-        includedSuggestionSets.hashCode,
-        includedElementKinds.hashCode,
-        includedSuggestionRelevanceTags.hashCode,
+        id,
+        replacementOffset,
+        replacementLength,
+        results,
+        isLast,
+        libraryFile,
+        includedSuggestionSets,
+        includedElementKinds,
+        includedSuggestionRelevanceTags,
       );
 }
 
@@ -5210,11 +5210,11 @@
 
   @override
   int get hashCode => Object.hash(
-        name.hashCode,
-        explicitFileCount.hashCode,
-        implicitFileCount.hashCode,
-        workItemQueueLength.hashCode,
-        cacheEntryExceptions.hashCode,
+        name,
+        explicitFileCount,
+        implicitFileCount,
+        workItemQueueLength,
+        cacheEntryExceptions,
       );
 }
 
@@ -5555,8 +5555,8 @@
 
   @override
   int get hashCode => Object.hash(
-        included.hashCode,
-        inTestMode.hashCode,
+        included,
+        inTestMode,
       );
 }
 
@@ -5643,8 +5643,8 @@
 
   @override
   int get hashCode => Object.hash(
-        edits.hashCode,
-        details.hashCode,
+        edits,
+        details,
       );
 }
 
@@ -5749,10 +5749,10 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        selectionOffset.hashCode,
-        selectionLength.hashCode,
-        lineLength.hashCode,
+        file,
+        selectionOffset,
+        selectionLength,
+        lineLength,
       );
 }
 
@@ -5849,9 +5849,9 @@
 
   @override
   int get hashCode => Object.hash(
-        edits.hashCode,
-        selectionOffset.hashCode,
-        selectionLength.hashCode,
+        edits,
+        selectionOffset,
+        selectionLength,
       );
 }
 
@@ -5938,9 +5938,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        length.hashCode,
+        file,
+        offset,
+        length,
       );
 }
 
@@ -6097,9 +6097,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        length.hashCode,
+        file,
+        offset,
+        length,
       );
 }
 
@@ -6243,8 +6243,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
+        file,
+        offset,
       );
 }
 
@@ -6400,9 +6400,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        key.hashCode,
-        offset.hashCode,
+        file,
+        key,
+        offset,
       );
 }
 
@@ -6604,12 +6604,12 @@
 
   @override
   int get hashCode => Object.hash(
-        kind.hashCode,
-        file.hashCode,
-        offset.hashCode,
-        length.hashCode,
-        validateOnly.hashCode,
-        options.hashCode,
+        kind,
+        file,
+        offset,
+        length,
+        validateOnly,
+        options,
       );
 }
 
@@ -6784,12 +6784,12 @@
 
   @override
   int get hashCode => Object.hash(
-        initialProblems.hashCode,
-        optionsProblems.hashCode,
-        finalProblems.hashCode,
-        feedback.hashCode,
-        change.hashCode,
-        potentialEdits.hashCode,
+        initialProblems,
+        optionsProblems,
+        finalProblems,
+        feedback,
+        change,
+        potentialEdits,
       );
 }
 
@@ -6864,8 +6864,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
+        file,
+        offset,
       );
 }
 
@@ -6945,8 +6945,8 @@
 
   @override
   int get hashCode => Object.hash(
-        change.hashCode,
-        whitespaceOnly.hashCode,
+        change,
+        whitespaceOnly,
       );
 }
 
@@ -7043,9 +7043,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        elements.hashCode,
-        offset.hashCode,
+        file,
+        elements,
+        offset,
       );
 }
 
@@ -7202,9 +7202,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        key.hashCode,
-        offset.hashCode,
+        file,
+        key,
+        offset,
       );
 }
 
@@ -7814,17 +7814,17 @@
 
   @override
   int get hashCode => Object.hash(
-        name.hashCode,
-        kind.hashCode,
-        fileIndex.hashCode,
-        offset.hashCode,
-        line.hashCode,
-        column.hashCode,
-        codeOffset.hashCode,
-        codeLength.hashCode,
-        className.hashCode,
-        mixinName.hashCode,
-        parameters.hashCode,
+        name,
+        kind,
+        fileIndex,
+        offset,
+        line,
+        column,
+        codeOffset,
+        codeLength,
+        className,
+        mixinName,
+        parameters,
       );
 }
 
@@ -7889,8 +7889,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        kind.hashCode,
+        file,
+        kind,
       );
 }
 
@@ -8335,12 +8335,12 @@
 
   @override
   int get hashCode => Object.hash(
-        code.hashCode,
-        offset.hashCode,
-        contextFile.hashCode,
-        contextOffset.hashCode,
-        variables.hashCode,
-        expressions.hashCode,
+        code,
+        offset,
+        contextFile,
+        contextOffset,
+        variables,
+        expressions,
       );
 }
 
@@ -8449,8 +8449,8 @@
 
   @override
   int get hashCode => Object.hash(
-        suggestions.hashCode,
-        expressions.hashCode,
+        suggestions,
+        expressions,
       );
 }
 
@@ -8546,9 +8546,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        kind.hashCode,
-        referencedFiles.hashCode,
+        file,
+        kind,
+        referencedFiles,
       );
 }
 
@@ -8635,9 +8635,9 @@
 
   @override
   int get hashCode => Object.hash(
-        id.hashCode,
-        file.hashCode,
-        uri.hashCode,
+        id,
+        file,
+        uri,
       );
 }
 
@@ -8717,8 +8717,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        uri.hashCode,
+        file,
+        uri,
       );
 }
 
@@ -8921,8 +8921,8 @@
 
   @override
   int get hashCode => Object.hash(
-        uri.hashCode,
-        elements.hashCode,
+        uri,
+        elements,
       );
 }
 
@@ -8994,8 +8994,8 @@
 
   @override
   int get hashCode => Object.hash(
-        elements.hashCode,
-        imports.hashCode,
+        elements,
+        imports,
       );
 }
 
@@ -9119,11 +9119,11 @@
 
   @override
   int get hashCode => Object.hash(
-        coveringExpressionOffsets.hashCode,
-        coveringExpressionLengths.hashCode,
-        names.hashCode,
-        offsets.hashCode,
-        lengths.hashCode,
+        coveringExpressionOffsets,
+        coveringExpressionLengths,
+        names,
+        offsets,
+        lengths,
       );
 }
 
@@ -9198,8 +9198,8 @@
 
   @override
   int get hashCode => Object.hash(
-        name.hashCode,
-        extractAll.hashCode,
+        name,
+        extractAll,
       );
 }
 
@@ -9361,14 +9361,14 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
-        returnType.hashCode,
-        names.hashCode,
-        canCreateGetter.hashCode,
-        parameters.hashCode,
-        offsets.hashCode,
-        lengths.hashCode,
+        offset,
+        length,
+        returnType,
+        names,
+        canCreateGetter,
+        parameters,
+        offsets,
+        lengths,
       );
 }
 
@@ -9503,11 +9503,11 @@
 
   @override
   int get hashCode => Object.hash(
-        returnType.hashCode,
-        createGetter.hashCode,
-        name.hashCode,
-        parameters.hashCode,
-        extractAll.hashCode,
+        returnType,
+        createGetter,
+        name,
+        parameters,
+        extractAll,
       );
 }
 
@@ -9728,8 +9728,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
+        file,
+        offset,
       );
 }
 
@@ -10045,18 +10045,18 @@
 
   @override
   int get hashCode => Object.hash(
-        kind.hashCode,
-        offset.hashCode,
-        length.hashCode,
-        codeOffset.hashCode,
-        codeLength.hashCode,
-        label.hashCode,
-        dartElement.hashCode,
-        attributes.hashCode,
-        className.hashCode,
-        parentAssociationLabel.hashCode,
-        variableName.hashCode,
-        children.hashCode,
+        kind,
+        offset,
+        length,
+        codeOffset,
+        codeLength,
+        label,
+        dartElement,
+        attributes,
+        className,
+        parentAssociationLabel,
+        variableName,
+        children,
       );
 }
 
@@ -10209,13 +10209,13 @@
 
   @override
   int get hashCode => Object.hash(
-        name.hashCode,
-        label.hashCode,
-        literalValueBoolean.hashCode,
-        literalValueInteger.hashCode,
-        literalValueString.hashCode,
-        nameLocation.hashCode,
-        valueLocation.hashCode,
+        name,
+        label,
+        literalValueBoolean,
+        literalValueInteger,
+        literalValueString,
+        nameLocation,
+        valueLocation,
       );
 }
 
@@ -10377,8 +10377,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        outline.hashCode,
+        file,
+        outline,
       );
 }
 
@@ -10608,8 +10608,8 @@
 
   @override
   int get hashCode => Object.hash(
-        id.hashCode,
-        value.hashCode,
+        id,
+        value,
       );
 }
 
@@ -10867,15 +10867,15 @@
 
   @override
   int get hashCode => Object.hash(
-        documentation.hashCode,
-        expression.hashCode,
-        id.hashCode,
-        isRequired.hashCode,
-        isSafeToUpdate.hashCode,
-        name.hashCode,
-        children.hashCode,
-        editor.hashCode,
-        value.hashCode,
+        documentation,
+        expression,
+        id,
+        isRequired,
+        isSafeToUpdate,
+        name,
+        children,
+        editor,
+        value,
       );
 }
 
@@ -10952,8 +10952,8 @@
 
   @override
   int get hashCode => Object.hash(
-        kind.hashCode,
-        enumItems.hashCode,
+        kind,
+        enumItems,
       );
 }
 
@@ -11178,12 +11178,12 @@
 
   @override
   int get hashCode => Object.hash(
-        boolValue.hashCode,
-        doubleValue.hashCode,
-        intValue.hashCode,
-        stringValue.hashCode,
-        enumValue.hashCode,
-        expression.hashCode,
+        boolValue,
+        doubleValue,
+        intValue,
+        stringValue,
+        enumValue,
+        expression,
       );
 }
 
@@ -11284,10 +11284,10 @@
 
   @override
   int get hashCode => Object.hash(
-        libraryUri.hashCode,
-        className.hashCode,
-        name.hashCode,
-        documentation.hashCode,
+        libraryUri,
+        className,
+        name,
+        documentation,
       );
 }
 
@@ -11580,18 +11580,18 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
-        containingLibraryPath.hashCode,
-        containingLibraryName.hashCode,
-        containingClassDescription.hashCode,
-        dartdoc.hashCode,
-        elementDescription.hashCode,
-        elementKind.hashCode,
-        isDeprecated.hashCode,
-        parameter.hashCode,
-        propagatedType.hashCode,
-        staticType.hashCode,
+        offset,
+        length,
+        containingLibraryPath,
+        containingLibraryName,
+        containingClassDescription,
+        dartdoc,
+        elementDescription,
+        elementKind,
+        isDeprecated,
+        parameter,
+        propagatedType,
+        staticType,
       );
 }
 
@@ -11655,8 +11655,8 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
+        offset,
+        length,
       );
 }
 
@@ -11720,8 +11720,8 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
+        offset,
+        length,
       );
 }
 
@@ -11802,9 +11802,9 @@
 
   @override
   int get hashCode => Object.hash(
-        strings.hashCode,
-        uris.hashCode,
-        names.hashCode,
+        strings,
+        uris,
+        names,
       );
 }
 
@@ -11883,9 +11883,9 @@
 
   @override
   int get hashCode => Object.hash(
-        path.hashCode,
-        prefix.hashCode,
-        elements.hashCode,
+        path,
+        prefix,
+        elements,
       );
 }
 
@@ -11953,8 +11953,8 @@
 
   @override
   int get hashCode => Object.hash(
-        tag.hashCode,
-        relevanceBoost.hashCode,
+        tag,
+        relevanceBoost,
       );
 }
 
@@ -12042,9 +12042,9 @@
 
   @override
   int get hashCode => Object.hash(
-        id.hashCode,
-        relevance.hashCode,
-        displayUri.hashCode,
+        id,
+        relevance,
+        displayUri,
       );
 }
 
@@ -12110,8 +12110,8 @@
 
   @override
   int get hashCode => Object.hash(
-        name.hashCode,
-        occurrences.hashCode,
+        name,
+        occurrences,
       );
 }
 
@@ -12212,9 +12212,9 @@
 
   @override
   int get hashCode => Object.hash(
-        className.hashCode,
-        methodName.hashCode,
-        isDeclaration.hashCode,
+        className,
+        methodName,
+        isDeclaration,
       );
 }
 
@@ -12288,8 +12288,8 @@
 
   @override
   int get hashCode => Object.hash(
-        deleteSource.hashCode,
-        inlineAll.hashCode,
+        deleteSource,
+        inlineAll,
       );
 }
 
@@ -12440,8 +12440,8 @@
 
   @override
   int get hashCode => Object.hash(
-        entries.hashCode,
-        files.hashCode,
+        entries,
+        files,
       );
 }
 
@@ -12511,8 +12511,8 @@
 
   @override
   int get hashCode => Object.hash(
-        scope.hashCode,
-        libraryPaths.hashCode,
+        scope,
+        libraryPaths,
       );
 }
 
@@ -12652,8 +12652,8 @@
 
   @override
   int get hashCode => Object.hash(
-        element.hashCode,
-        className.hashCode,
+        element,
+        className,
       );
 }
 
@@ -12759,10 +12759,10 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
-        superclassMember.hashCode,
-        interfaceMembers.hashCode,
+        offset,
+        length,
+        superclassMember,
+        interfaceMembers,
       );
 }
 
@@ -12839,9 +12839,9 @@
 
   @override
   int get hashCode => Object.hash(
-        name.hashCode,
-        key.hashCode,
-        example.hashCode,
+        name,
+        key,
+        example,
       );
 }
 
@@ -13058,10 +13058,10 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
-        elementKindName.hashCode,
-        oldName.hashCode,
+        offset,
+        length,
+        elementKindName,
+        oldName,
       );
 }
 
@@ -13201,9 +13201,9 @@
 
   @override
   int get hashCode => Object.hash(
-        code.hashCode,
-        message.hashCode,
-        stackTrace.hashCode,
+        code,
+        message,
+        stackTrace,
       );
 }
 
@@ -13633,9 +13633,9 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
-        type.hashCode,
+        offset,
+        length,
+        type,
       );
 }
 
@@ -13817,13 +13817,13 @@
 
   @override
   int get hashCode => Object.hash(
-        libraryPath.hashCode,
-        kind.hashCode,
-        name.hashCode,
-        typeArguments.hashCode,
-        returnType.hashCode,
-        parameterTypes.hashCode,
-        parameterNames.hashCode,
+        libraryPath,
+        kind,
+        name,
+        typeArguments,
+        returnType,
+        parameterTypes,
+        parameterNames,
       );
 }
 
@@ -13949,8 +13949,8 @@
 
   @override
   int get hashCode => Object.hash(
-        name.hashCode,
-        type.hashCode,
+        name,
+        type,
       );
 }
 
@@ -14042,9 +14042,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        includePotential.hashCode,
+        file,
+        offset,
+        includePotential,
       );
 }
 
@@ -14130,8 +14130,8 @@
 
   @override
   int get hashCode => Object.hash(
-        id.hashCode,
-        element.hashCode,
+        id,
+        element,
       );
 }
 
@@ -14609,9 +14609,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        pattern.hashCode,
-        maxResults.hashCode,
+        file,
+        pattern,
+        maxResults,
       );
 }
 
@@ -14696,8 +14696,8 @@
 
   @override
   int get hashCode => Object.hash(
-        declarations.hashCode,
-        files.hashCode,
+        declarations,
+        files,
       );
 }
 
@@ -14789,9 +14789,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        superOnly.hashCode,
+        file,
+        offset,
+        superOnly,
       );
 }
 
@@ -14972,10 +14972,10 @@
 
   @override
   int get hashCode => Object.hash(
-        location.hashCode,
-        kind.hashCode,
-        isPotential.hashCode,
-        path.hashCode,
+        location,
+        kind,
+        isPotential,
+        path,
       );
 }
 
@@ -15158,9 +15158,9 @@
 
   @override
   int get hashCode => Object.hash(
-        id.hashCode,
-        results.hashCode,
-        isLast.hashCode,
+        id,
+        results,
+        isLast,
       );
 }
 
@@ -15234,8 +15234,8 @@
 
   @override
   int get hashCode => Object.hash(
-        version.hashCode,
-        pid.hashCode,
+        version,
+        pid,
       );
 }
 
@@ -15326,9 +15326,9 @@
 
   @override
   int get hashCode => Object.hash(
-        isFatal.hashCode,
-        message.hashCode,
-        stackTrace.hashCode,
+        isFatal,
+        message,
+        stackTrace,
       );
 }
 
@@ -15495,9 +15495,9 @@
 
   @override
   int get hashCode => Object.hash(
-        time.hashCode,
-        kind.hashCode,
-        data.hashCode,
+        time,
+        kind,
+        data,
       );
 }
 
@@ -15914,8 +15914,8 @@
 
   @override
   int get hashCode => Object.hash(
-        analysis.hashCode,
-        pub.hashCode,
+        analysis,
+        pub,
       );
 }
 
@@ -16077,12 +16077,12 @@
 
   @override
   int get hashCode => Object.hash(
-        classElement.hashCode,
-        displayName.hashCode,
-        memberElement.hashCode,
-        superclass.hashCode,
-        interfaces.hashCode,
-        mixins.hashCode,
-        subclasses.hashCode,
+        classElement,
+        displayName,
+        memberElement,
+        superclass,
+        interfaces,
+        mixins,
+        subclasses,
       );
 }
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index e1189f9..0a2871d 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/to_source_visitor.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
 
 export 'package:analyzer/src/dart/ast/constant_evaluator.dart';
@@ -1923,6 +1924,12 @@
       return true;
     } else if (identical(node.defaultValue, _oldNode)) {
       node.defaultValue = _newNode as Expression;
+      var parameterElement = node.declaredElement;
+      if (parameterElement is DefaultParameterElementImpl) {
+        parameterElement.constantInitializer = _newNode as Expression;
+      } else if (parameterElement is DefaultFieldFormalParameterElementImpl) {
+        parameterElement.constantInitializer = _newNode as Expression;
+      }
       return true;
     }
     return visitNode(node);
@@ -2904,6 +2911,9 @@
     } else if (identical(node.initializer, _oldNode)) {
       node.initializer = _newNode as Expression;
       return true;
+      // TODO(srawlins) also replace node's declared element's
+      // `constantInitializer`, if the element is [ConstFieldElementImpl],
+      // [ConstLocalVariableElementImpl], or [ConstTopLevelVariableElementImpl].
     }
     return visitAnnotatedNode(node);
   }
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index 5b34511..40a0feb 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -116,7 +116,7 @@
   @override
   void visitConstructorReference(ConstructorReference node) {
     super.visitConstructorReference(node);
-    if (node.inConstantContext) {
+    if (node.inConstantContext || node.inConstantExpression) {
       _checkForConstWithTypeParameters(node.constructorName.type2,
           CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_CONSTRUCTOR_TEAROFF);
     }
@@ -131,7 +131,7 @@
   @override
   void visitFunctionReference(FunctionReference node) {
     super.visitFunctionReference(node);
-    if (node.inConstantContext) {
+    if (node.inConstantContext || node.inConstantExpression) {
       var typeArguments = node.typeArguments;
       if (typeArguments == null) {
         return;
@@ -545,13 +545,10 @@
     }
   }
 
-  /// Validates that the expressions of any field initializers in the class
-  /// declaration are all compile time constants. Since this is only required if
-  /// the class has a constant constructor, the error is reported at the
-  /// constructor site.
-  ///
-  /// @param classDeclaration the class which should be validated
-  /// @param errorSite the site at which errors should be reported.
+  /// Validates that the expressions of any field initializers in
+  /// [classDeclaration] are all compile-time constants. Since this is only
+  /// required if the class has a constant constructor, the error is reported at
+  /// [constKeyword], the const keyword on such a constant constructor.
   void _validateFieldInitializers(
       ClassOrMixinDeclaration classDeclaration, Token constKeyword) {
     NodeList<ClassMember> members = classDeclaration.members;
@@ -1048,3 +1045,44 @@
     required this.elementType,
   });
 }
+
+extension on Expression {
+  /// Returns whether `this` is found in a constant expression.
+  ///
+  /// This does not check whether `this` is found in a constant context.
+  bool get inConstantExpression {
+    AstNode child = this;
+    var parent = child.parent;
+    while (parent != null) {
+      if (parent is DefaultFormalParameter && child == parent.defaultValue) {
+        // A parameter default value does not constitute a constant context, but
+        // must be a constant expression.
+        return true;
+      } else if (parent is VariableDeclaration && child == parent.initializer) {
+        var declarationList = parent.parent;
+        if (declarationList is VariableDeclarationList) {
+          var declarationListParent = declarationList.parent;
+          if (declarationListParent is FieldDeclaration &&
+              !declarationListParent.isStatic) {
+            var container = declarationListParent.parent;
+            if (container is ClassOrMixinDeclaration) {
+              var enclosingClass = container.declaredElement;
+              if (enclosingClass != null) {
+                // A field initializer of a class with at least one generative
+                // const constructor does not constitute a constant context, but
+                // must be a constant expression.
+                return enclosingClass.constructors
+                    .any((c) => c.isConst && !c.isFactory);
+              }
+            }
+          }
+        }
+        return false;
+      } else {
+        child = parent;
+        parent = child.parent;
+      }
+    }
+    return false;
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index dc07809..43707ea 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -1310,12 +1310,46 @@
           "of '{1}'.");
 
   /**
-   * This hint is generated anywhere where a member annotated with
-   * `@visibleForOverriding` is used for another purpose than overriding it.
-   *
    * Parameters:
    * 0: the name of the member
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when an instance member that is
+  // annotated with `visibleForOverriding` is referenced outside the library in
+  // which it's declared for any reason other than to override it.
+  //
+  // #### Example
+  //
+  // Given a file named `a.dart` containing the following declaration:
+  //
+  // ```dart
+  // %uri="lib/a.dart"
+  // import 'package:meta/meta.dart';
+  //
+  // class A {
+  //   @visibleForOverriding
+  //   void a() {}
+  // }
+  // ```
+  //
+  // The following code produces this diagnostic because the method `m` is being
+  // invoked even though the only reason it's public is to allow it to be
+  // overridden:
+  //
+  // ```dart
+  // import 'a.dart';
+  //
+  // class B extends A {
+  //   void b() {
+  //     [!a!]();
+  //   }
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Remove the invalid use of the member.
   static const HintCode INVALID_USE_OF_VISIBLE_FOR_OVERRIDING_MEMBER = HintCode(
       'INVALID_USE_OF_VISIBLE_FOR_OVERRIDING_MEMBER',
       "The member '{0}' can only be used for overriding.");
@@ -1398,13 +1432,40 @@
           "meaningful on declarations of public members.",
       hasPublishedDocs: true);
 
-  /// Hint when an `@visibleForOverriding` annotation is used on something that
-  /// isn't an interface member.
+  /**
+   * No parameters.
+   */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when anything other than a public
+  // instance member of a class is annotated with `visibleForOverriding`.
+  // Because only public instance members can be overridden outside the defining
+  // library, there's no value to annotating any other declarations.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the annotation is on a
+  // class, and classes can't be overridden:
+  //
+  // ```dart
+  // import 'package:meta/meta.dart';
+  //
+  // [!@visibleForOverriding!]
+  // class C {}
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Remove the annotation:
+  //
+  // ```dart
+  // class C {}
+  // ```
   static const HintCode INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION = HintCode(
     'INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION',
-    "The declaration '{0}' is annotated with 'visibleForOverriding'. As '{0}' "
-        "is not an interface member that could be overriden, the annotation is "
-        'meaningless.',
+    "The declaration '{0}' is annotated with 'visibleForOverriding'. Because "
+        "'{0}' isn't an interface member that could be overridden, the "
+        "annotation is meaningless.",
   );
 
   /**
@@ -1749,13 +1810,43 @@
   );
 
   /**
-   * Users should not use `Future.value` or `Completer.complete` with a null
-   * argument if the type argument is non-nullable.
+   * Parameters:
+   * 0: the name of the method being invoked
+   * 1: the type argument associated with the method
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when `null` is passed to either the
+  // constructor `Future.value` or the method `Completer.complete` when the type
+  // argument used to create the instance was non-nullable. Even though the type
+  // system can't express this restriction, passing in a `null` results in a
+  // runtime exception.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because `null` is being passed
+  // to the constructor `Future.value` even though the type argument is the
+  // non-nullable type `String`:
+  //
+  // ```dart
+  // Future<String> f() {
+  //   return Future.value([!null!]);
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Pass in a non-null value:
+  //
+  // ```dart
+  // Future<String> f() {
+  //   return Future.value('');
+  // }
+  // ```
   static const HintCode NULL_ARGUMENT_TO_NON_NULL_TYPE = HintCode(
       'NULL_ARGUMENT_TO_NON_NULL_TYPE',
-      "'{0}' should not be called with a null argument for the non-nullable "
-          "type argument '{1}'",
+      "'{0}' shouldn't be called with a null argument for the non-nullable "
+          "type argument '{1}'.",
       correction: 'Try adding a non-null argument.');
 
   /**
@@ -2213,23 +2304,62 @@
       hasPublishedDocs: true);
 
   /**
-   * A constructor cannot be torn off without the 'constructor-tearoffs'
-   * language feature.
+   * No parameters.
    *
    * There is also a [ParserError.EXPERIMENT_NOT_ENABLED] code which catches
    * some cases of constructor tearoff features (like `List<int>.filled;`).
    * Other constructor tearoff cases are not realized until resolution
    * (like `List.filled;`).
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a constructor tear-off is found
+  // in code that has an SDK constraint whose lower bound is less than 2.15.
+  // Constructor tear-offs weren't supported in earlier versions, so this code
+  // won't be able to run against earlier versions of the SDK.
+  //
+  // #### Example
+  //
+  // Here's an example of a pubspec that defines an SDK constraint with a lower
+  // bound of less than 2.15:
+  //
+  // ```yaml
+  // %uri="pubspec.yaml"
+  // environment:
+  //   sdk: '>=2.9.0 <2.15.0'
+  // ```
+  //
+  // In the package that has that pubspec, code like the following produces this
+  // diagnostic:
+  //
+  // ```dart
+  // %language=2.14
+  // var setConstructor = [!Set.identity!];
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If you don't need to support older versions of the SDK, then you can
+  // increase the SDK constraint to allow the operator to be used:
+  //
+  // ```yaml
+  // environment:
+  //   sdk: '>=2.15.0 <2.16.0'
+  // ```
+  //
+  // If you need to support older versions of the SDK, then rewrite the code to
+  // not use constructor tear-offs:
+  //
+  // ```dart
+  // %language=2.14
+  // var setConstructor = () => Set.identity();
+  // ```
   static const HintCode SDK_VERSION_CONSTRUCTOR_TEAROFFS = HintCode(
       'SDK_VERSION_CONSTRUCTOR_TEAROFFS',
       "Tearing off a constructor requires the 'constructor-tearoffs' "
           "language feature.",
-      // TODO(srawlins): Update this text to something like "Try updating
-      // your pubspec.yaml to set the minimum SDK constraint to 2.14 or
-      // higher, and running 'pub get'."
-      correction: "Try enabling the experiment by including "
-          "'--enable-experiment=constructor-tearoffs' in the 'dart' command.");
+      correction: "Try updating your pubspec.yaml to set the minimum SDK "
+          "constraint to 2.15 or higher, and running 'pub get'.");
 
   /**
    * No parameters.
@@ -2865,13 +2995,39 @@
       hasPublishedDocs: true);
 
   /**
-   * This hint is generated when an `@UnusedResult.unless` annotation
-   * references an undefined parameter.
-   *
    * Parameters:
    * 0: the name of the undefined parameter
    * 1: the name of the targeted member
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when an annotation of the form
+  // `@UnusedResult.unless(parameterDefined: parameterName)` specifies a
+  // parameter name that isn't defined by the annotated function.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the function `f`
+  // doesn't have a parameter named `b`:
+  //
+  // ```dart
+  // import 'package:meta/meta.dart';
+  //
+  // @UseResult.unless(parameterDefined: [!'b'!])
+  // int f([int? a]) => a ?? 0;
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Change the argument named `parameterDefined` to match the name of one of
+  // the parameters to the function:
+  //
+  // ```dart
+  // import 'package:meta/meta.dart';
+  //
+  // @UseResult.unless(parameterDefined: 'a')
+  // int f([int? a]) => a ?? 0;
+  // ```
   static const HintCode UNDEFINED_REFERENCED_PARAMETER = HintCode(
       'UNDEFINED_REFERENCED_PARAMETER',
       "The parameter '{0}' is not defined by '{1}'.");
@@ -2970,10 +3126,57 @@
           "Try removing the name from the list, or removing the whole comment "
           "if this is the only name in the list.");
 
+  /**
+   * Parameters:
+   * 0: the uri that is not necessary
+   * 1: the uri that makes it unnecessary
+   */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when an import isn't needed because
+  // all of the names that are imported and referenced within the importing
+  // library are also visible through another import.
+  //
+  // #### Example
+  //
+  // Given a file named `a.dart` that contains the following:
+  //
+  // ```dart
+  // %uri="lib/a.dart"
+  // class A {}
+  // ```
+  //
+  // And, given a file named `b.dart` that contains the following:
+  //
+  // ```dart
+  // %uri="lib/b.dart"
+  // export 'a.dart';
+  //
+  // class B {}
+  // ```
+  //
+  // The following code produces this diagnostic because the class `A`, which is
+  // imported from `a.dart`, is also imported from `b.dart`. Removing the import
+  // of `a.dart` leaves the semantics unchanged:
+  //
+  // ```dart
+  // import [!'a.dart'!];
+  // import 'b.dart';
+  //
+  // void f(A a, B b) {}
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If the import isn't needed, then remove it.
+  //
+  // If some of the names imported by this import are intended to be used but
+  // aren't yet, and if those names aren't imported by other imports, then add
+  // the missing references to those names.
   static const HintCode UNNECESSARY_IMPORT = HintCode(
       'UNNECESSARY_IMPORT',
-      "The import of '{0}' is unnecessary as all of the used elements are also "
-          "provided by the import of '{1}'.",
+      "The import of '{0}' is unnecessary because all of the used elements are "
+          "also provided by the import of '{1}'.",
       correction: 'Try removing the import directive.');
 
   /**
@@ -3105,6 +3308,28 @@
    * Parameters:
    * 0: the name of the type
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when either the type `dynamic` or the
+  // type `Null` is followed by a question mark. Both of these types are
+  // inherently nullable so the question mark doesn't change the semantics.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the question mark
+  // following `dynamic` isn't necessary:
+  //
+  // ```dart
+  // dynamic[!?!] x;
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Remove the unneeded question mark:
+  //
+  // ```dart
+  // dynamic x;
+  // ```
   static const HintCode UNNECESSARY_QUESTION_MARK = HintCode(
       'UNNECESSARY_QUESTION_MARK',
       "The '?' is unnecessary because '{0}' is nullable without it.");
@@ -3327,16 +3552,24 @@
   //
   // #### Examples
   //
-  // The following code produces this diagnostic because `_x` isn't referenced
-  // anywhere in the library:
+  // The following code produces this diagnostic because the field
+  // `_originalValue` isn't read anywhere in the library:
   //
   // ```dart
-  // %language=2.9
-  // class Point {
-  //   int [!_x!];
+  // class C {
+  //   final String [!_originalValue!];
+  //   final String _currentValue;
+  //
+  //   C(this._originalValue) : _currentValue = _originalValue;
+  //
+  //   String get value => _currentValue;
   // }
   // ```
   //
+  // It might appear that the field `_originalValue` is being read in the
+  // initializer (`_currentValue = _originalValue`), but that is actually a
+  // reference to the parameter of the same name, not a reference to the field.
+  //
   // #### Common fixes
   //
   // If the field isn't needed, then remove it.
@@ -3461,16 +3694,78 @@
       hasPublishedDocs: true);
 
   /**
-   * The result of invoking a method, property, or function annotated with
-   * `@useResult` must be used (assigned, passed to a function as an argument,
-   * or returned by a function).
-   *
    * Parameters:
    * 0: the name of the annotated method, property or function
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a function annotated with
+  // `useResult` is invoked, and the value returned by that function isn't used.
+  // The value is considered to be used if a member of the value is invoked, if
+  // the value is passed to another function, or if the value is assigned to a
+  // variable or field.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the invocation of
+  // `c.a()` isn't used, even though the method `a` is annotated with
+  // `useResult`:
+  //
+  // ```dart
+  // import 'package:meta/meta.dart';
+  //
+  // class C {
+  //   @useResult
+  //   int a() => 0;
+  //
+  //   int b() => 0;
+  // }
+  //
+  // void f(C c) {
+  //   c.[!a!]();
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If you intended to invoke the annotated function, then use the value that
+  // was returned:
+  //
+  // ```dart
+  // import 'package:meta/meta.dart';
+  //
+  // class C {
+  //   @useResult
+  //   int a() => 0;
+  //
+  //   int b() => 0;
+  // }
+  //
+  // void f(C c) {
+  //   print(c.a());
+  // }
+  // ```
+  //
+  // If you intended to invoke a different function, then correct the name of
+  // the function being invoked:
+  //
+  // ```dart
+  // import 'package:meta/meta.dart';
+  //
+  // class C {
+  //   @useResult
+  //   int a() => 0;
+  //
+  //   int b() => 0;
+  // }
+  //
+  // void f(C c) {
+  //   c.b();
+  // }
+  // ```
   static const HintCode UNUSED_RESULT = HintCode(
     'UNUSED_RESULT',
-    "'{0}' should be used.",
+    "The value of '{0}' should be used.",
     correction: "Try using the result by invoking a member, passing it to a "
         "function, or returning it from this function.",
     hasPublishedDocs: false,
@@ -3533,12 +3828,30 @@
       hasPublishedDocs: true);
 
   /**
-   * Users should not import or export Dart native extensions via 'dart-ext:'.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a library is imported using the
+  // `dart-ext` scheme.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the native library `x`
+  // is being imported using a scheme of `dart-ext`:
+  //
+  // ```dart
+  // [!import 'dart-ext:x';!]
+  // int f() native 'string';
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Rewrite the code to use `dart:ffi` as a way of invoking the contents of the
+  // native library.
   static const HintCode USE_OF_NATIVE_EXTENSION = HintCode(
       'USE_OF_NATIVE_EXTENSION',
-      "Dart native extensions are deprecated and will not be available in Dart "
-          "2.15",
+      "Dart native extensions are deprecated and aren’t available in Dart 2.15.",
       correction: "Try using dart:ffi for C interop.");
 
   /**
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 966655d..4cd3002 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -5254,21 +5254,55 @@
   /**
    * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when an instance method is being torn
+  // off from a receiver whose type is `dynamic`, and the tear-off includes type
+  // arguments. Because the analyzer can't know how many type parameters the
+  // method has, or whether it has any type parameters, there's no way it can
+  // validate that the type arguments are correct. As a result, the type
+  // arguments aren't allowed.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the type of `p` is
+  // `dynamic` and the tear-off of `m` has type arguments:
+  //
+  // ```dart
+  // void f(dynamic list) {
+  //   [!list.fold!]<int>;
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If you can use a more specific type than `dynamic`, then change the type of
+  // the receiver:
+  //
+  // ```dart
+  // void f(List<Object> list) {
+  //   list.fold<int>;
+  // }
+  // ```
+  //
+  // If you can't use a more specific type, then remove the type arguments:
+  //
+  // ```dart
+  // void f(dynamic list) {
+  //   list.cast;
+  // }
+  // ```
   static const CompileTimeErrorCode
       GENERIC_METHOD_TYPE_INSTANTIATION_ON_DYNAMIC = CompileTimeErrorCode(
     'GENERIC_METHOD_TYPE_INSTANTIATION_ON_DYNAMIC',
-    "A method tearoff on a target whose type is 'dynamic' can't have type "
+    "A method tear-off on a receiver whose type is 'dynamic' can't have type "
         "arguments.",
     correction:
-        "Specify the type of the target, or remove the type arguments from the "
-        "method tearoff.",
+        "Specify the type of the receiver, or remove the type arguments from "
+        "the method tear-off.",
   );
 
   /**
-   * 10.3 Setters: It is a compile-time error if a class has a setter named
-   * `v=` with argument type `T` and a getter named `v` with return type `S`,
-   * and `S` may not be assigned to `T`.
-   *
    * Parameters:
    * 0: the name of the getter
    * 1: the type of the getter
@@ -6262,11 +6296,45 @@
       hasPublishedDocs: true);
 
   /**
-   * It is a compile-time error for an instance creation `C<T1, .. Tk>(...)` or
-   * `C<T1, .. Tk>.name()` (where `k` may be zero, which means that the type
-   * argument list is absent) if `C` denotes a type alias that expands to a
-   * type variable.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a constructor invocation is
+  // found where the type being instantiated is a type alias for one of the type
+  // parameters of the type alias. This isn’t allowed because the value of the
+  // type parameter is a type rather than a class.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because it creates an instance
+  // of `A`, even though `A` is a type alias that is defined to be equivalent to
+  // a type parameter:
+  //
+  // ```dart
+  // typedef A<T> = T;
+  //
+  // void f() {
+  //   const [!A!]<int>();
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Use either a class name or a type alias defined to be a class, rather than
+  // a type alias defined to be a type parameter:
+  //
+  // ```dart
+  // typedef A<T> = C<T>;
+  //
+  // void f() {
+  //   const A<int>();
+  // }
+  //
+  // class C<T> {
+  //   const C();
+  // }
+  // ```
   static const CompileTimeErrorCode
       INSTANTIATE_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER = CompileTimeErrorCode(
           'INSTANTIATE_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER',
@@ -6429,6 +6497,55 @@
           "constructor invocation.",
       hasPublishedDocs: true);
 
+  /**
+   * No parameters.
+   */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a constant defined in a library
+  // that is imported as a deferred library is referenced in the argument list
+  // of an annotation. Annotations are evaluated at compile time, and values
+  // from deferred libraries aren't available at compile time.
+  //
+  // For more information, see the language tour's coverage of
+  // [deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the constant `pi` is
+  // being referenced in the argument list of an annotation, even though the
+  // library that defines it is being imported as a deferred library:
+  //
+  // ```dart
+  // import 'dart:math' deferred as math;
+  //
+  // class C {
+  //   const C(double d);
+  // }
+  //
+  // @C([!math.pi!])
+  // void f () {}
+  // ```
+  //
+  // #### Common fixes
+  //
+  // If you need to reference the imported constant, then remove the `deferred`
+  // keyword:
+  //
+  // ```dart
+  // import 'dart:math' as math;
+  //
+  // class C {
+  //   const C(double d);
+  // }
+  //
+  // @C(math.pi)
+  // void f () {}
+  // ```
+  //
+  // If the import is required to be deferred and there's another constant that
+  // is appropriate, then use that constant in place of the constant from the
+  // deferred library.
   static const CompileTimeErrorCode
       INVALID_ANNOTATION_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY =
       CompileTimeErrorCode(
@@ -10405,6 +10522,27 @@
    * Parameters:
    * 0: the name of the operator that is not a binary operator.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when an operator that can only be
+  // used as a unary operator is used as a binary operator.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the operator `~` can
+  // only be used as a unary operator:
+  //
+  // ```dart
+  // var a = 5 [!~!] 3;
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Replace the operator with the correct binary operator:
+  //
+  // ```dart
+  // var a = 5 - 3;
+  // ```
   static const CompileTimeErrorCode NOT_BINARY_OPERATOR = CompileTimeErrorCode(
       'NOT_BINARY_OPERATOR', "'{0}' isn't a binary operator.");
 
@@ -11904,16 +12042,48 @@
           hasPublishedDocs: true);
 
   /**
-   * It is a compile-time error for a redirecting factory constructor to have
-   * a body which is a type alias that expands to a type variable, or a body
-   * which is a parameterized type of the form `F<T1, .. Tk>`, where `F` is
-   * a type alias that expands to a type variable.
+   * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a redirecting factory
+  // constructor redirects to a type alias, and the type alias expands to one of
+  // the type parameters of the type alias. This isn’t allowed because the value
+  // of the type parameter is a type rather than a class.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the redirect to `B<A>`
+  // is to a type alias whose value is `T`, even though it looks like the value
+  // should be `A`:
+  //
+  // ```dart
+  // class A implements C {}
+  //
+  // typedef B<T> = T;
+  //
+  // abstract class C {
+  //   factory C() = [!B!]<A>;
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Use either a class name or a type alias that is defined to be a class
+  // rather than a type alias defined to be a type parameter:
+  //
+  // ```dart
+  // class A implements C {}
+  //
+  // abstract class C {
+  //   factory C() = A;
+  // }
+  // ```
   static const CompileTimeErrorCode
       REDIRECT_TO_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER = CompileTimeErrorCode(
           'REDIRECT_TO_TYPE_ALIAS_EXPANDS_TO_TYPE_PARAMETER',
-          "Redirecting constructor can't redirect to a type alias "
-              "that expands to a type parameter.",
+          "A redirecting constructor can't redirect to a type alias that "
+              "expands to a type parameter.",
           correction: "Try replacing it with a class.");
 
   /**
@@ -12088,9 +12258,9 @@
   // #### Description
   //
   // The analyzer produces this diagnostic when a generator function (one whose
-  // body is marked with either `async*` or `sync*`) uses a `return` statement
-  // to return a value. In both cases, they should use `yield` instead of
-  // `return`.
+  // body is marked with either `async*` or `sync*`) uses either a `return`
+  // statement to return a value or implicitly returns a value because of using
+  // `=>`. In any of these cases, they should use `yield` instead of `return`.
   //
   // #### Example
   //
@@ -12103,8 +12273,24 @@
   // }
   // ```
   //
+  // The following code produces this diagnostic because the function `f` is a
+  // generator and is implicitly returning a value:
+  //
+  // ```dart
+  // Stream<int> f() async* [!=>!] 3;
+  // ```
+  //
   // #### Common fixes
   //
+  // If the function is using `=>` for the body of the function, then convert it
+  // to a block function body, and use `yield` to return a value:
+  //
+  // ```dart
+  // Stream<int> f() async* {
+  //   yield 3;
+  // }
+  // ```
+  //
   // If the method is intended to be a generator, then use `yield` to return a
   // value:
   //
@@ -12626,11 +12812,36 @@
   /**
    * No parameters.
    */
+  // #### Description
+  //
+  // The analyzer produces this diagnostic when a generative constructor from an
+  // abstract class is being torn off. This isn't allowed because it isn't valid
+  // to create an instance of an abstract class, which means that there isn't
+  // any valid use for the torn off constructor.
+  //
+  // #### Example
+  //
+  // The following code produces this diagnostic because the constructor `C.new`
+  // is being torn off and the class `C` is an abstract class:
+  //
+  // ```dart
+  // abstract class C {
+  //   C();
+  // }
+  //
+  // void f() {
+  //   [!C.new!];
+  // }
+  // ```
+  //
+  // #### Common fixes
+  //
+  // Tear off the constructor of a concrete class.
   static const CompileTimeErrorCode
       TEAROFF_OF_GENERATIVE_CONSTRUCTOR_OF_ABSTRACT_CLASS =
       CompileTimeErrorCode(
           'TEAROFF_OF_GENERATIVE_CONSTRUCTOR_OF_ABSTRACT_CLASS',
-          "A generative constructor of an abstract class can't be torn off",
+          "A generative constructor of an abstract class can't be torn off.",
           correction: "Try tearing off a constructor of a concrete class, or a "
               "non-generative constructor.");
 
@@ -15076,7 +15287,7 @@
   /**
    * ?? Yield: It is a compile-time error if a yield statement appears in a
    * function that is not a generator function.
-   * 
+   *
    * No parameters.
    */
   static const CompileTimeErrorCode YIELD_IN_NON_GENERATOR =
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart
index 230b7cd..e6f424c 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart
@@ -18,6 +18,8 @@
 
 @reflectiveTest
 class AnalysisDriverCachingTest extends PubPackageResolutionTest {
+  String get testFilePathPlatform => convertPath(testFilePath);
+
   List<Set<String>> get _linkedCycles {
     var driver = driverFor(testFilePath);
     return driver.test.libraryContext.linkedCycles;
@@ -30,7 +32,7 @@
 }
 ''');
 
-    driverFor(testFilePath).changeFile(testFilePath);
+    driverFor(testFilePathPlatform).changeFile(testFilePathPlatform);
     await resolveTestCode(r'''
 class A {
   factory A() =;
@@ -46,7 +48,7 @@
 }
 ''');
 
-    driverFor(testFilePath).changeFile(testFilePath);
+    driverFor(testFilePathPlatform).changeFile(testFilePathPlatform);
     await resolveTestCode(r'''
 class A {
   factory A() =
@@ -62,7 +64,7 @@
 }
 ''');
 
-    driverFor(testFilePath).changeFile(testFilePath);
+    driverFor(testFilePathPlatform).changeFile(testFilePathPlatform);
     await resolveTestCode(r'''
 class A {
   const
diff --git a/pkg/analyzer/test/src/diagnostics/const_with_type_parameters_test.dart b/pkg/analyzer/test/src/diagnostics/const_with_type_parameters_test.dart
index 6b02405..1014910 100644
--- a/pkg/analyzer/test/src/diagnostics/const_with_type_parameters_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_with_type_parameters_test.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
 import 'package:analyzer/src/error/codes.dart';
-import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/context_collection_resolution.dart';
@@ -34,6 +34,41 @@
     ]);
   }
 
+  test_defaultValue() async {
+    await assertErrorsInCode('''
+class A<T> {
+  void m([var fn = A<T>.new]) {}
+}
+''', [
+      error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_CONSTRUCTOR_TEAROFF,
+          34, 1),
+    ]);
+  }
+
+  test_defaultValue_fieldFormalParameter() async {
+    await assertErrorsInCode('''
+class A<T> {
+  A<T> Function() fn;
+  A([this.fn = A<T>.new]);
+}
+''', [
+      error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_CONSTRUCTOR_TEAROFF,
+          52, 1),
+    ]);
+  }
+
+  test_defaultValue_noTypeVariableInferredFromParameter() async {
+    await assertErrorsInCode('''
+class A<T> {
+  void m([A<T> Function() fn = A.new]) {}
+}
+''', [
+      // `A<dynamic> Function()` cannot be assigned to `A<T> Function()`, but
+      // there should not be any other error reported here.
+      error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 44, 5),
+    ]);
+  }
+
   test_direct() async {
     await assertErrorsInCode('''
 class A<T> {
@@ -48,6 +83,18 @@
     ]);
   }
 
+  test_fieldValue_constClass() async {
+    await assertErrorsInCode('''
+class A<T> {
+  const A();
+  final x = A<T>.new;
+}
+''', [
+      error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_CONSTRUCTOR_TEAROFF,
+          40, 1),
+    ]);
+  }
+
   test_indirect() async {
     await assertErrorsInCode('''
 class A<T> {
@@ -88,24 +135,16 @@
 @reflectiveTest
 class ConstWithTypeParametersFunctionTearoffTest
     extends PubPackageResolutionTest {
-  @FailingTest(
-    reason: 'The default value of an optional parameter is not considered a '
-        '"constant context". Currently only ConstantVerifier checks '
-        'CONST_WITH_TYPE_PARAMETERS (and related) errors, and only for '
-        'constant contexts. These checks should probably be moved to '
-        'ConstantVisitor (evaluation.dart), so as to check all expressions '
-        'expected to be constant expressions. Another example of a missing '
-        'error is a field initializer in a class with a constant constructor.',
-  )
   test_defaultValue() async {
-    addTestFile('''
+    await assertErrorsInCode('''
 void f<T>(T a) {}
 class A<U> {
   void m([void Function(U) fn = f<U>]) {}
 }
-''');
-    await resolveTestFile();
-    expect(result.errors, isNotEmpty);
+''', [
+      error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_FUNCTION_TEAROFF,
+          65, 1),
+    ]);
   }
 
   test_direct() async {
@@ -123,6 +162,42 @@
     ]);
   }
 
+  test_fieldValue_constClass() async {
+    await assertErrorsInCode('''
+void f<T>(T a) {}
+class A<U> {
+  const A();
+  final x = f<U>;
+}
+''', [
+      error(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS_FUNCTION_TEAROFF,
+          58, 1),
+    ]);
+  }
+
+  test_fieldValue_extension() async {
+    await assertErrorsInCode('''
+void f<T>(T a) {}
+class A<U> {}
+extension<U> on A<U> {
+  final x = f<U>;
+}
+''', [
+      // An instance field is illegal, but we should not also report an
+      // additional error for the type variable.
+      error(ParserErrorCode.EXTENSION_DECLARES_INSTANCE_FIELD, 63, 1),
+    ]);
+  }
+
+  test_fieldValue_nonConstClass() async {
+    await assertNoErrorsInCode('''
+void f<T>(T a) {}
+class A<U> {
+  final x = f<U>;
+}
+''');
+  }
+
   test_indirect() async {
     await assertErrorsInCode('''
 void f<T>(T a) {}
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index b519644..2a99024 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -5285,6 +5285,50 @@
 }
 {% endprettify %}
 
+### generic_method_type_instantiation_on_dynamic
+
+_A method tear-off on a receiver whose type is 'dynamic' can't have type
+arguments._
+
+#### Description
+
+The analyzer produces this diagnostic when an instance method is being torn
+off from a receiver whose type is `dynamic`, and the tear-off includes type
+arguments. Because the analyzer can't know how many type parameters the
+method has, or whether it has any type parameters, there's no way it can
+validate that the type arguments are correct. As a result, the type
+arguments aren't allowed.
+
+#### Example
+
+The following code produces this diagnostic because the type of `p` is
+`dynamic` and the tear-off of `m` has type arguments:
+
+{% prettify dart tag=pre+code %}
+void f(dynamic list) {
+  [!list.fold!]<int>;
+}
+{% endprettify %}
+
+#### Common fixes
+
+If you can use a more specific type than `dynamic`, then change the type of
+the receiver:
+
+{% prettify dart tag=pre+code %}
+void f(List<Object> list) {
+  list.fold<int>;
+}
+{% endprettify %}
+
+If you can't use a more specific type, then remove the type arguments:
+
+{% prettify dart tag=pre+code %}
+void f(dynamic list) {
+  list.cast;
+}
+{% endprettify %}
+
 ### getter_not_subtype_setter_types
 
 _The return type of getter '{0}' is '{1}' which isn't a subtype of the type
@@ -6114,6 +6158,48 @@
 
 If you intend to use an instance of a class, then use the name of that class in place of the name of the enum.
 
+### instantiate_type_alias_expands_to_type_parameter
+
+_Type aliases that expand to a type parameter can't be instantiated._
+
+#### Description
+
+The analyzer produces this diagnostic when a constructor invocation is
+found where the type being instantiated is a type alias for one of the type
+parameters of the type alias. This isn’t allowed because the value of the
+type parameter is a type rather than a class.
+
+#### Example
+
+The following code produces this diagnostic because it creates an instance
+of `A`, even though `A` is a type alias that is defined to be equivalent to
+a type parameter:
+
+{% prettify dart tag=pre+code %}
+typedef A<T> = T;
+
+void f() {
+  const [!A!]<int>();
+}
+{% endprettify %}
+
+#### Common fixes
+
+Use either a class name or a type alias defined to be a class, rather than
+a type alias defined to be a type parameter:
+
+{% prettify dart tag=pre+code %}
+typedef A<T> = C<T>;
+
+void f() {
+  const A<int>();
+}
+
+class C<T> {
+  const C();
+}
+{% endprettify %}
+
 ### integer_literal_imprecise_as_double
 
 _The integer literal is being used as a double, but can't be represented as a
@@ -6251,6 +6337,57 @@
 }
 {% endprettify %}
 
+### invalid_annotation_constant_value_from_deferred_library
+
+_Constant values from a deferred library can't be used in annotations._
+
+#### Description
+
+The analyzer produces this diagnostic when a constant defined in a library
+that is imported as a deferred library is referenced in the argument list
+of an annotation. Annotations are evaluated at compile time, and values
+from deferred libraries aren't available at compile time.
+
+For more information, see the language tour's coverage of
+[deferred loading](https://dart.dev/guides/language/language-tour#lazily-loading-a-library).
+
+#### Example
+
+The following code produces this diagnostic because the constant `pi` is
+being referenced in the argument list of an annotation, even though the
+library that defines it is being imported as a deferred library:
+
+{% prettify dart tag=pre+code %}
+import 'dart:math' deferred as math;
+
+class C {
+  const C(double d);
+}
+
+@C([!math.pi!])
+void f () {}
+{% endprettify %}
+
+#### Common fixes
+
+If you need to reference the imported constant, then remove the `deferred`
+keyword:
+
+{% prettify dart tag=pre+code %}
+import 'dart:math' as math;
+
+class C {
+  const C(double d);
+}
+
+@C(math.pi)
+void f () {}
+{% endprettify %}
+
+If the import is required to be deferred and there's another constant that
+is appropriate, then use that constant in place of the constant from the
+deferred library.
+
 ### invalid_annotation_from_deferred_library
 
 _Constant values from a deferred library can't be used as annotations._
@@ -7163,6 +7300,47 @@
 }
 {% endprettify %}
 
+### invalid_use_of_visible_for_overriding_member
+
+_The member '{0}' can only be used for overriding._
+
+#### Description
+
+The analyzer produces this diagnostic when an instance member that is
+annotated with `visibleForOverriding` is referenced outside the library in
+which it's declared for any reason other than to override it.
+
+#### Example
+
+Given a file named `a.dart` containing the following declaration:
+
+{% prettify dart tag=pre+code %}
+import 'package:meta/meta.dart';
+
+class A {
+  @visibleForOverriding
+  void a() {}
+}
+{% endprettify %}
+
+The following code produces this diagnostic because the method `m` is being
+invoked even though the only reason it's public is to allow it to be
+overridden:
+
+{% prettify dart tag=pre+code %}
+import 'a.dart';
+
+class B extends A {
+  void b() {
+    [!a!]();
+  }
+}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the invalid use of the member.
+
 ### invalid_visibility_annotation
 
 _The member '{0}' is annotated with '{1}', but this annotation is only
@@ -7208,6 +7386,38 @@
 void f() => someFunction();
 {% endprettify %}
 
+### invalid_visible_for_overriding_annotation
+
+_The declaration '{0}' is annotated with 'visibleForOverriding'. Because '{0}'
+isn't an interface member that could be overridden, the annotation is meaningless._
+
+#### Description
+
+The analyzer produces this diagnostic when anything other than a public
+instance member of a class is annotated with `visibleForOverriding`.
+Because only public instance members can be overridden outside the defining
+library, there's no value to annotating any other declarations.
+
+#### Example
+
+The following code produces this diagnostic because the annotation is on a
+class, and classes can't be overridden:
+
+{% prettify dart tag=pre+code %}
+import 'package:meta/meta.dart';
+
+[!@visibleForOverriding!]
+class C {}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the annotation:
+
+{% prettify dart tag=pre+code %}
+class C {}
+{% endprettify %}
+
 ### invocation_of_extension_without_call
 
 _The extension '{0}' doesn't define a 'call' method so the override can't be
@@ -9828,6 +10038,32 @@
 
 Replace the name with the name of a type.
 
+### not_binary_operator
+
+_'{0}' isn't a binary operator._
+
+#### Description
+
+The analyzer produces this diagnostic when an operator that can only be
+used as a unary operator is used as a binary operator.
+
+#### Example
+
+The following code produces this diagnostic because the operator `~` can
+only be used as a unary operator:
+
+{% prettify dart tag=pre+code %}
+var a = 5 [!~!] 3;
+{% endprettify %}
+
+#### Common fixes
+
+Replace the operator with the correct binary operator:
+
+{% prettify dart tag=pre+code %}
+var a = 5 - 3;
+{% endprettify %}
+
 ### not_enough_positional_arguments
 
 _{0} positional argument(s) expected, but {1} found._
@@ -10326,6 +10562,41 @@
 class C with M {}
 {% endprettify %}
 
+### null_argument_to_non_null_type
+
+_'{0}' shouldn't be called with a null argument for the non-nullable type
+argument '{1}'._
+
+#### Description
+
+The analyzer produces this diagnostic when `null` is passed to either the
+constructor `Future.value` or the method `Completer.complete` when the type
+argument used to create the instance was non-nullable. Even though the type
+system can't express this restriction, passing in a `null` results in a
+runtime exception.
+
+#### Example
+
+The following code produces this diagnostic because `null` is being passed
+to the constructor `Future.value` even though the type argument is the
+non-nullable type `String`:
+
+{% prettify dart tag=pre+code %}
+Future<String> f() {
+  return Future.value([!null!]);
+}
+{% endprettify %}
+
+#### Common fixes
+
+Pass in a non-null value:
+
+{% prettify dart tag=pre+code %}
+Future<String> f() {
+  return Future.value('');
+}
+{% endprettify %}
+
 ### on_repeated
 
 _The type '{0}' can be included in the superclass constraints only once._
@@ -11249,6 +11520,47 @@
 }
 {% endprettify %}
 
+### redirect_to_type_alias_expands_to_type_parameter
+
+_A redirecting constructor can't redirect to a type alias that expands to a type
+parameter._
+
+#### Description
+
+The analyzer produces this diagnostic when a redirecting factory
+constructor redirects to a type alias, and the type alias expands to one of
+the type parameters of the type alias. This isn’t allowed because the value
+of the type parameter is a type rather than a class.
+
+#### Example
+
+The following code produces this diagnostic because the redirect to `B<A>`
+is to a type alias whose value is `T`, even though it looks like the value
+should be `A`:
+
+{% prettify dart tag=pre+code %}
+class A implements C {}
+
+typedef B<T> = T;
+
+abstract class C {
+  factory C() = [!B!]<A>;
+}
+{% endprettify %}
+
+#### Common fixes
+
+Use either a class name or a type alias that is defined to be a class
+rather than a type alias defined to be a type parameter:
+
+{% prettify dart tag=pre+code %}
+class A implements C {}
+
+abstract class C {
+  factory C() = A;
+}
+{% endprettify %}
+
 ### referenced_before_declaration
 
 _Local variable '{0}' can't be referenced before it is declared._
@@ -11403,9 +11715,9 @@
 #### Description
 
 The analyzer produces this diagnostic when a generator function (one whose
-body is marked with either `async*` or `sync*`) uses a `return` statement
-to return a value. In both cases, they should use `yield` instead of
-`return`.
+body is marked with either `async*` or `sync*`) uses either a `return`
+statement to return a value or implicitly returns a value because of using
+`=>`. In any of these cases, they should use `yield` instead of `return`.
 
 #### Example
 
@@ -11418,8 +11730,24 @@
 }
 {% endprettify %}
 
+The following code produces this diagnostic because the function `f` is a
+generator and is implicitly returning a value:
+
+{% prettify dart tag=pre+code %}
+Stream<int> f() async* [!=>!] 3;
+{% endprettify %}
+
 #### Common fixes
 
+If the function is using `=>` for the body of the function, then convert it
+to a block function body, and use `yield` to return a value:
+
+{% prettify dart tag=pre+code %}
+Stream<int> f() async* {
+  yield 3;
+}
+{% endprettify %}
+
 If the method is intended to be a generator, then use `yield` to return a
 value:
 
@@ -11689,6 +12017,52 @@
 bool c = a & b;
 {% endprettify %}
 
+### sdk_version_constructor_tearoffs
+
+_Tearing off a constructor requires the 'constructor-tearoffs' language
+feature._
+
+#### Description
+
+The analyzer produces this diagnostic when a constructor tear-off is found
+in code that has an SDK constraint whose lower bound is less than 2.15.
+Constructor tear-offs weren't supported in earlier versions, so this code
+won't be able to run against earlier versions of the SDK.
+
+#### Example
+
+Here's an example of a pubspec that defines an SDK constraint with a lower
+bound of less than 2.15:
+
+```yaml
+environment:
+  sdk: '>=2.9.0 <2.15.0'
+```
+
+In the package that has that pubspec, code like the following produces this
+diagnostic:
+
+{% prettify dart tag=pre+code %}
+var setConstructor = [!Set.identity!];
+{% endprettify %}
+
+#### Common fixes
+
+If you don't need to support older versions of the SDK, then you can
+increase the SDK constraint to allow the operator to be used:
+
+```yaml
+environment:
+  sdk: '>=2.15.0 <2.16.0'
+```
+
+If you need to support older versions of the SDK, then rewrite the code to
+not use constructor tear-offs:
+
+{% prettify dart tag=pre+code %}
+var setConstructor = () => Set.identity();
+{% endprettify %}
+
 ### sdk_version_eq_eq_operator_in_const_context
 
 _Using the operator '==' for non-primitive types wasn't supported until version
@@ -12524,6 +12898,36 @@
 }
 {% endprettify %}
 
+### tearoff_of_generative_constructor_of_abstract_class
+
+_A generative constructor of an abstract class can't be torn off._
+
+#### Description
+
+The analyzer produces this diagnostic when a generative constructor from an
+abstract class is being torn off. This isn't allowed because it isn't valid
+to create an instance of an abstract class, which means that there isn't
+any valid use for the torn off constructor.
+
+#### Example
+
+The following code produces this diagnostic because the constructor `C.new`
+is being torn off and the class `C` is an abstract class:
+
+{% prettify dart tag=pre+code %}
+abstract class C {
+  C();
+}
+
+void f() {
+  [!C.new!];
+}
+{% endprettify %}
+
+#### Common fixes
+
+Tear off the constructor of a concrete class.
+
 ### throw_of_invalid_type
 
 _The type '{0}' of the thrown expression must be assignable to 'Object'._
@@ -13834,6 +14238,40 @@
 If the name is wrong, then change it to one of the names that's declared in
 the imported libraries.
 
+### undefined_referenced_parameter
+
+_The parameter '{0}' is not defined by '{1}'._
+
+#### Description
+
+The analyzer produces this diagnostic when an annotation of the form
+`@UnusedResult.unless(parameterDefined: parameterName)` specifies a
+parameter name that isn't defined by the annotated function.
+
+#### Example
+
+The following code produces this diagnostic because the function `f`
+doesn't have a parameter named `b`:
+
+{% prettify dart tag=pre+code %}
+import 'package:meta/meta.dart';
+
+@UseResult.unless(parameterDefined: [!'b'!])
+int f([int? a]) => a ?? 0;
+{% endprettify %}
+
+#### Common fixes
+
+Change the argument named `parameterDefined` to match the name of one of
+the parameters to the function:
+
+{% prettify dart tag=pre+code %}
+import 'package:meta/meta.dart';
+
+@UseResult.unless(parameterDefined: 'a')
+int f([int? a]) => a ?? 0;
+{% endprettify %}
+
 ### undefined_setter
 
 _The setter '{0}' isn't defined for the '{1}' function type._
@@ -14027,6 +14465,52 @@
   meta: ^1.0.2
 ```
 
+### unnecessary_import
+
+_The import of '{0}' is unnecessary because all of the used elements are also
+provided by the import of '{1}'._
+
+#### Description
+
+The analyzer produces this diagnostic when an import isn't needed because
+all of the names that are imported and referenced within the importing
+library are also visible through another import.
+
+#### Example
+
+Given a file named `a.dart` that contains the following:
+
+{% prettify dart tag=pre+code %}
+class A {}
+{% endprettify %}
+
+And, given a file named `b.dart` that contains the following:
+
+{% prettify dart tag=pre+code %}
+export 'a.dart';
+
+class B {}
+{% endprettify %}
+
+The following code produces this diagnostic because the class `A`, which is
+imported from `a.dart`, is also imported from `b.dart`. Removing the import
+of `a.dart` leaves the semantics unchanged:
+
+{% prettify dart tag=pre+code %}
+import [!'a.dart'!];
+import 'b.dart';
+
+void f(A a, B b) {}
+{% endprettify %}
+
+#### Common fixes
+
+If the import isn't needed, then remove it.
+
+If some of the names imported by this import are intended to be used but
+aren't yet, and if those names aren't imported by other imports, then add
+the missing references to those names.
+
 ### unnecessary_non_null_assertion
 
 _The '!' will have no effect because the receiver can't be null._
@@ -14162,6 +14646,33 @@
 }
 {% endprettify %}
 
+### unnecessary_question_mark
+
+_The '?' is unnecessary because '{0}' is nullable without it._
+
+#### Description
+
+The analyzer produces this diagnostic when either the type `dynamic` or the
+type `Null` is followed by a question mark. Both of these types are
+inherently nullable so the question mark doesn't change the semantics.
+
+#### Example
+
+The following code produces this diagnostic because the question mark
+following `dynamic` isn't necessary:
+
+{% prettify dart tag=pre+code %}
+dynamic[!?!] x;
+{% endprettify %}
+
+#### Common fixes
+
+Remove the unneeded question mark:
+
+{% prettify dart tag=pre+code %}
+dynamic x;
+{% endprettify %}
+
 ### unnecessary_type_check
 
 _Unnecessary type check; the result is always 'false'._
@@ -14441,15 +14952,24 @@
 
 #### Examples
 
-The following code produces this diagnostic because `_x` isn't referenced
-anywhere in the library:
+The following code produces this diagnostic because the field
+`_originalValue` isn't read anywhere in the library:
 
 {% prettify dart tag=pre+code %}
-class Point {
-  int [!_x!];
+class C {
+  final String [!_originalValue!];
+  final String _currentValue;
+
+  C(this._originalValue) : _currentValue = _originalValue;
+
+  String get value => _currentValue;
 }
 {% endprettify %}
 
+It might appear that the field `_originalValue` is being read in the
+initializer (`_currentValue = _originalValue`), but that is actually a
+reference to the parameter of the same name, not a reference to the field.
+
 #### Common fixes
 
 If the field isn't needed, then remove it.
@@ -14555,6 +15075,79 @@
 
 If the variable was intended to be used, then add the missing code.
 
+### unused_result
+
+_'{0}' should be used. {1}._
+
+_The value of '{0}' should be used._
+
+#### Description
+
+The analyzer produces this diagnostic when a function annotated with
+`useResult` is invoked, and the value returned by that function isn't used.
+The value is considered to be used if a member of the value is invoked, if
+the value is passed to another function, or if the value is assigned to a
+variable or field.
+
+#### Example
+
+The following code produces this diagnostic because the invocation of
+`c.a()` isn't used, even though the method `a` is annotated with
+`useResult`:
+
+{% prettify dart tag=pre+code %}
+import 'package:meta/meta.dart';
+
+class C {
+  @useResult
+  int a() => 0;
+
+  int b() => 0;
+}
+
+void f(C c) {
+  c.[!a!]();
+}
+{% endprettify %}
+
+#### Common fixes
+
+If you intended to invoke the annotated function, then use the value that
+was returned:
+
+{% prettify dart tag=pre+code %}
+import 'package:meta/meta.dart';
+
+class C {
+  @useResult
+  int a() => 0;
+
+  int b() => 0;
+}
+
+void f(C c) {
+  print(c.a());
+}
+{% endprettify %}
+
+If you intended to invoke a different function, then correct the name of
+the function being invoked:
+
+{% prettify dart tag=pre+code %}
+import 'package:meta/meta.dart';
+
+class C {
+  @useResult
+  int a() => 0;
+
+  int b() => 0;
+}
+
+void f(C c) {
+  c.b();
+}
+{% endprettify %}
+
 ### unused_shown_name
 
 _The name {0} is shown, but isn’t used._
@@ -14677,6 +15270,30 @@
 var zero = min(0, 0);
 {% endprettify %}
 
+### use_of_native_extension
+
+_Dart native extensions are deprecated and aren’t available in Dart 2.15._
+
+#### Description
+
+The analyzer produces this diagnostic when a library is imported using the
+`dart-ext` scheme.
+
+#### Example
+
+The following code produces this diagnostic because the native library `x`
+is being imported using a scheme of `dart-ext`:
+
+{% prettify dart tag=pre+code %}
+[!import 'dart-ext:x';!]
+int f() native 'string';
+{% endprettify %}
+
+#### Common fixes
+
+Rewrite the code to use `dart:ffi` as a way of invoking the contents of the
+native library.
+
 ### use_of_void_result
 
 _This expression has a type of 'void' so its value can't be used._
diff --git a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
index 2e566d7..8348e13 100644
--- a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
+++ b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
@@ -67,7 +67,7 @@
   @override
   int get hashCode => Object.hash(
         704418402,
-        content.hashCode,
+        content,
       );
 }
 
@@ -250,15 +250,15 @@
 
   @override
   int get hashCode => Object.hash(
-        severity.hashCode,
-        type.hashCode,
-        location.hashCode,
-        message.hashCode,
-        correction.hashCode,
-        code.hashCode,
-        url.hashCode,
-        contextMessages.hashCode,
-        hasFix.hashCode,
+        severity,
+        type,
+        location,
+        message,
+        correction,
+        code,
+        url,
+        contextMessages,
+        hasFix,
       );
 }
 
@@ -474,7 +474,7 @@
   @override
   int get hashCode => Object.hash(
         873118866,
-        edits.hashCode,
+        edits,
       );
 }
 
@@ -912,29 +912,29 @@
 
   @override
   int get hashCode => Object.hashAll([
-        kind.hashCode,
-        relevance.hashCode,
-        completion.hashCode,
-        displayText.hashCode,
-        replacementOffset.hashCode,
-        replacementLength.hashCode,
-        selectionOffset.hashCode,
-        selectionLength.hashCode,
-        isDeprecated.hashCode,
-        isPotential.hashCode,
-        docSummary.hashCode,
-        docComplete.hashCode,
-        declaringType.hashCode,
-        defaultArgumentListString.hashCode,
-        defaultArgumentListTextRanges.hashCode,
-        element.hashCode,
-        returnType.hashCode,
-        parameterNames.hashCode,
-        parameterTypes.hashCode,
-        requiredParameterCount.hashCode,
-        hasNamedParameters.hashCode,
-        parameterName.hashCode,
-        parameterType.hashCode,
+        kind,
+        relevance,
+        completion,
+        displayText,
+        replacementOffset,
+        replacementLength,
+        selectionOffset,
+        selectionLength,
+        isDeprecated,
+        isPotential,
+        docSummary,
+        docComplete,
+        declaringType,
+        defaultArgumentListString,
+        defaultArgumentListTextRanges,
+        element,
+        returnType,
+        parameterNames,
+        parameterTypes,
+        requiredParameterCount,
+        hasNamedParameters,
+        parameterName,
+        parameterType,
       ]);
 }
 
@@ -1131,8 +1131,8 @@
 
   @override
   int get hashCode => Object.hash(
-        message.hashCode,
-        location.hashCode,
+        message,
+        location,
       );
 }
 
@@ -1337,14 +1337,14 @@
 
   @override
   int get hashCode => Object.hash(
-        kind.hashCode,
-        name.hashCode,
-        location.hashCode,
-        flags.hashCode,
-        parameters.hashCode,
-        returnType.hashCode,
-        typeParameters.hashCode,
-        aliasedType.hashCode,
+        kind,
+        name,
+        location,
+        flags,
+        parameters,
+        returnType,
+        typeParameters,
+        aliasedType,
       );
 }
 
@@ -1741,9 +1741,9 @@
 
   @override
   int get hashCode => Object.hash(
-        kind.hashCode,
-        offset.hashCode,
-        length.hashCode,
+        kind,
+        offset,
+        length,
       );
 }
 
@@ -1821,9 +1821,9 @@
 
   @override
   int get hashCode => Object.hash(
-        type.hashCode,
-        offset.hashCode,
-        length.hashCode,
+        type,
+        offset,
+        length,
       );
 }
 
@@ -2529,11 +2529,11 @@
 
   @override
   int get hashCode => Object.hash(
-        source.hashCode,
-        kind.hashCode,
-        target.hashCode,
-        fact.hashCode,
-        value.hashCode,
+        source,
+        kind,
+        target,
+        fact,
+        value,
       );
 }
 
@@ -2641,11 +2641,11 @@
 
   @override
   int get hashCode => Object.hash(
-        signature.hashCode,
-        corpus.hashCode,
-        root.hashCode,
-        path.hashCode,
-        language.hashCode,
+        signature,
+        corpus,
+        root,
+        path,
+        language,
       );
 }
 
@@ -2750,9 +2750,9 @@
 
   @override
   int get hashCode => Object.hash(
-        positions.hashCode,
-        length.hashCode,
-        suggestions.hashCode,
+        positions,
+        length,
+        suggestions,
       );
 }
 
@@ -2817,8 +2817,8 @@
 
   @override
   int get hashCode => Object.hash(
-        value.hashCode,
-        kind.hashCode,
+        value,
+        kind,
       );
 }
 
@@ -3019,13 +3019,13 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        length.hashCode,
-        startLine.hashCode,
-        startColumn.hashCode,
-        endLine.hashCode,
-        endColumn.hashCode,
+        file,
+        offset,
+        length,
+        startLine,
+        startColumn,
+        endLine,
+        endColumn,
       );
 }
 
@@ -3105,9 +3105,9 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
-        targets.hashCode,
+        offset,
+        length,
+        targets,
       );
 }
 
@@ -3259,14 +3259,14 @@
 
   @override
   int get hashCode => Object.hash(
-        kind.hashCode,
-        fileIndex.hashCode,
-        offset.hashCode,
-        length.hashCode,
-        startLine.hashCode,
-        startColumn.hashCode,
-        codeOffset.hashCode,
-        codeLength.hashCode,
+        kind,
+        fileIndex,
+        offset,
+        length,
+        startLine,
+        startColumn,
+        codeOffset,
+        codeLength,
       );
 }
 
@@ -3345,9 +3345,9 @@
 
   @override
   int get hashCode => Object.hash(
-        element.hashCode,
-        offsets.hashCode,
-        length.hashCode,
+        element,
+        offsets,
+        length,
       );
 }
 
@@ -3477,12 +3477,12 @@
 
   @override
   int get hashCode => Object.hash(
-        element.hashCode,
-        offset.hashCode,
-        length.hashCode,
-        codeOffset.hashCode,
-        codeLength.hashCode,
-        children.hashCode,
+        element,
+        offset,
+        length,
+        codeOffset,
+        codeLength,
+        children,
       );
 }
 
@@ -3575,10 +3575,10 @@
 
   @override
   int get hashCode => Object.hash(
-        kind.hashCode,
-        name.hashCode,
-        type.hashCode,
-        defaultValue.hashCode,
+        kind,
+        name,
+        type,
+        defaultValue,
       );
 }
 
@@ -3712,8 +3712,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
+        file,
+        offset,
       );
 }
 
@@ -3925,11 +3925,11 @@
 
   @override
   int get hashCode => Object.hash(
-        id.hashCode,
-        kind.hashCode,
-        type.hashCode,
-        name.hashCode,
-        parameters.hashCode,
+        id,
+        kind,
+        type,
+        name,
+        parameters,
       );
 }
 
@@ -4071,9 +4071,9 @@
 
   @override
   int get hashCode => Object.hash(
-        severity.hashCode,
-        message.hashCode,
-        location.hashCode,
+        severity,
+        message,
+        location,
       );
 }
 
@@ -4205,7 +4205,7 @@
   }
 
   @override
-  int get hashCode => 114870849;
+  int get hashCode => 114870849.hashCode;
 }
 
 /// SourceChange
@@ -4351,11 +4351,11 @@
 
   @override
   int get hashCode => Object.hash(
-        message.hashCode,
-        edits.hashCode,
-        linkedEditGroups.hashCode,
-        selection.hashCode,
-        id.hashCode,
+        message,
+        edits,
+        linkedEditGroups,
+        selection,
+        id,
       );
 }
 
@@ -4464,10 +4464,10 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
-        replacement.hashCode,
-        id.hashCode,
+        offset,
+        length,
+        replacement,
+        id,
       );
 }
 
@@ -4560,8 +4560,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        fileStamp.hashCode,
-        edits.hashCode,
+        file,
+        fileStamp,
+        edits,
       );
 }
diff --git a/pkg/analyzer_plugin/lib/protocol/protocol_generated.dart b/pkg/analyzer_plugin/lib/protocol/protocol_generated.dart
index ac23e92..e8ee6b4 100644
--- a/pkg/analyzer_plugin/lib/protocol/protocol_generated.dart
+++ b/pkg/analyzer_plugin/lib/protocol/protocol_generated.dart
@@ -81,8 +81,8 @@
 
   @override
   int get hashCode => Object.hash(
-        error.hashCode,
-        fixes.hashCode,
+        error,
+        fixes,
       );
 }
 
@@ -162,8 +162,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        errors.hashCode,
+        file,
+        errors,
       );
 }
 
@@ -243,8 +243,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        regions.hashCode,
+        file,
+        regions,
       );
 }
 
@@ -334,9 +334,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        length.hashCode,
+        file,
+        offset,
+        length,
       );
 }
 
@@ -441,9 +441,9 @@
 
   @override
   int get hashCode => Object.hash(
-        files.hashCode,
-        targets.hashCode,
-        regions.hashCode,
+        files,
+        targets,
+        regions,
       );
 }
 
@@ -615,8 +615,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        regions.hashCode,
+        file,
+        regions,
       );
 }
 
@@ -729,10 +729,10 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        regions.hashCode,
-        targets.hashCode,
-        files.hashCode,
+        file,
+        regions,
+        targets,
+        files,
       );
 }
 
@@ -813,8 +813,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        occurrences.hashCode,
+        file,
+        occurrences,
       );
 }
 
@@ -892,8 +892,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        outline.hashCode,
+        file,
+        outline,
       );
 }
 
@@ -1411,8 +1411,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
+        file,
+        offset,
       );
 }
 
@@ -1522,9 +1522,9 @@
 
   @override
   int get hashCode => Object.hash(
-        replacementOffset.hashCode,
-        replacementLength.hashCode,
-        results.hashCode,
+        replacementOffset,
+        replacementLength,
+        results,
       );
 }
 
@@ -1607,9 +1607,9 @@
 
   @override
   int get hashCode => Object.hash(
-        root.hashCode,
-        exclude.hashCode,
-        optionsFile.hashCode,
+        root,
+        exclude,
+        optionsFile,
       );
 }
 
@@ -1764,9 +1764,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        length.hashCode,
+        file,
+        offset,
+        length,
       );
 }
 
@@ -1923,9 +1923,9 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
-        length.hashCode,
+        file,
+        offset,
+        length,
       );
 }
 
@@ -2074,8 +2074,8 @@
 
   @override
   int get hashCode => Object.hash(
-        file.hashCode,
-        offset.hashCode,
+        file,
+        offset,
       );
 }
 
@@ -2281,12 +2281,12 @@
 
   @override
   int get hashCode => Object.hash(
-        kind.hashCode,
-        file.hashCode,
-        offset.hashCode,
-        length.hashCode,
-        validateOnly.hashCode,
-        options.hashCode,
+        kind,
+        file,
+        offset,
+        length,
+        validateOnly,
+        options,
       );
 }
 
@@ -2460,12 +2460,12 @@
 
   @override
   int get hashCode => Object.hash(
-        initialProblems.hashCode,
-        optionsProblems.hashCode,
-        finalProblems.hashCode,
-        feedback.hashCode,
-        change.hashCode,
-        potentialEdits.hashCode,
+        initialProblems,
+        optionsProblems,
+        finalProblems,
+        feedback,
+        change,
+        potentialEdits,
       );
 }
 
@@ -2589,11 +2589,11 @@
 
   @override
   int get hashCode => Object.hash(
-        coveringExpressionOffsets.hashCode,
-        coveringExpressionLengths.hashCode,
-        names.hashCode,
-        offsets.hashCode,
-        lengths.hashCode,
+        coveringExpressionOffsets,
+        coveringExpressionLengths,
+        names,
+        offsets,
+        lengths,
       );
 }
 
@@ -2668,8 +2668,8 @@
 
   @override
   int get hashCode => Object.hash(
-        name.hashCode,
-        extractAll.hashCode,
+        name,
+        extractAll,
       );
 }
 
@@ -2831,14 +2831,14 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
-        returnType.hashCode,
-        names.hashCode,
-        canCreateGetter.hashCode,
-        parameters.hashCode,
-        offsets.hashCode,
-        lengths.hashCode,
+        offset,
+        length,
+        returnType,
+        names,
+        canCreateGetter,
+        parameters,
+        offsets,
+        lengths,
       );
 }
 
@@ -2973,11 +2973,11 @@
 
   @override
   int get hashCode => Object.hash(
-        returnType.hashCode,
-        createGetter.hashCode,
-        name.hashCode,
-        parameters.hashCode,
-        extractAll.hashCode,
+        returnType,
+        createGetter,
+        name,
+        parameters,
+        extractAll,
       );
 }
 
@@ -3043,8 +3043,8 @@
 
   @override
   int get hashCode => Object.hash(
-        name.hashCode,
-        occurrences.hashCode,
+        name,
+        occurrences,
       );
 }
 
@@ -3145,9 +3145,9 @@
 
   @override
   int get hashCode => Object.hash(
-        className.hashCode,
-        methodName.hashCode,
-        isDeclaration.hashCode,
+        className,
+        methodName,
+        isDeclaration,
       );
 }
 
@@ -3221,8 +3221,8 @@
 
   @override
   int get hashCode => Object.hash(
-        deleteSource.hashCode,
-        inlineAll.hashCode,
+        deleteSource,
+        inlineAll,
       );
 }
 
@@ -3373,8 +3373,8 @@
 
   @override
   int get hashCode => Object.hash(
-        entries.hashCode,
-        files.hashCode,
+        entries,
+        files,
       );
 }
 
@@ -3541,9 +3541,9 @@
 
   @override
   int get hashCode => Object.hash(
-        isFatal.hashCode,
-        message.hashCode,
-        stackTrace.hashCode,
+        isFatal,
+        message,
+        stackTrace,
       );
 }
 
@@ -3684,9 +3684,9 @@
 
   @override
   int get hashCode => Object.hash(
-        byteStorePath.hashCode,
-        sdkPath.hashCode,
-        version.hashCode,
+        byteStorePath,
+        sdkPath,
+        version,
       );
 }
 
@@ -3819,11 +3819,11 @@
 
   @override
   int get hashCode => Object.hash(
-        isCompatible.hashCode,
-        name.hashCode,
-        version.hashCode,
-        contactInfo.hashCode,
-        interestingFiles.hashCode,
+        isCompatible,
+        name,
+        version,
+        contactInfo,
+        interestingFiles,
       );
 }
 
@@ -3890,8 +3890,8 @@
 
   @override
   int get hashCode => Object.hash(
-        priority.hashCode,
-        change.hashCode,
+        priority,
+        change,
       );
 }
 
@@ -4054,10 +4054,10 @@
 
   @override
   int get hashCode => Object.hash(
-        offset.hashCode,
-        length.hashCode,
-        elementKindName.hashCode,
-        oldName.hashCode,
+        offset,
+        length,
+        elementKindName,
+        oldName,
       );
 }
 
@@ -4197,9 +4197,9 @@
 
   @override
   int get hashCode => Object.hash(
-        code.hashCode,
-        message.hashCode,
-        stackTrace.hashCode,
+        code,
+        message,
+        stackTrace,
       );
 }
 
@@ -4345,8 +4345,8 @@
 
   @override
   int get hashCode => Object.hash(
-        type.hashCode,
-        path.hashCode,
+        type,
+        path,
       );
 }
 
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart b/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart
index 5f3d9ca..c5f4cb9 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart
@@ -622,14 +622,15 @@
           if (field.value != null) {
             return field.value.hashCode.toString();
           } else {
-            return '${field.name}.hashCode';
+            return field.name;
           }
         }).toList();
 
         if (items.isEmpty) {
           writeln('0');
         } else if (items.length == 1) {
-          writeln(items.single);
+          write(items.single);
+          write('.hashCode');
         } else if (items.length <= 20) {
           writeln('Object.hash(');
           for (var field in items) {
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 38ee528..8de67b8 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -317,6 +317,8 @@
 # up with the real Dart stack trace and hence we don't get correct
 # symbol names.
 [ $arch == simarm || $arch == simarm64 || $arch == simarm64c ]
+cc/DartAPI_NativeFieldAccess: Skip # Test uses dart:ffi which is not supported on simulators.
+cc/DartAPI_NativeFieldAccess_Throws: Skip # Test uses dart:ffi which is not supported on simulators.
 cc/Dart_SetFfiNativeResolver: SkipByDesign # Test uses dart:ffi which is not supported on simulators.
 cc/Dart_SetFfiNativeResolver_DoesNotResolve: SkipByDesign # Test uses dart:ffi which is not supported on simulators.
 cc/Dart_SetFfiNativeResolver_MissingResolver: SkipByDesign # Test uses dart:ffi which is not supported on simulators.
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index 1f65f74..c17b697 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -2303,6 +2303,16 @@
   BindARMv7(label);
 }
 
+void Assembler::LoadCompressedSmi(Register dest, const Address& slot) {
+  ldr(dest, slot);
+#if defined(DEBUG)
+  Label done;
+  BranchIfSmi(dest, &done);
+  Stop("Expected Smi");
+  Bind(&done);
+#endif
+}
+
 OperandSize Address::OperandSizeFor(intptr_t cid) {
   switch (cid) {
     case kArrayCid:
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index 636d030..e98eef8 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -395,6 +395,7 @@
     LoadFromOffset(dst, base, offset);
   }
   void LoadCompressed(Register dest, const Address& slot) { ldr(dest, slot); }
+  void LoadCompressedSmi(Register dest, const Address& slot);
   void StoreMemoryValue(Register src, Register base, int32_t offset) {
     StoreToOffset(src, base, offset);
   }
@@ -429,7 +430,15 @@
     cmp(value, Operand(TMP));
   }
 
-  void CompareTypeNullabilityWith(Register type, int8_t value) {
+  void CompareFunctionTypeNullabilityWith(Register type,
+                                          int8_t value) override {
+    EnsureHasClassIdInDEBUG(kFunctionTypeCid, type, TMP);
+    ldrb(TMP, FieldAddress(
+                  type, compiler::target::FunctionType::nullability_offset()));
+    cmp(TMP, Operand(value));
+  }
+  void CompareTypeNullabilityWith(Register type, int8_t value) override {
+    EnsureHasClassIdInDEBUG(kTypeCid, type, TMP);
     ldrb(TMP, FieldAddress(type, compiler::target::Type::nullability_offset()));
     cmp(TMP, Operand(value));
   }
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index 4f214f7..4484fb5 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -646,7 +646,17 @@
     cmp(value, Operand(TMP), sz);
   }
 
-  void CompareTypeNullabilityWith(Register type, int8_t value) {
+  void CompareFunctionTypeNullabilityWith(Register type,
+                                          int8_t value) override {
+    EnsureHasClassIdInDEBUG(kFunctionTypeCid, type, TMP);
+    ldr(TMP,
+        FieldAddress(type, compiler::target::FunctionType::nullability_offset(),
+                     kByte),
+        kUnsignedByte);
+    cmp(TMP, Operand(value));
+  }
+  void CompareTypeNullabilityWith(Register type, int8_t value) override {
+    EnsureHasClassIdInDEBUG(kTypeCid, type, TMP);
     ldr(TMP,
         FieldAddress(type, compiler::target::Type::nullability_offset(), kByte),
         kUnsignedByte);
diff --git a/runtime/vm/compiler/assembler/assembler_base.h b/runtime/vm/compiler/assembler/assembler_base.h
index 9ef00e4..ad8aa79 100644
--- a/runtime/vm/compiler/assembler/assembler_base.h
+++ b/runtime/vm/compiler/assembler/assembler_base.h
@@ -718,6 +718,20 @@
                             Register address,
                             int32_t offset = 0) = 0;
 
+  // Retrieves nullability from a FunctionTypePtr in [type] and compares it
+  // to [value].
+  //
+  // TODO(dartbug.com/47034): Change how nullability is stored so that it
+  // can be accessed without checking the class id first.
+  virtual void CompareFunctionTypeNullabilityWith(Register type,
+                                                  int8_t value) = 0;
+
+  // Retrieves nullability from a TypePtr in [type] and compares it to [value].
+  //
+  // TODO(dartbug.com/47034): Change how nullability is stored so that it
+  // can be accessed without checking the class id first.
+  virtual void CompareTypeNullabilityWith(Register type, int8_t value) = 0;
+
   virtual void EnsureHasClassIdInDEBUG(intptr_t cid,
                                        Register src,
                                        Register scratch,
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index da68e52..6bd5f28 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -782,7 +782,13 @@
     cmpxchgl(address, reg);
   }
 
-  void CompareTypeNullabilityWith(Register type, int8_t value) {
+  void CompareFunctionTypeNullabilityWith(Register type,
+                                          int8_t value) override {
+    cmpb(FieldAddress(type,
+                      compiler::target::FunctionType::nullability_offset()),
+         Immediate(value));
+  }
+  void CompareTypeNullabilityWith(Register type, int8_t value) override {
     cmpb(FieldAddress(type, compiler::target::Type::nullability_offset()),
          Immediate(value));
   }
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 32646c9..237bd61 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -1102,7 +1102,15 @@
     OBJ(cmp)(value, FieldAddress(base, offset));
   }
 
-  void CompareTypeNullabilityWith(Register type, int8_t value) {
+  void CompareFunctionTypeNullabilityWith(Register type,
+                                          int8_t value) override {
+    EnsureHasClassIdInDEBUG(kFunctionTypeCid, type, TMP);
+    cmpb(FieldAddress(type,
+                      compiler::target::FunctionType::nullability_offset()),
+         Immediate(value));
+  }
+  void CompareTypeNullabilityWith(Register type, int8_t value) override {
+    EnsureHasClassIdInDEBUG(kTypeCid, type, TMP);
     cmpb(FieldAddress(type, compiler::target::Type::nullability_offset()),
          Immediate(value));
   }
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 6341678..bc544f7 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -426,14 +426,16 @@
 static constexpr dart::compiler::target::word Type_nullability_offset = 25;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 28;
 static constexpr dart::compiler::target::word
+    FunctionType_named_parameter_names_offset = 24;
+static constexpr dart::compiler::target::word FunctionType_nullability_offset =
+    39;
+static constexpr dart::compiler::target::word
     FunctionType_packed_parameter_counts_offset = 32;
 static constexpr dart::compiler::target::word
     FunctionType_packed_type_parameter_counts_offset = 36;
 static constexpr dart::compiler::target::word
     FunctionType_parameter_types_offset = 20;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 24;
-static constexpr dart::compiler::target::word
     FunctionType_type_parameters_offset = 12;
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 20;
@@ -982,14 +984,16 @@
 static constexpr dart::compiler::target::word Type_nullability_offset = 49;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
 static constexpr dart::compiler::target::word
+    FunctionType_named_parameter_names_offset = 48;
+static constexpr dart::compiler::target::word FunctionType_nullability_offset =
+    71;
+static constexpr dart::compiler::target::word
     FunctionType_packed_parameter_counts_offset = 64;
 static constexpr dart::compiler::target::word
     FunctionType_packed_type_parameter_counts_offset = 68;
 static constexpr dart::compiler::target::word
     FunctionType_parameter_types_offset = 40;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 48;
-static constexpr dart::compiler::target::word
     FunctionType_type_parameters_offset = 24;
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 40;
@@ -1531,14 +1535,16 @@
 static constexpr dart::compiler::target::word Type_nullability_offset = 25;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 28;
 static constexpr dart::compiler::target::word
+    FunctionType_named_parameter_names_offset = 24;
+static constexpr dart::compiler::target::word FunctionType_nullability_offset =
+    39;
+static constexpr dart::compiler::target::word
     FunctionType_packed_parameter_counts_offset = 32;
 static constexpr dart::compiler::target::word
     FunctionType_packed_type_parameter_counts_offset = 36;
 static constexpr dart::compiler::target::word
     FunctionType_parameter_types_offset = 20;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 24;
-static constexpr dart::compiler::target::word
     FunctionType_type_parameters_offset = 12;
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 20;
@@ -2084,14 +2090,16 @@
 static constexpr dart::compiler::target::word Type_nullability_offset = 49;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
 static constexpr dart::compiler::target::word
+    FunctionType_named_parameter_names_offset = 48;
+static constexpr dart::compiler::target::word FunctionType_nullability_offset =
+    71;
+static constexpr dart::compiler::target::word
     FunctionType_packed_parameter_counts_offset = 64;
 static constexpr dart::compiler::target::word
     FunctionType_packed_type_parameter_counts_offset = 68;
 static constexpr dart::compiler::target::word
     FunctionType_parameter_types_offset = 40;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 48;
-static constexpr dart::compiler::target::word
     FunctionType_type_parameters_offset = 24;
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 40;
@@ -2640,14 +2648,16 @@
 static constexpr dart::compiler::target::word Type_nullability_offset = 37;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
+    FunctionType_named_parameter_names_offset = 36;
+static constexpr dart::compiler::target::word FunctionType_nullability_offset =
+    51;
+static constexpr dart::compiler::target::word
     FunctionType_packed_parameter_counts_offset = 44;
 static constexpr dart::compiler::target::word
     FunctionType_packed_type_parameter_counts_offset = 48;
 static constexpr dart::compiler::target::word
     FunctionType_parameter_types_offset = 32;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 36;
-static constexpr dart::compiler::target::word
     FunctionType_type_parameters_offset = 24;
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 32;
@@ -3195,14 +3205,16 @@
 static constexpr dart::compiler::target::word Type_nullability_offset = 37;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
+    FunctionType_named_parameter_names_offset = 36;
+static constexpr dart::compiler::target::word FunctionType_nullability_offset =
+    51;
+static constexpr dart::compiler::target::word
     FunctionType_packed_parameter_counts_offset = 44;
 static constexpr dart::compiler::target::word
     FunctionType_packed_type_parameter_counts_offset = 48;
 static constexpr dart::compiler::target::word
     FunctionType_parameter_types_offset = 32;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 36;
-static constexpr dart::compiler::target::word
     FunctionType_type_parameters_offset = 24;
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 32;
@@ -3741,14 +3753,16 @@
 static constexpr dart::compiler::target::word Type_nullability_offset = 25;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 28;
 static constexpr dart::compiler::target::word
+    FunctionType_named_parameter_names_offset = 24;
+static constexpr dart::compiler::target::word FunctionType_nullability_offset =
+    39;
+static constexpr dart::compiler::target::word
     FunctionType_packed_parameter_counts_offset = 32;
 static constexpr dart::compiler::target::word
     FunctionType_packed_type_parameter_counts_offset = 36;
 static constexpr dart::compiler::target::word
     FunctionType_parameter_types_offset = 20;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 24;
-static constexpr dart::compiler::target::word
     FunctionType_type_parameters_offset = 12;
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 20;
@@ -4291,14 +4305,16 @@
 static constexpr dart::compiler::target::word Type_nullability_offset = 49;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
 static constexpr dart::compiler::target::word
+    FunctionType_named_parameter_names_offset = 48;
+static constexpr dart::compiler::target::word FunctionType_nullability_offset =
+    71;
+static constexpr dart::compiler::target::word
     FunctionType_packed_parameter_counts_offset = 64;
 static constexpr dart::compiler::target::word
     FunctionType_packed_type_parameter_counts_offset = 68;
 static constexpr dart::compiler::target::word
     FunctionType_parameter_types_offset = 40;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 48;
-static constexpr dart::compiler::target::word
     FunctionType_type_parameters_offset = 24;
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 40;
@@ -4834,14 +4850,16 @@
 static constexpr dart::compiler::target::word Type_nullability_offset = 25;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 28;
 static constexpr dart::compiler::target::word
+    FunctionType_named_parameter_names_offset = 24;
+static constexpr dart::compiler::target::word FunctionType_nullability_offset =
+    39;
+static constexpr dart::compiler::target::word
     FunctionType_packed_parameter_counts_offset = 32;
 static constexpr dart::compiler::target::word
     FunctionType_packed_type_parameter_counts_offset = 36;
 static constexpr dart::compiler::target::word
     FunctionType_parameter_types_offset = 20;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 24;
-static constexpr dart::compiler::target::word
     FunctionType_type_parameters_offset = 12;
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 20;
@@ -5381,14 +5399,16 @@
 static constexpr dart::compiler::target::word Type_nullability_offset = 49;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 56;
 static constexpr dart::compiler::target::word
+    FunctionType_named_parameter_names_offset = 48;
+static constexpr dart::compiler::target::word FunctionType_nullability_offset =
+    71;
+static constexpr dart::compiler::target::word
     FunctionType_packed_parameter_counts_offset = 64;
 static constexpr dart::compiler::target::word
     FunctionType_packed_type_parameter_counts_offset = 68;
 static constexpr dart::compiler::target::word
     FunctionType_parameter_types_offset = 40;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 48;
-static constexpr dart::compiler::target::word
     FunctionType_type_parameters_offset = 24;
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 40;
@@ -5931,14 +5951,16 @@
 static constexpr dart::compiler::target::word Type_nullability_offset = 37;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
+    FunctionType_named_parameter_names_offset = 36;
+static constexpr dart::compiler::target::word FunctionType_nullability_offset =
+    51;
+static constexpr dart::compiler::target::word
     FunctionType_packed_parameter_counts_offset = 44;
 static constexpr dart::compiler::target::word
     FunctionType_packed_type_parameter_counts_offset = 48;
 static constexpr dart::compiler::target::word
     FunctionType_parameter_types_offset = 32;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 36;
-static constexpr dart::compiler::target::word
     FunctionType_type_parameters_offset = 24;
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 32;
@@ -6480,14 +6502,16 @@
 static constexpr dart::compiler::target::word Type_nullability_offset = 37;
 static constexpr dart::compiler::target::word FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
+    FunctionType_named_parameter_names_offset = 36;
+static constexpr dart::compiler::target::word FunctionType_nullability_offset =
+    51;
+static constexpr dart::compiler::target::word
     FunctionType_packed_parameter_counts_offset = 44;
 static constexpr dart::compiler::target::word
     FunctionType_packed_type_parameter_counts_offset = 48;
 static constexpr dart::compiler::target::word
     FunctionType_parameter_types_offset = 32;
 static constexpr dart::compiler::target::word
-    FunctionType_named_parameter_names_offset = 36;
-static constexpr dart::compiler::target::word
     FunctionType_type_parameters_offset = 24;
 static constexpr dart::compiler::target::word
     TypeParameter_parameterized_class_id_offset = 32;
@@ -7076,14 +7100,16 @@
 static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 25;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 28;
 static constexpr dart::compiler::target::word
+    AOT_FunctionType_named_parameter_names_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_FunctionType_nullability_offset = 39;
+static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_parameter_counts_offset = 32;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_type_parameter_counts_offset = 36;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_parameter_types_offset = 20;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 24;
-static constexpr dart::compiler::target::word
     AOT_FunctionType_type_parameters_offset = 12;
 static constexpr dart::compiler::target::word
     AOT_TypeParameter_parameterized_class_id_offset = 20;
@@ -7692,14 +7718,16 @@
 static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 49;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
 static constexpr dart::compiler::target::word
+    AOT_FunctionType_named_parameter_names_offset = 48;
+static constexpr dart::compiler::target::word
+    AOT_FunctionType_nullability_offset = 71;
+static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_parameter_counts_offset = 64;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_type_parameter_counts_offset = 68;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_parameter_types_offset = 40;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 48;
-static constexpr dart::compiler::target::word
     AOT_FunctionType_type_parameters_offset = 24;
 static constexpr dart::compiler::target::word
     AOT_TypeParameter_parameterized_class_id_offset = 40;
@@ -8313,14 +8341,16 @@
 static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 49;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
 static constexpr dart::compiler::target::word
+    AOT_FunctionType_named_parameter_names_offset = 48;
+static constexpr dart::compiler::target::word
+    AOT_FunctionType_nullability_offset = 71;
+static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_parameter_counts_offset = 64;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_type_parameter_counts_offset = 68;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_parameter_types_offset = 40;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 48;
-static constexpr dart::compiler::target::word
     AOT_FunctionType_type_parameters_offset = 24;
 static constexpr dart::compiler::target::word
     AOT_TypeParameter_parameterized_class_id_offset = 40;
@@ -8931,14 +8961,16 @@
 static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 37;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
+    AOT_FunctionType_named_parameter_names_offset = 36;
+static constexpr dart::compiler::target::word
+    AOT_FunctionType_nullability_offset = 51;
+static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_parameter_counts_offset = 44;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_type_parameter_counts_offset = 48;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_parameter_types_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 36;
-static constexpr dart::compiler::target::word
     AOT_FunctionType_type_parameters_offset = 24;
 static constexpr dart::compiler::target::word
     AOT_TypeParameter_parameterized_class_id_offset = 32;
@@ -9548,14 +9580,16 @@
 static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 37;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
+    AOT_FunctionType_named_parameter_names_offset = 36;
+static constexpr dart::compiler::target::word
+    AOT_FunctionType_nullability_offset = 51;
+static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_parameter_counts_offset = 44;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_type_parameter_counts_offset = 48;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_parameter_types_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 36;
-static constexpr dart::compiler::target::word
     AOT_FunctionType_type_parameters_offset = 24;
 static constexpr dart::compiler::target::word
     AOT_TypeParameter_parameterized_class_id_offset = 32;
@@ -10160,14 +10194,16 @@
 static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 25;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 28;
 static constexpr dart::compiler::target::word
+    AOT_FunctionType_named_parameter_names_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_FunctionType_nullability_offset = 39;
+static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_parameter_counts_offset = 32;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_type_parameter_counts_offset = 36;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_parameter_types_offset = 20;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 24;
-static constexpr dart::compiler::target::word
     AOT_FunctionType_type_parameters_offset = 12;
 static constexpr dart::compiler::target::word
     AOT_TypeParameter_parameterized_class_id_offset = 20;
@@ -10769,14 +10805,16 @@
 static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 49;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
 static constexpr dart::compiler::target::word
+    AOT_FunctionType_named_parameter_names_offset = 48;
+static constexpr dart::compiler::target::word
+    AOT_FunctionType_nullability_offset = 71;
+static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_parameter_counts_offset = 64;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_type_parameter_counts_offset = 68;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_parameter_types_offset = 40;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 48;
-static constexpr dart::compiler::target::word
     AOT_FunctionType_type_parameters_offset = 24;
 static constexpr dart::compiler::target::word
     AOT_TypeParameter_parameterized_class_id_offset = 40;
@@ -11383,14 +11421,16 @@
 static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 49;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 56;
 static constexpr dart::compiler::target::word
+    AOT_FunctionType_named_parameter_names_offset = 48;
+static constexpr dart::compiler::target::word
+    AOT_FunctionType_nullability_offset = 71;
+static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_parameter_counts_offset = 64;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_type_parameter_counts_offset = 68;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_parameter_types_offset = 40;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 48;
-static constexpr dart::compiler::target::word
     AOT_FunctionType_type_parameters_offset = 24;
 static constexpr dart::compiler::target::word
     AOT_TypeParameter_parameterized_class_id_offset = 40;
@@ -11994,14 +12034,16 @@
 static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 37;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
+    AOT_FunctionType_named_parameter_names_offset = 36;
+static constexpr dart::compiler::target::word
+    AOT_FunctionType_nullability_offset = 51;
+static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_parameter_counts_offset = 44;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_type_parameter_counts_offset = 48;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_parameter_types_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 36;
-static constexpr dart::compiler::target::word
     AOT_FunctionType_type_parameters_offset = 24;
 static constexpr dart::compiler::target::word
     AOT_TypeParameter_parameterized_class_id_offset = 32;
@@ -12604,14 +12646,16 @@
 static constexpr dart::compiler::target::word AOT_Type_nullability_offset = 37;
 static constexpr dart::compiler::target::word AOT_FunctionType_hash_offset = 40;
 static constexpr dart::compiler::target::word
+    AOT_FunctionType_named_parameter_names_offset = 36;
+static constexpr dart::compiler::target::word
+    AOT_FunctionType_nullability_offset = 51;
+static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_parameter_counts_offset = 44;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_packed_type_parameter_counts_offset = 48;
 static constexpr dart::compiler::target::word
     AOT_FunctionType_parameter_types_offset = 32;
 static constexpr dart::compiler::target::word
-    AOT_FunctionType_named_parameter_names_offset = 36;
-static constexpr dart::compiler::target::word
     AOT_FunctionType_type_parameters_offset = 24;
 static constexpr dart::compiler::target::word
     AOT_TypeParameter_parameterized_class_id_offset = 32;
diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h
index 510ef0e..88ab5b2 100644
--- a/runtime/vm/compiler/runtime_offsets_list.h
+++ b/runtime/vm/compiler/runtime_offsets_list.h
@@ -294,10 +294,11 @@
   FIELD(Type, type_state_offset)                                               \
   FIELD(Type, nullability_offset)                                              \
   FIELD(FunctionType, hash_offset)                                             \
+  FIELD(FunctionType, named_parameter_names_offset)                            \
+  FIELD(FunctionType, nullability_offset)                                      \
   FIELD(FunctionType, packed_parameter_counts_offset)                          \
   FIELD(FunctionType, packed_type_parameter_counts_offset)                     \
   FIELD(FunctionType, parameter_types_offset)                                  \
-  FIELD(FunctionType, named_parameter_names_offset)                            \
   FIELD(FunctionType, type_parameters_offset)                                  \
   FIELD(TypeParameter, parameterized_class_id_offset)                          \
   FIELD(TypeParameter, index_offset)                                           \
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index bf28845..6adbe81 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -339,9 +339,18 @@
 struct TTSInternalRegs {
   static const Register kInstanceTypeArgumentsReg = R4;
   static const Register kScratchReg = R9;
+  static const Register kSubTypeArgumentReg = R3;
+  static const Register kSuperTypeArgumentReg = R8;
+
+  // Must be pushed/popped whenever generic type arguments are being checked as
+  // they overlap with registers in TypeTestABI.
+  static const intptr_t kSavedTypeArgumentRegisters =
+      (1 << kSubTypeArgumentReg) | (1 << kSuperTypeArgumentReg);
 
   static const intptr_t kInternalRegisters =
-      (1 << kInstanceTypeArgumentsReg) | (1 << kScratchReg);
+      ((1 << kInstanceTypeArgumentsReg) | (1 << kScratchReg) |
+       (1 << kSubTypeArgumentReg) | (1 << kSuperTypeArgumentReg)) &
+      ~kSavedTypeArgumentRegisters;
 };
 
 // Registers in addition to those listed in TypeTestABI used inside the
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 2279f02..e23657c 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -172,9 +172,17 @@
 struct TTSInternalRegs {
   static const Register kInstanceTypeArgumentsReg = R7;
   static const Register kScratchReg = R9;
+  static const Register kSubTypeArgumentReg = R5;
+  static const Register kSuperTypeArgumentReg = R6;
+
+  // Must be pushed/popped whenever generic type arguments are being checked as
+  // they overlap with registers in TypeTestABI.
+  static const intptr_t kSavedTypeArgumentRegisters = 0;
 
   static const intptr_t kInternalRegisters =
-      (1 << kInstanceTypeArgumentsReg) | (1 << kScratchReg);
+      ((1 << kInstanceTypeArgumentsReg) | (1 << kScratchReg) |
+       (1 << kSubTypeArgumentReg) | (1 << kSuperTypeArgumentReg)) &
+      ~kSavedTypeArgumentRegisters;
 };
 
 // Registers in addition to those listed in TypeTestABI used inside the
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index c776976..eb24c81 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -148,9 +148,17 @@
 struct TTSInternalRegs {
   static const Register kInstanceTypeArgumentsReg = RSI;
   static const Register kScratchReg = R8;
+  static const Register kSubTypeArgumentReg = R10;
+  static const Register kSuperTypeArgumentReg = R13;
+
+  // Must be pushed/popped whenever generic type arguments are being checked as
+  // they overlap with registers in TypeTestABI.
+  static const intptr_t kSavedTypeArgumentRegisters = 0;
 
   static const intptr_t kInternalRegisters =
-      (1 << kInstanceTypeArgumentsReg) | (1 << kScratchReg);
+      ((1 << kInstanceTypeArgumentsReg) | (1 << kScratchReg) |
+       (1 << kSubTypeArgumentReg) | (1 << kSuperTypeArgumentReg)) &
+      ~kSavedTypeArgumentRegisters;
 };
 
 // Registers in addition to those listed in TypeTestABI used inside the
diff --git a/runtime/vm/type_testing_stubs.cc b/runtime/vm/type_testing_stubs.cc
index a7de67d..8b57841 100644
--- a/runtime/vm/type_testing_stubs.cc
+++ b/runtime/vm/type_testing_stubs.cc
@@ -4,7 +4,10 @@
 
 #include <functional>
 
+#include "platform/globals.h"
+#include "vm/class_id.h"
 #include "vm/compiler/assembler/disassembler.h"
+#include "vm/compiler/runtime_api.h"
 #include "vm/hash_map.h"
 #include "vm/longjump.h"
 #include "vm/object_store.h"
@@ -329,7 +332,7 @@
 
   if (type.IsObjectType()) {
     ASSERT(type.IsNonNullable() &&
-           IsolateGroup::Current()->use_strict_null_safety_checks());
+           hi->thread()->isolate_group()->use_strict_null_safety_checks());
     compiler::Label is_null;
     __ CompareObject(TypeTestABI::kInstanceReg, Object::null_object());
     __ BranchIf(EQUAL, &is_null, compiler::Assembler::kNearJump);
@@ -621,6 +624,11 @@
     }
 
     // c) Then we'll check each value of the type argument.
+    compiler::Label pop_saved_registers_on_failure;
+    const RegisterSet saved_registers(
+        TTSInternalRegs::kSavedTypeArgumentRegisters);
+    __ PushRegisters(saved_registers);
+
     AbstractType& type_arg = AbstractType::Handle();
     const TypeArguments& ta = TypeArguments::Handle(type.arguments());
     const intptr_t num_type_parameters = type_class.NumTypeParameters();
@@ -634,10 +642,20 @@
       ASSERT(type_arg.IsTypeParameter() ||
              hi->CanUseSubtypeRangeCheckFor(type_arg));
 
-      BuildOptimizedTypeArgumentValueCheck(
-          assembler, hi, type_arg, type_param_value_offset_i, &check_failed);
+      if (type_arg.IsTypeParameter()) {
+        BuildOptimizedTypeParameterArgumentValueCheck(
+            assembler, hi, TypeParameter::Cast(type_arg),
+            type_param_value_offset_i, &pop_saved_registers_on_failure);
+      } else {
+        BuildOptimizedTypeArgumentValueCheck(
+            assembler, hi, Type::Cast(type_arg), type_param_value_offset_i,
+            &pop_saved_registers_on_failure);
+      }
     }
+    __ PopRegisters(saved_registers);
     __ Ret();
+    __ Bind(&pop_saved_registers_on_failure);
+    __ PopRegisters(saved_registers);
   }
 
   // If anything fails.
@@ -928,110 +946,259 @@
   return !type_argument_checks.is_empty();
 }
 
+// Unwraps TypeRefs, jumping to the appropriate label for the unwrapped type
+// if that label is not nullptr and otherwise falling through.
+//
+// [type_reg] must contain an AbstractTypePtr, and [scratch] must be distinct
+// from [type_reg]. Clobbers [type_reg] with the unwrapped type.
+static void UnwrapAbstractType(compiler::Assembler* assembler,
+                               Register type_reg,
+                               Register scratch,
+                               compiler::Label* is_type = nullptr,
+                               compiler::Label* is_function_type = nullptr,
+                               compiler::Label* is_type_parameter = nullptr) {
+  ASSERT(scratch != type_reg);
+  compiler::Label cid_checks, fall_through;
+  // TypeRefs never wrap other TypeRefs, so we only need to unwrap once.
+  __ LoadClassId(scratch, type_reg);
+  __ CompareImmediate(scratch, kTypeRefCid);
+  __ BranchIf(NOT_EQUAL, &cid_checks, compiler::Assembler::kNearJump);
+  __ LoadCompressedFieldFromOffset(type_reg, type_reg,
+                                   compiler::target::TypeRef::type_offset());
+  // Only load the class id of the unwrapped type if it will be checked below.
+  if (is_type != nullptr || is_function_type != nullptr ||
+      is_type_parameter != nullptr) {
+    __ LoadClassId(scratch, type_reg);
+  }
+  __ Bind(&cid_checks);
+  if (is_type != nullptr) {
+    __ CompareImmediate(scratch, kTypeCid);
+    __ BranchIf(EQUAL, is_type);
+  }
+  if (is_function_type != nullptr) {
+    __ CompareImmediate(scratch, kFunctionTypeCid);
+    __ BranchIf(EQUAL, is_function_type);
+  }
+  if (is_type_parameter != nullptr) {
+    __ CompareImmediate(scratch, kTypeParameterCid);
+    __ BranchIf(EQUAL, is_type_parameter);
+  }
+}
+
+// src must contain a TypePtr. Assumes dst != src. May affect flags.
+static void LoadTypeClassId(compiler::Assembler* assembler,
+                            Register dst,
+                            Register src) {
+  ASSERT(src != dst);
+  __ EnsureHasClassIdInDEBUG(kTypeCid, src, dst);
+  __ LoadCompressedSmi(
+      dst, compiler::FieldAddress(
+               src, compiler::target::Type::type_class_id_offset()));
+  __ SmiUntag(dst);
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeParameterArgumentValueCheck(
+    compiler::Assembler* assembler,
+    HierarchyInfo* hi,
+    const TypeParameter& type_param,
+    intptr_t type_param_value_offset_i,
+    compiler::Label* check_failed) {
+  if (assembler->EmittingComments()) {
+    TextBuffer buffer(128);
+    buffer.Printf("Generating check for type argument %" Pd ": ",
+                  type_param_value_offset_i);
+    type_param.PrintName(Object::kScrubbedName, &buffer);
+    __ Comment("%s", buffer.buffer());
+  }
+
+  const Register kTypeArgumentsReg =
+      type_param.IsClassTypeParameter()
+          ? TypeTestABI::kInstantiatorTypeArgumentsReg
+          : TypeTestABI::kFunctionTypeArgumentsReg;
+
+  const bool strict_null_safety =
+      hi->thread()->isolate_group()->use_strict_null_safety_checks();
+  compiler::Label is_subtype;
+  // TODO(dartbug.com/46920): Currently only canonical equality (identity)
+  // and some top and bottom types are checked.
+  __ CompareObject(kTypeArgumentsReg, Object::null_object());
+  __ BranchIf(EQUAL, &is_subtype);
+
+  __ LoadCompressedFieldFromOffset(
+      TTSInternalRegs::kSuperTypeArgumentReg, kTypeArgumentsReg,
+      compiler::target::TypeArguments::type_at_offset(type_param.index()));
+  __ LoadCompressedFieldFromOffset(
+      TTSInternalRegs::kSubTypeArgumentReg,
+      TTSInternalRegs::kInstanceTypeArgumentsReg,
+      compiler::target::TypeArguments::type_at_offset(
+          type_param_value_offset_i));
+  __ CompareRegisters(TTSInternalRegs::kSuperTypeArgumentReg,
+                      TTSInternalRegs::kSubTypeArgumentReg);
+  __ BranchIf(EQUAL, &is_subtype);
+
+  __ Comment("Checking instantiated type parameter for possible top types");
+  compiler::Label check_subtype_type_class_ids;
+  UnwrapAbstractType(assembler, TTSInternalRegs::kSuperTypeArgumentReg,
+                     TTSInternalRegs::kScratchReg, /*is_type=*/nullptr,
+                     &check_subtype_type_class_ids);
+  LoadTypeClassId(assembler, TTSInternalRegs::kScratchReg,
+                  TTSInternalRegs::kSuperTypeArgumentReg);
+  __ CompareImmediate(TTSInternalRegs::kScratchReg, kDynamicCid);
+  __ BranchIf(EQUAL, &is_subtype);
+  __ CompareImmediate(TTSInternalRegs::kScratchReg, kVoidCid);
+  __ BranchIf(EQUAL, &is_subtype);
+  __ CompareImmediate(TTSInternalRegs::kScratchReg, kInstanceCid);
+  if (strict_null_safety) {
+    __ BranchIf(NOT_EQUAL, &check_subtype_type_class_ids);
+    // If non-nullable Object, then the subtype must be legacy or non-nullable.
+    __ CompareTypeNullabilityWith(
+        TTSInternalRegs::kSuperTypeArgumentReg,
+        static_cast<int8_t>(Nullability::kNonNullable));
+    __ BranchIf(NOT_EQUAL, &is_subtype);
+    __ Comment("Checking for legacy or non-nullable instance type argument");
+    compiler::Label subtype_is_type;
+    UnwrapAbstractType(assembler, TTSInternalRegs::kSubTypeArgumentReg,
+                       TTSInternalRegs::kScratchReg, &subtype_is_type);
+    __ CompareFunctionTypeNullabilityWith(
+        TTSInternalRegs::kSubTypeArgumentReg,
+        static_cast<int8_t>(Nullability::kNullable));
+    __ BranchIf(EQUAL, check_failed);
+    __ Jump(&is_subtype);
+    __ Bind(&subtype_is_type);
+    __ CompareTypeNullabilityWith(TTSInternalRegs::kSubTypeArgumentReg,
+                                  static_cast<int8_t>(Nullability::kNullable));
+    __ BranchIf(EQUAL, check_failed);
+    __ Jump(&is_subtype);
+  } else {
+    __ BranchIf(EQUAL, &is_subtype, compiler::Assembler::kNearJump);
+  }
+
+  __ Bind(&check_subtype_type_class_ids);
+  __ Comment("Checking instance type argument for possible bottom types");
+  // Nothing else to check for non-Types, so fall back to the slow stub.
+  UnwrapAbstractType(assembler, TTSInternalRegs::kSubTypeArgumentReg,
+                     TTSInternalRegs::kScratchReg, /*is_type=*/nullptr,
+                     check_failed);
+  LoadTypeClassId(assembler, TTSInternalRegs::kScratchReg,
+                  TTSInternalRegs::kSubTypeArgumentReg);
+  __ CompareImmediate(TTSInternalRegs::kScratchReg, kNeverCid);
+  __ BranchIf(EQUAL, &is_subtype);
+  __ CompareImmediate(TTSInternalRegs::kScratchReg, kNullCid);
+  // Last possible check, so fall back to slow stub on failure.
+  __ BranchIf(NOT_EQUAL, check_failed);
+  if (strict_null_safety) {
+    // Only nullable or legacy types can be a supertype of Null.
+    __ Comment("Checking for legacy or nullable instantiated type parameter");
+    compiler::Label supertype_is_type;
+    UnwrapAbstractType(assembler, TTSInternalRegs::kSuperTypeArgumentReg,
+                       TTSInternalRegs::kScratchReg, &supertype_is_type);
+    __ CompareFunctionTypeNullabilityWith(
+        TTSInternalRegs::kSuperTypeArgumentReg,
+        static_cast<int8_t>(Nullability::kNonNullable));
+    __ BranchIf(EQUAL, check_failed);
+    __ Jump(&is_subtype, compiler::Assembler::kNearJump);
+    __ Bind(&supertype_is_type);
+    __ CompareTypeNullabilityWith(
+        TTSInternalRegs::kSuperTypeArgumentReg,
+        static_cast<int8_t>(Nullability::kNonNullable));
+    __ BranchIf(EQUAL, check_failed);
+  }
+
+  __ Bind(&is_subtype);
+}
+
 // Generate code to verify that instance's type argument is a subtype of
 // 'type_arg'.
 void TypeTestingStubGenerator::BuildOptimizedTypeArgumentValueCheck(
     compiler::Assembler* assembler,
     HierarchyInfo* hi,
-    const AbstractType& type_arg,
+    const Type& type,
     intptr_t type_param_value_offset_i,
     compiler::Label* check_failed) {
-  if (type_arg.IsTopTypeForSubtyping()) {
+  ASSERT(type.IsInstantiated());
+  if (type.IsTopTypeForSubtyping()) {
     return;
   }
 
+  const bool strict_null_safety =
+      hi->thread()->isolate_group()->use_strict_null_safety_checks();
+  ASSERT(!type.IsObjectType() || (strict_null_safety && type.IsNonNullable()));
+
   if (assembler->EmittingComments()) {
     TextBuffer buffer(128);
     buffer.Printf("Generating check for type argument %" Pd ": ",
                   type_param_value_offset_i);
-    type_arg.PrintName(Object::kScrubbedName, &buffer);
+    type.PrintName(Object::kScrubbedName, &buffer);
     __ Comment("%s", buffer.buffer());
   }
-  if (type_arg.IsTypeParameter()) {
-    const TypeParameter& type_param = TypeParameter::Cast(type_arg);
-    const Register kTypeArgumentsReg =
-        type_param.IsClassTypeParameter()
-            ? TypeTestABI::kInstantiatorTypeArgumentsReg
-            : TypeTestABI::kFunctionTypeArgumentsReg;
 
-    compiler::Label is_dynamic;
-    __ CompareObject(kTypeArgumentsReg, Object::null_object());
-    __ BranchIf(EQUAL, &is_dynamic, compiler::Assembler::kNearJump);
-
-    // TODO(dartbug.com/46920): Currently only canonical equality (identity)
-    // is checked.
-    __ LoadCompressedFieldFromOffset(
-        TTSInternalRegs::kScratchReg, kTypeArgumentsReg,
-        compiler::target::TypeArguments::type_at_offset(type_param.index()));
-    __ CompareWithCompressedFieldFromOffset(
-        TTSInternalRegs::kScratchReg,
-        TTSInternalRegs::kInstanceTypeArgumentsReg,
-        compiler::target::TypeArguments::type_at_offset(
-            type_param_value_offset_i));
-    __ BranchIf(NOT_EQUAL, check_failed);
-    __ Bind(&is_dynamic);
-  } else {
-    __ LoadCompressedFieldFromOffset(
-        TTSInternalRegs::kScratchReg,
-        TTSInternalRegs::kInstanceTypeArgumentsReg,
-        compiler::target::TypeArguments::type_at_offset(
-            type_param_value_offset_i));
-    if (type_arg.IsObjectType()) {
-      // Just check the nullability, since this must be non-nullable Object
-      // and we must be in null safe mode.
-      ASSERT(IsolateGroup::Current()->use_strict_null_safety_checks() &&
-             type_arg.IsNonNullable());
-      __ CompareTypeNullabilityWith(TTSInternalRegs::kScratchReg,
-                                    compiler::target::Nullability::kNullable);
+  compiler::Label is_subtype, check_subtype_cid, sub_is_function_type,
+      sub_is_type;
+  __ LoadCompressedFieldFromOffset(
+      TTSInternalRegs::kSubTypeArgumentReg,
+      TTSInternalRegs::kInstanceTypeArgumentsReg,
+      compiler::target::TypeArguments::type_at_offset(
+          type_param_value_offset_i));
+  __ Bind(&check_subtype_cid);
+  UnwrapAbstractType(assembler, TTSInternalRegs::kSubTypeArgumentReg,
+                     TTSInternalRegs::kScratchReg, &sub_is_type);
+  __ Comment("Checks for FunctionType");
+  __ EnsureHasClassIdInDEBUG(kFunctionTypeCid,
+                             TTSInternalRegs::kSubTypeArgumentReg,
+                             TTSInternalRegs::kScratchReg);
+  if (type.IsObjectType() || type.IsDartFunctionType()) {
+    if (strict_null_safety && type.IsNonNullable()) {
+      // Nullable types cannot be a subtype of a non-nullable type.
+      __ CompareFunctionTypeNullabilityWith(
+          TTSInternalRegs::kSubTypeArgumentReg,
+          compiler::target::Nullability::kNullable);
       __ BranchIf(EQUAL, check_failed);
-    } else {
-      __ LoadCompressedFieldFromOffset(
-          TTSInternalRegs::kScratchReg, TTSInternalRegs::kScratchReg,
-          compiler::target::Type::type_class_id_offset());
-
-      const Class& type_class = Class::Handle(type_arg.type_class());
-      const bool null_is_assignable = Instance::NullIsAssignableTo(type_arg);
-      const CidRangeVector& ranges =
-          hi->SubtypeRangesForClass(type_class,
-                                    /*include_abstract=*/true,
-                                    /*exclude_null=*/!null_is_assignable);
-
-      compiler::Label is_subtype;
-      __ SmiUntag(TTSInternalRegs::kScratchReg);
-      // Never is a bottom type.
-      __ CompareImmediate(TTSInternalRegs::kScratchReg, kNeverCid);
-      __ BranchIf(EQUAL, &is_subtype);
-      if (null_is_assignable) {
-        __ CompareImmediate(TTSInternalRegs::kScratchReg, kNullCid);
-        __ BranchIf(EQUAL, &is_subtype);
-      }
-      compiler::Label check_nullability;
-      BuildOptimizedSubtypeRangeCheck(assembler, ranges,
-                                      TTSInternalRegs::kScratchReg,
-                                      &check_nullability, check_failed);
-      __ Bind(&check_nullability);
-
-      // Weak NNBD mode uses LEGACY_SUBTYPE which ignores nullability.
-      // We don't need to check nullability of LHS for nullable and legacy RHS
-      // ("Right Legacy", "Right Nullable" rules).
-      if (IsolateGroup::Current()->use_strict_null_safety_checks() &&
-          type_arg.IsNonNullable()) {
-        // Nullable type is not a subtype of non-nullable type.
-        // TODO(dartbug.com/40736): Allocate a register for instance type
-        // argument and avoid reloading it.
-        __ LoadCompressedFieldFromOffset(
-            TTSInternalRegs::kScratchReg,
-            TTSInternalRegs::kInstanceTypeArgumentsReg,
-            compiler::target::TypeArguments::type_at_offset(
-                type_param_value_offset_i));
-        __ CompareTypeNullabilityWith(TTSInternalRegs::kScratchReg,
-                                      compiler::target::Nullability::kNullable);
-        __ BranchIf(EQUAL, check_failed);
-      }
-
-      __ Bind(&is_subtype);
     }
+    // No further checks needed for non-nullable Object or Function.
+    __ Jump(&is_subtype, compiler::Assembler::kNearJump);
+  } else {
+    // _Closure <: Function, and T <: Function for any FunctionType T, but
+    // T </: _Closure, so we _don't_ want to fall back to cid tests. Instead,
+    // just let the STC/runtime handle any possible false negatives here.
+    __ Jump(check_failed);
   }
+
+  __ Comment("Checks for Type");
+  __ Bind(&sub_is_type);
+  if (strict_null_safety && type.IsNonNullable()) {
+    // Nullable types cannot be a subtype of a non-nullable type in strict mode.
+    __ CompareTypeNullabilityWith(TTSInternalRegs::kSubTypeArgumentReg,
+                                  compiler::target::Nullability::kNullable);
+    __ BranchIf(EQUAL, check_failed);
+    // Fall through to bottom type checks.
+  }
+
+  // No further checks needed for non-nullable object.
+  if (!type.IsObjectType()) {
+    LoadTypeClassId(assembler, TTSInternalRegs::kScratchReg,
+                    TTSInternalRegs::kSubTypeArgumentReg);
+
+    const bool null_is_assignable = Instance::NullIsAssignableTo(type);
+    // Check bottom types.
+    __ CompareImmediate(TTSInternalRegs::kScratchReg, kNeverCid);
+    __ BranchIf(EQUAL, &is_subtype);
+    if (null_is_assignable) {
+      __ CompareImmediate(TTSInternalRegs::kScratchReg, kNullCid);
+      __ BranchIf(EQUAL, &is_subtype);
+    }
+
+    // Not a bottom type, so check cid ranges.
+    const Class& type_class = Class::Handle(type.type_class());
+    const CidRangeVector& ranges =
+        hi->SubtypeRangesForClass(type_class,
+                                  /*include_abstract=*/true,
+                                  /*exclude_null=*/!null_is_assignable);
+    BuildOptimizedSubtypeRangeCheck(assembler, ranges,
+                                    TTSInternalRegs::kScratchReg, &is_subtype,
+                                    check_failed);
+  }
+
+  __ Bind(&is_subtype);
 }
 
 void RegisterTypeArgumentsUse(const Function& function,
diff --git a/runtime/vm/type_testing_stubs.h b/runtime/vm/type_testing_stubs.h
index 40534c7..5775b53 100644
--- a/runtime/vm/type_testing_stubs.h
+++ b/runtime/vm/type_testing_stubs.h
@@ -103,10 +103,17 @@
       compiler::Label* load_succeeded,
       compiler::Label* load_failed);
 
+  static void BuildOptimizedTypeParameterArgumentValueCheck(
+      compiler::Assembler* assembler,
+      HierarchyInfo* hi,
+      const TypeParameter& type_param,
+      intptr_t type_param_value_offset_i,
+      compiler::Label* check_failed);
+
   static void BuildOptimizedTypeArgumentValueCheck(
       compiler::Assembler* assembler,
       HierarchyInfo* hi,
-      const AbstractType& type_arg,
+      const Type& type,
       intptr_t type_param_value_offset_i,
       compiler::Label* check_failed);
 
diff --git a/runtime/vm/type_testing_stubs_test.cc b/runtime/vm/type_testing_stubs_test.cc
index 34e24d9..7f04842 100644
--- a/runtime/vm/type_testing_stubs_test.cc
+++ b/runtime/vm/type_testing_stubs_test.cc
@@ -20,16 +20,16 @@
 
 namespace dart {
 
-// FLAG_trace_type_checks is only a non-constant in DEBUG mode, so we only
-// allow tracing of type testing stub tests there.
-#if defined(DEBUG)
+// Note that flags that this affects may only mutable in some modes, e.g.,
+// tracing type checks can only be done in DEBUG mode.
 DEFINE_FLAG(bool,
             trace_type_testing_stub_tests,
             false,
-            "Trace type checks performed in type testing stub tests");
-#else
-const bool FLAG_trace_type_testing_stub_tests = false;
-#endif
+            "Trace type testing stub tests");
+DEFINE_FLAG(bool,
+            print_type_testing_stub_test_headers,
+            true,
+            "Print headers for executed type testing stub tests");
 
 class TraceStubInvocationScope : public ValueObject {
  public:
@@ -351,7 +351,9 @@
         new_tts_stub_(Code::Handle(zone())),
         last_stc_(SubtypeTestCache::Handle(zone())),
         last_result_(Object::Handle(zone())) {
-    THR_Print("Creating test state for type %s\n", type.ToCString());
+    if (FLAG_print_type_testing_stub_test_headers) {
+      THR_Print("Creating test state for type %s\n", type.ToCString());
+    }
   }
 
   Zone* zone() const { return thread_->zone(); }
@@ -379,17 +381,20 @@
     const auto& default_stub =
         Code::Handle(zone(), TypeTestingStubGenerator::DefaultCodeForType(
                                  last_tested_type_, /*lazy_specialize=*/false));
-    previous_tts_stub_ =
-        TypeTestingStubGenerator::SpecializeStubFor(thread_, last_tested_type_);
+    {
+      // To make sure we output the disassembled stub if desired.
+      TraceStubInvocationScope scope;
+      previous_tts_stub_ = TypeTestingStubGenerator::SpecializeStubFor(
+          thread_, last_tested_type_);
+    }
     EXPECT_EQ(test_case.should_specialize,
               previous_tts_stub_.ptr() != default_stub.ptr());
     last_tested_type_.SetTypeTestingStub(previous_tts_stub_);
-    PrintInvocationHeader(test_case);
+    PrintInvocationHeader("eagerly specialized", test_case);
     InvokeStubHelper(test_case);
     // Treat it as a failure if the stub respecializes, since we're attempting
     // to simulate AOT mode.
     EXPECT(previous_tts_stub_.ptr() == new_tts_stub_.ptr());
-    ReportUnexpectedSTCChanges(test_case);
   }
 
   void InvokeLazilySpecializedStub(const TTSTestCase& test_case) {
@@ -401,8 +406,8 @@
     const auto& specializing_stub =
         Code::Handle(zone(), TypeTestingStubGenerator::DefaultCodeForType(
                                  last_tested_type_, /*lazy_specialize=*/true));
-    PrintInvocationHeader(test_case);
     last_tested_type_.SetTypeTestingStub(specializing_stub);
+    PrintInvocationHeader("lazy specialized", test_case);
     InvokeStubHelper(test_case,
                      /*is_lazy_specialization=*/test_case.should_specialize);
     if (test_case.should_fail || test_case.instance.IsNull()) {
@@ -417,18 +422,15 @@
       // Non-specializing test cases should result in a default TTS.
       EXPECT(new_tts_stub_.ptr() == default_stub.ptr());
     }
-    ReportUnexpectedSTCChanges(
-        test_case, /*is_lazy_specialization=*/test_case.should_specialize);
   }
 
   void InvokeExistingStub(const TTSTestCase& test_case) {
     last_tested_type_ = TypeToTest(test_case);
-    PrintInvocationHeader(test_case);
+    PrintInvocationHeader("existing", test_case);
     InvokeStubHelper(test_case);
     // Only respecialization should result in a new stub.
     EXPECT_EQ(test_case.should_respecialize,
               previous_tts_stub_.ptr() != new_tts_stub_.ptr());
-    ReportUnexpectedSTCChanges(test_case);
   }
 
  private:
@@ -443,12 +445,14 @@
     return Smi::RawCast(modified_rest_regs_box_.At(0));
   }
 
-  void PrintInvocationHeader(const TTSTestCase& test_case) {
+  void PrintInvocationHeader(const char* stub_type,
+                             const TTSTestCase& test_case) {
+    if (!FLAG_print_type_testing_stub_test_headers) return;
     LogBlock lb;
     const auto& tts = Code::Handle(zone(), last_tested_type_.type_test_stub());
     auto* const stub_name = StubCode::NameOfStub(tts.EntryPoint());
-    THR_Print("Testing %s stub for type %s\n",
-              stub_name == nullptr ? "optimized" : stub_name,
+    THR_Print("Testing %s %s stub for type %s\n",
+              stub_name == nullptr ? "optimized" : stub_name, stub_type,
               last_tested_type_.ToCString());
     if (last_tested_type_.ptr() != type_.ptr()) {
       THR_Print("  Original type: %s\n", type_.ToCString());
@@ -523,8 +527,8 @@
     }
     new_tts_stub_ = last_tested_type_.type_test_stub();
     last_stc_ = current_stc();
-    EXPECT_EQ(test_case.should_fail, !last_result_.IsNull());
     if (test_case.should_fail) {
+      EXPECT(!last_result_.IsNull());
       EXPECT(last_result_.IsError());
       EXPECT(last_result_.IsUnhandledException());
       if (last_result_.IsUnhandledException()) {
@@ -533,16 +537,28 @@
         EXPECT(strstr(error.ToCString(), "_TypeError"));
       }
     } else {
-      EXPECT(new_tts_stub_.ptr() != StubCode::LazySpecializeTypeTest().ptr());
-      ReportModifiedRegisters(modified_abi_regs());
-      // If we shouldn't go to the runtime, report any unexpected changes in
-      // non-ABI registers.
-      if (!is_lazy_specialization && !test_case.should_respecialize &&
-          (!test_case.should_be_false_negative ||
-           test_case.HasSTCEntry(previous_stc_, type_))) {
-        ReportModifiedRegisters(modified_rest_regs());
+      EXPECT(last_result_.IsNull());
+      if (!last_result_.IsNull()) {
+        EXPECT(last_result_.IsError());
+        EXPECT(last_result_.IsUnhandledException());
+        if (last_result_.IsUnhandledException()) {
+          const auto& exception = UnhandledException::Cast(last_result_);
+          dart::Expect(__FILE__, __LINE__)
+              .Fail("%s", exception.ToErrorCString());
+        }
+      } else {
+        EXPECT(new_tts_stub_.ptr() != StubCode::LazySpecializeTypeTest().ptr());
+        ReportModifiedRegisters(modified_abi_regs());
+        // If we shouldn't go to the runtime, report any unexpected changes in
+        // non-ABI registers.
+        if (!is_lazy_specialization && !test_case.should_respecialize &&
+            (!test_case.should_be_false_negative ||
+             test_case.HasSTCEntry(previous_stc_, type_))) {
+          ReportModifiedRegisters(modified_rest_regs());
+        }
       }
     }
+    ReportUnexpectedSTCChanges(test_case, is_lazy_specialization);
   }
 
   static void ReportModifiedRegisters(SmiPtr encoded_reg_mask) {
@@ -595,6 +611,7 @@
 
   void ReportUnexpectedSTCChanges(const TTSTestCase& test_case,
                                   bool is_lazy_specialization = false) {
+    // Make sure should_be_false_negative is not set if respecialization is.
     ASSERT(!test_case.should_be_false_negative ||
            !test_case.should_respecialize);
     const bool had_stc_entry = test_case.HasSTCEntry(previous_stc_, type_);
@@ -872,20 +889,22 @@
   RunTTSTest(type_i_object_dynamic, Failure({obj_b1, tav_null, tav_null}));
   RunTTSTest(type_i_object_dynamic, {obj_b2, tav_null, tav_null});
 
-  // We do not generate TTS for uninstantiated types if we would need to use
-  // subtype range checks for the class of the interface type.
+  // We do generate TTSes for uninstantiated types when we need to use
+  // subtype range checks for the class of the interface type, but the TTS
+  // may be partial (returns a false negative in some cases that means going
+  // to the STC/runtime).
   //
   //   obj as I<dynamic, T>
   //
   auto& type_dynamic_t =
       AbstractType::Handle(Type::New(class_i, tav_dynamic_t));
   FinalizeAndCanonicalize(&type_dynamic_t);
-  RunTTSTest(type_dynamic_t, FalseNegative({obj_i, tav_object, tav_null}));
+  RunTTSTest(type_dynamic_t, {obj_i, tav_object, tav_null});
   RunTTSTest(type_dynamic_t, Failure({obj_i2, tav_object, tav_null}));
   RunTTSTest(type_dynamic_t, Failure({obj_base_int, tav_object, tav_null}));
   RunTTSTest(type_dynamic_t, Failure({obj_a, tav_object, tav_null}));
   RunTTSTest(type_dynamic_t, Failure({obj_a1, tav_object, tav_null}));
-  RunTTSTest(type_dynamic_t, FalseNegative({obj_a2, tav_object, tav_null}));
+  RunTTSTest(type_dynamic_t, {obj_a2, tav_object, tav_null});
   RunTTSTest(type_dynamic_t, Failure({obj_b, tav_object, tav_null}));
   RunTTSTest(type_dynamic_t, Failure({obj_b1, tav_object, tav_null}));
   RunTTSTest(type_dynamic_t, FalseNegative({obj_b2, tav_object, tav_null}));
@@ -1116,24 +1135,52 @@
       R"(
       import "dart:async";
 
-      createFutureInt() => (() async => 3)();
+      Future<int> createFutureInt() async => 3;
+      Future<int Function()> createFutureFunction() async => () => 3;
+      Future<int Function()?> createFutureNullableFunction() async =>
+          (() => 3) as int Function()?;
 )";
 
+  const auto& class_future =
+      Class::Handle(IsolateGroup::Current()->object_store()->future_class());
+
   const auto& root_library = Library::Handle(LoadTestScript(kScript));
-  const auto& class_future = Class::Handle(GetClass(root_library, "Future"));
+  const auto& class_closure =
+      Class::Handle(IsolateGroup::Current()->object_store()->closure_class());
   const auto& obj_futureint =
       Object::Handle(Invoke(root_library, "createFutureInt"));
-
-  const auto& type_nullable_object = Type::Handle(
-      IsolateGroup::Current()->object_store()->nullable_object_type());
-  const auto& type_int = Type::Handle(Type::IntType());
-  const auto& type_string = Type::Handle(Type::StringType());
-  const auto& type_num = Type::Handle(Type::Number());
+  const auto& obj_futurefunction =
+      Object::Handle(Invoke(root_library, "createFutureFunction"));
+  const auto& obj_futurenullablefunction =
+      Object::Handle(Invoke(root_library, "createFutureNullableFunction"));
 
   const auto& tav_null = Object::null_type_arguments();
+  const auto& type_object = Type::Handle(
+      IsolateGroup::Current()->object_store()->non_nullable_object_type());
+  const auto& type_legacy_object = Type::Handle(
+      IsolateGroup::Current()->object_store()->legacy_object_type());
+  const auto& type_nullable_object = Type::Handle(
+      IsolateGroup::Current()->object_store()->nullable_object_type());
+  const auto& type_int = Type::Handle(
+      IsolateGroup::Current()->object_store()->non_nullable_int_type());
+
+  auto& type_string = Type::Handle(Type::StringType());
+  type_string =
+      type_string.ToNullability(Nullability::kNonNullable, Heap::kNew);
+  FinalizeAndCanonicalize(&type_string);
+  auto& type_num = Type::Handle(Type::Number());
+  type_num = type_num.ToNullability(Nullability::kNonNullable, Heap::kNew);
+  FinalizeAndCanonicalize(&type_num);
+
   auto& tav_dynamic = TypeArguments::Handle(TypeArguments::New(1));
   tav_dynamic.SetTypeAt(0, Object::dynamic_type());
   CanonicalizeTAV(&tav_dynamic);
+  auto& tav_object = TypeArguments::Handle(TypeArguments::New(1));
+  tav_object.SetTypeAt(0, type_object);
+  CanonicalizeTAV(&tav_object);
+  auto& tav_legacy_object = TypeArguments::Handle(TypeArguments::New(1));
+  tav_legacy_object.SetTypeAt(0, type_legacy_object);
+  CanonicalizeTAV(&tav_legacy_object);
   auto& tav_nullable_object = TypeArguments::Handle(TypeArguments::New(1));
   tav_nullable_object.SetTypeAt(0, type_nullable_object);
   CanonicalizeTAV(&tav_nullable_object);
@@ -1147,45 +1194,422 @@
   tav_string.SetTypeAt(0, type_string);
   CanonicalizeTAV(&tav_string);
 
-  auto& type_future = Type::Handle(Type::New(class_future, tav_null));
+  auto& type_future = Type::Handle(
+      Type::New(class_future, tav_null, Nullability::kNonNullable));
   FinalizeAndCanonicalize(&type_future);
-  auto& type_future_dynamic =
-      Type::Handle(Type::New(class_future, tav_dynamic));
+  auto& type_future_dynamic = Type::Handle(
+      Type::New(class_future, tav_dynamic, Nullability::kNonNullable));
   FinalizeAndCanonicalize(&type_future_dynamic);
-  auto& type_future_nullable_object =
-      Type::Handle(Type::New(class_future, tav_nullable_object));
+  auto& type_future_object = Type::Handle(
+      Type::New(class_future, tav_object, Nullability::kNonNullable));
+  FinalizeAndCanonicalize(&type_future_object);
+  auto& type_future_legacy_object = Type::Handle(
+      Type::New(class_future, tav_legacy_object, Nullability::kNonNullable));
+  FinalizeAndCanonicalize(&type_future_legacy_object);
+  auto& type_future_nullable_object = Type::Handle(
+      Type::New(class_future, tav_nullable_object, Nullability::kNonNullable));
   FinalizeAndCanonicalize(&type_future_nullable_object);
-  auto& type_future_int = Type::Handle(Type::New(class_future, tav_int));
+  auto& type_future_int =
+      Type::Handle(Type::New(class_future, tav_int, Nullability::kNonNullable));
   FinalizeAndCanonicalize(&type_future_int);
-  auto& type_future_string = Type::Handle(Type::New(class_future, tav_string));
+  auto& type_future_string = Type::Handle(
+      Type::New(class_future, tav_string, Nullability::kNonNullable));
   FinalizeAndCanonicalize(&type_future_string);
-  auto& type_future_num = Type::Handle(Type::New(class_future, tav_num));
+  auto& type_future_num =
+      Type::Handle(Type::New(class_future, tav_num, Nullability::kNonNullable));
   FinalizeAndCanonicalize(&type_future_num);
-  auto& type_future_t = Type::Handle(class_future.DeclarationType());
+  const auto& type_future_t = Type::Handle(class_future.DeclarationType());
+
+  THR_Print("********************************************************\n");
+  THR_Print("               Testing Future<int>\n");
+  THR_Print("********************************************************\n\n");
 
   // Some more tests of generic implemented classes, using Future. Here,
   // obj is an object of type Future<int>.
   //
-  //   obj as Future          : Null type args (caught by TTS)
+  // True positives from TTS:
+  //   obj as Future          : Null type args
   //   obj as Future<dynamic> : Canonicalized to same as previous case.
-  //   obj as Future<Object?> : Type arg is top type (caught by TTS)
-  //   obj as Future<int>     : Type arg is the same type (caught by TTS)
-  //   obj as Future<String>  : Type arg is not a subtype (error via runtime)
+  //   obj as Future<Object?> : Type arg is top type
+  //   obj as Future<Object*> : Type arg is top type
+  //   obj as Future<Object>  : Type arg is certain supertype
+  //   obj as Future<int>     : Type arg is the same type
   //   obj as Future<num>     : Type arg is a supertype that can be matched
-  //                            with cid range (caught by TTS)
+  //                            with cid range
   //   obj as Future<X>,      : Type arg is a type parameter instantiated with
-  //       X = int            :    ... the same type (caught by TTS)
-  //       X = String         :    ... an unrelated type (error via runtime)
-  //       X = num            :    ... a supertype (caught by STC/runtime)
+  //       X = int            :    ... the same type
+  //
   RunTTSTest(type_future, {obj_futureint, tav_null, tav_null});
   RunTTSTest(type_future_dynamic, {obj_futureint, tav_null, tav_null});
+  RunTTSTest(type_future_object, {obj_futureint, tav_null, tav_null});
+  RunTTSTest(type_future_legacy_object, {obj_futureint, tav_null, tav_null});
   RunTTSTest(type_future_nullable_object, {obj_futureint, tav_null, tav_null});
   RunTTSTest(type_future_int, {obj_futureint, tav_null, tav_null});
-  RunTTSTest(type_future_string, Failure({obj_futureint, tav_null, tav_null}));
   RunTTSTest(type_future_num, {obj_futureint, tav_null, tav_null});
   RunTTSTest(type_future_t, {obj_futureint, tav_int, tav_null});
-  RunTTSTest(type_future_t, Failure({obj_futureint, tav_string, tav_null}));
+
+  // False negatives from TTS (caught by STC/runtime):
+  //   obj as Future<X>,      : Type arg is a type parameter instantiated with
+  //       X = num            :    ... a supertype
   RunTTSTest(type_future_t, FalseNegative({obj_futureint, tav_num, tav_null}));
+
+  // Errors:
+  //   obj as Future<String>  : Type arg is not a supertype
+  //   obj as Future<X>,      : Type arg is a type parameter instantiated with
+  //       X = String         :    ... an unrelated type
+  //
+  RunTTSTest(type_future_string, Failure({obj_futureint, tav_null, tav_null}));
+  RunTTSTest(type_future_t, Failure({obj_futureint, tav_string, tav_null}));
+
+  auto& type_function = Type::Handle(Type::DartFunctionType());
+  type_function =
+      type_function.ToNullability(Nullability::kNonNullable, Heap::kNew);
+  FinalizeAndCanonicalize(&type_function);
+  auto& type_legacy_function = Type::Handle(
+      type_function.ToNullability(Nullability::kLegacy, Heap::kNew));
+  FinalizeAndCanonicalize(&type_legacy_function);
+  auto& type_nullable_function = Type::Handle(
+      type_function.ToNullability(Nullability::kNullable, Heap::kOld));
+  FinalizeAndCanonicalize(&type_nullable_function);
+  auto& type_closure = Type::Handle(
+      Type::New(class_closure, tav_null, Nullability::kNonNullable));
+  FinalizeAndCanonicalize(&type_closure);
+  auto& type_legacy_closure = Type::Handle(
+      type_closure.ToNullability(Nullability::kLegacy, Heap::kOld));
+  FinalizeAndCanonicalize(&type_legacy_closure);
+  auto& type_nullable_closure = Type::Handle(
+      type_closure.ToNullability(Nullability::kNullable, Heap::kOld));
+  FinalizeAndCanonicalize(&type_nullable_closure);
+  auto& type_function_int_nullary =
+      FunctionType::Handle(FunctionType::New(0, Nullability::kNonNullable));
+  // Testing with a closure, so it has an implicit parameter, and we want a
+  // type that is canonically equal to the type of the closure.
+  type_function_int_nullary.set_num_implicit_parameters(1);
+  type_function_int_nullary.set_num_fixed_parameters(1);
+  type_function_int_nullary.set_parameter_types(Array::Handle(Array::New(1)));
+  type_function_int_nullary.SetParameterTypeAt(0, Type::dynamic_type());
+  type_function_int_nullary.set_result_type(type_int);
+  FinalizeAndCanonicalize(&type_function_int_nullary);
+  auto& type_legacy_function_int_nullary =
+      FunctionType::Handle(type_function_int_nullary.ToNullability(
+          Nullability::kLegacy, Heap::kOld));
+  FinalizeAndCanonicalize(&type_legacy_function_int_nullary);
+  auto& type_nullable_function_int_nullary =
+      FunctionType::Handle(type_function_int_nullary.ToNullability(
+          Nullability::kNullable, Heap::kOld));
+  FinalizeAndCanonicalize(&type_nullable_function_int_nullary);
+
+  auto& tav_function = TypeArguments::Handle(TypeArguments::New(1));
+  tav_function.SetTypeAt(0, type_function);
+  CanonicalizeTAV(&tav_function);
+  auto& tav_legacy_function = TypeArguments::Handle(TypeArguments::New(1));
+  tav_legacy_function.SetTypeAt(0, type_legacy_function);
+  CanonicalizeTAV(&tav_legacy_function);
+  auto& tav_nullable_function = TypeArguments::Handle(TypeArguments::New(1));
+  tav_nullable_function.SetTypeAt(0, type_nullable_function);
+  CanonicalizeTAV(&tav_nullable_function);
+  auto& tav_closure = TypeArguments::Handle(TypeArguments::New(1));
+  tav_closure.SetTypeAt(0, type_closure);
+  CanonicalizeTAV(&tav_closure);
+  auto& tav_legacy_closure = TypeArguments::Handle(TypeArguments::New(1));
+  tav_legacy_closure.SetTypeAt(0, type_legacy_closure);
+  CanonicalizeTAV(&tav_legacy_closure);
+  auto& tav_nullable_closure = TypeArguments::Handle(TypeArguments::New(1));
+  tav_nullable_closure.SetTypeAt(0, type_nullable_closure);
+  CanonicalizeTAV(&tav_nullable_closure);
+  auto& tav_function_int_nullary = TypeArguments::Handle(TypeArguments::New(1));
+  tav_function_int_nullary.SetTypeAt(0, type_function_int_nullary);
+  CanonicalizeTAV(&tav_function_int_nullary);
+  auto& tav_legacy_function_int_nullary =
+      TypeArguments::Handle(TypeArguments::New(1));
+  tav_legacy_function_int_nullary.SetTypeAt(0,
+                                            type_legacy_function_int_nullary);
+  CanonicalizeTAV(&tav_legacy_function_int_nullary);
+  auto& tav_nullable_function_int_nullary =
+      TypeArguments::Handle(TypeArguments::New(1));
+  tav_nullable_function_int_nullary.SetTypeAt(
+      0, type_nullable_function_int_nullary);
+  CanonicalizeTAV(&tav_nullable_function_int_nullary);
+
+  auto& type_future_function = Type::Handle(
+      Type::New(class_future, tav_function, Nullability::kNonNullable));
+  FinalizeAndCanonicalize(&type_future_function);
+  auto& type_future_legacy_function = Type::Handle(
+      Type::New(class_future, tav_legacy_function, Nullability::kNonNullable));
+  FinalizeAndCanonicalize(&type_future_legacy_function);
+  auto& type_future_nullable_function = Type::Handle(Type::New(
+      class_future, tav_nullable_function, Nullability::kNonNullable));
+  FinalizeAndCanonicalize(&type_future_nullable_function);
+  auto& type_future_closure = Type::Handle(
+      Type::New(class_future, tav_closure, Nullability::kNonNullable));
+  FinalizeAndCanonicalize(&type_future_closure);
+  auto& type_future_legacy_closure = Type::Handle(
+      Type::New(class_future, tav_legacy_closure, Nullability::kNonNullable));
+  FinalizeAndCanonicalize(&type_future_legacy_closure);
+  auto& type_future_nullable_closure = Type::Handle(
+      Type::New(class_future, tav_nullable_closure, Nullability::kNonNullable));
+  FinalizeAndCanonicalize(&type_future_nullable_closure);
+  auto& type_future_function_int_nullary =
+      Type::Handle(Type::New(class_future, tav_function_int_nullary));
+  FinalizeAndCanonicalize(&type_future_function_int_nullary);
+  auto& type_future_legacy_function_int_nullary =
+      Type::Handle(Type::New(class_future, tav_legacy_function_int_nullary));
+  FinalizeAndCanonicalize(&type_future_legacy_function_int_nullary);
+  auto& type_future_nullable_function_int_nullary =
+      Type::Handle(Type::New(class_future, tav_nullable_function_int_nullary));
+  FinalizeAndCanonicalize(&type_future_nullable_function_int_nullary);
+
+  THR_Print("\n********************************************************\n");
+  THR_Print("            Testing Future<int Function()>\n");
+  THR_Print("********************************************************\n\n");
+
+  // And here, obj is an object of type Future<int Function()>. Note that
+  // int Function() <: Function, but int Function() </: _Closure. That is,
+  // _Closure is a separate subtype of Function from FunctionTypes.
+  //
+  // True positive from TTS:
+  //   obj as Future            : Null type args
+  //   obj as Future<dynamic>   : Canonicalized to same as previous case.
+  //   obj as Future<Object?>   : Type arg is top type
+  //   obj as Future<Object*>   : Type arg is top typ
+  //   obj as Future<Object>    : Type arg is certain supertype
+  //   obj as Future<Function?> : Type arg is certain supertype
+  //   obj as Future<Function*> : Type arg is certain supertype
+  //   obj as Future<Function>  : Type arg is certain supertype
+  //   obj as Future<X>,        : Type arg is a type parameter instantiated with
+  //       X = dynamic          :    ... a top type
+  //       X = Object?          :    ... a top type
+  //       X = Object*          :    ... a top type
+  //       X = Object           :    ... a certain supertype
+  //       X = int Function()   :    ... the same type.
+  //
+  RunTTSTest(type_future, {obj_futurefunction, tav_null, tav_null});
+  RunTTSTest(type_future_dynamic, {obj_futurefunction, tav_null, tav_null});
+  RunTTSTest(type_future_nullable_object,
+             {obj_futurefunction, tav_null, tav_null});
+  RunTTSTest(type_future_legacy_object,
+             {obj_futurefunction, tav_null, tav_null});
+  RunTTSTest(type_future_object, {obj_futurefunction, tav_null, tav_null});
+  RunTTSTest(type_future_nullable_object,
+             {obj_futurefunction, tav_null, tav_null});
+  RunTTSTest(type_future_legacy_object,
+             {obj_futurefunction, tav_null, tav_null});
+  RunTTSTest(type_future_object, {obj_futurefunction, tav_null, tav_null});
+  RunTTSTest(type_future_nullable_function,
+             {obj_futurefunction, tav_null, tav_null});
+  RunTTSTest(type_future_legacy_function,
+             {obj_futurefunction, tav_null, tav_null});
+  RunTTSTest(type_future_function, {obj_futurefunction, tav_null, tav_null});
+  RunTTSTest(type_future_t, {obj_futurefunction, tav_null, tav_null});
+  RunTTSTest(type_future_t,
+             {obj_futurefunction, tav_nullable_object, tav_null});
+  RunTTSTest(type_future_t, {obj_futurefunction, tav_legacy_object, tav_null});
+  RunTTSTest(type_future_t, {obj_futurefunction, tav_object, tav_null});
+  RunTTSTest(type_future_t,
+             {obj_futurefunction, tav_function_int_nullary, tav_null});
+
+  // False negative from TTS (caught by runtime or STC):
+  //   obj as Future<int Function()?> : No specialization.
+  //   obj as Future<int Function()*> : No specialization.
+  //   obj as Future<int Function()>  : No specialization.
+  //   obj as Future<X>,        : Type arg is a type parameter instantiated with
+  //       X = Function?        :    ... a certain supertype (but not checked)
+  //       X = Function*        :    ... a certain supertype (but not checked)
+  //       X = Function         :    ... a certain supertype (but not checked)
+  //       X = int Function()?  :    ... a canonically different type.
+  //       X = int Function()*  :    ... a canonically different type.
+  //
+  RunTTSTest(type_future_nullable_function_int_nullary,
+             FalseNegative({obj_futurefunction, tav_null, tav_null,
+                            /*should_specialize=*/false}));
+  RunTTSTest(type_future_legacy_function_int_nullary,
+             FalseNegative({obj_futurefunction, tav_null, tav_null,
+                            /*should_specialize=*/false}));
+  RunTTSTest(type_future_function_int_nullary,
+             FalseNegative({obj_futurefunction, tav_null, tav_null,
+                            /*should_specialize=*/false}));
+  RunTTSTest(type_future_t, FalseNegative({obj_futurefunction,
+                                           tav_nullable_function, tav_null}));
+  RunTTSTest(type_future_t, FalseNegative({obj_futurefunction,
+                                           tav_legacy_function, tav_null}));
+  RunTTSTest(type_future_t,
+             FalseNegative({obj_futurefunction, tav_function, tav_null}));
+  RunTTSTest(type_future_t,
+             FalseNegative({obj_futurefunction,
+                            tav_nullable_function_int_nullary, tav_null}));
+  RunTTSTest(type_future_t,
+             FalseNegative({obj_futurefunction, tav_legacy_function_int_nullary,
+                            tav_null}));
+
+  // Errors:
+  //   obj as Future<_Closure?> : Type arg is not a supertype
+  //   obj as Future<_Closure*> : Type arg is not a supertype
+  //   obj as Future<_Closure>  : Type arg is not a supertype
+  //   obj as Future<X>,        : Type arg is a type parameter instantiated with
+  //       X = _Closure?        :    ... an unrelated type.
+  //       X = _Closure*        :    ... an unrelated type.
+  //       X = _Closure         :    ... an unrelated type.
+  //
+  RunTTSTest(type_future_nullable_closure,
+             Failure({obj_futurefunction, tav_null, tav_null}));
+  RunTTSTest(type_future_legacy_closure,
+             Failure({obj_futurefunction, tav_null, tav_null}));
+  RunTTSTest(type_future_closure,
+             Failure({obj_futurefunction, tav_null, tav_null}));
+  RunTTSTest(type_future_t,
+             Failure({obj_futurefunction, tav_nullable_closure, tav_null}));
+  RunTTSTest(type_future_t,
+             Failure({obj_futurefunction, tav_legacy_closure, tav_null}));
+  RunTTSTest(type_future_t,
+             Failure({obj_futurefunction, tav_closure, tav_null}));
+
+  THR_Print("\n********************************************************\n");
+  THR_Print("            Testing Future<int Function()?>\n");
+  THR_Print("********************************************************\n\n");
+
+  const bool strict_null_safety =
+      thread->isolate_group()->use_strict_null_safety_checks();
+
+  // And here, obj is an object of type Future<int Function()?>.
+  //
+  // True positive from TTS:
+  //   obj as Future            : Null type args
+  //   obj as Future<dynamic>   : Canonicalized to same as previous case.
+  //   obj as Future<Object?>   : Type arg is top type
+  //   obj as Future<Object*>   : Type arg is top typ
+  //   obj as Future<Function?> : Type arg is certain supertype
+  //   obj as Future<Function*> : Type arg is certain supertype
+  //   obj as Future<X>,        : Type arg is a type parameter instantiated with
+  //       X = dynamic          :    ... a top type
+  //       X = Object?          :    ... a top type
+  //       X = Object*          :    ... a top type
+  //       X = int Function()?  :    ... the same type.
+  //
+  // If not null safe:
+  //   obj as Future<Object>    : Type arg is certain supertype
+  //   obj as Future<Function>  : Type arg is certain supertype
+  //   obj as Future<X>,        : Type arg is a type parameter instantiated with
+  //       X = Object           :    ... a certain supertype
+  RunTTSTest(type_future, {obj_futurenullablefunction, tav_null, tav_null});
+  RunTTSTest(type_future_dynamic,
+             {obj_futurenullablefunction, tav_null, tav_null});
+  RunTTSTest(type_future_nullable_object,
+             {obj_futurenullablefunction, tav_null, tav_null});
+  RunTTSTest(type_future_legacy_object,
+             {obj_futurenullablefunction, tav_null, tav_null});
+  RunTTSTest(type_future_nullable_object,
+             {obj_futurefunction, tav_null, tav_null});
+  RunTTSTest(type_future_legacy_object,
+             {obj_futurenullablefunction, tav_null, tav_null});
+  RunTTSTest(type_future_nullable_function,
+             {obj_futurenullablefunction, tav_null, tav_null});
+  RunTTSTest(type_future_legacy_function,
+             {obj_futurenullablefunction, tav_null, tav_null});
+  RunTTSTest(type_future_t, {obj_futurenullablefunction, tav_null, tav_null});
+  RunTTSTest(type_future_t,
+             {obj_futurenullablefunction, tav_nullable_object, tav_null});
+  RunTTSTest(type_future_t,
+             {obj_futurenullablefunction, tav_legacy_object, tav_null});
+  RunTTSTest(type_future_t, {obj_futurenullablefunction,
+                             tav_nullable_function_int_nullary, tav_null});
+
+  if (!strict_null_safety) {
+    RunTTSTest(type_future_object,
+               {obj_futurenullablefunction, tav_null, tav_null});
+    RunTTSTest(type_future_function,
+               {obj_futurenullablefunction, tav_null, tav_null});
+    RunTTSTest(type_future_t,
+               {obj_futurenullablefunction, tav_object, tav_null});
+  }
+
+  // False negative from TTS (caught by runtime or STC):
+  //   obj as Future<int Function()?> : No specialization.
+  //   obj as Future<int Function()*> : No specialization.
+  //   obj as Future<X>,        : Type arg is a type parameter instantiated with
+  //       X = Function?        :    ... a certain supertype (but not checked)
+  //       X = Function*        :    ... a certain supertype (but not checked)
+  //       X = int Function()*  :    ... a canonically different type.
+  //
+  // If not null safe:
+  //   obj as Future<int Function()>  : No specialization.
+  //   obj as Future<X>,        : Type arg is a type parameter instantiated with
+  //       X = Function         :    ... a certain supertype (but not checked)
+  //       X = int Function()   :    ... a canonically different type.
+
+  RunTTSTest(type_future_nullable_function_int_nullary,
+             FalseNegative({obj_futurenullablefunction, tav_null, tav_null,
+                            /*should_specialize=*/false}));
+  RunTTSTest(type_future_legacy_function_int_nullary,
+             FalseNegative({obj_futurenullablefunction, tav_null, tav_null,
+                            /*should_specialize=*/false}));
+  RunTTSTest(type_future_t, FalseNegative({obj_futurenullablefunction,
+                                           tav_nullable_function, tav_null}));
+  RunTTSTest(type_future_t, FalseNegative({obj_futurenullablefunction,
+                                           tav_legacy_function, tav_null}));
+  RunTTSTest(type_future_t,
+             FalseNegative({obj_futurenullablefunction,
+                            tav_legacy_function_int_nullary, tav_null}));
+
+  if (!strict_null_safety) {
+    RunTTSTest(type_future_function_int_nullary,
+               FalseNegative({obj_futurenullablefunction, tav_null, tav_null,
+                              /*should_specialize=*/false}));
+    RunTTSTest(type_future_t, FalseNegative({obj_futurenullablefunction,
+                                             tav_function, tav_null}));
+    RunTTSTest(type_future_t,
+               FalseNegative({obj_futurenullablefunction,
+                              tav_function_int_nullary, tav_null}));
+  }
+
+  // Errors:
+  //   obj as Future<_Closure?> : Type arg is not a supertype
+  //   obj as Future<_Closure*> : Type arg is not a supertype
+  //   obj as Future<_Closure>  : Type arg is not a supertype
+  //   obj as Future<X>,        : Type arg is a type parameter instantiated with
+  //       X = _Closure?        :    ... an unrelated type.
+  //       X = _Closure*        :    ... an unrelated type.
+  //       X = _Closure         :    ... an unrelated type.
+  //
+  // If null safe:
+  //   obj as Future<int Function()>  : Nullable type cannot be subtype of a
+  //                                    non-nullable type.
+  //   obj as Future<Object>    : Nullable type cannot be subtype of a
+  //                              non-nullable type.
+  //   obj as Future<Function>  : Nullable type cannot be subtype of a
+  //                              non-nullable type.
+  //   obj as Future<X>,        : Type arg is a type parameter instantiated with
+  //       X = Object           :    ... a non-nullable type.
+  //       X = Function         :    ... a non-nullable type.
+  //       X = int Function()   :    ... a non-nullable type.
+
+  RunTTSTest(type_future_nullable_closure,
+             Failure({obj_futurenullablefunction, tav_null, tav_null}));
+  RunTTSTest(type_future_legacy_closure,
+             Failure({obj_futurenullablefunction, tav_null, tav_null}));
+  RunTTSTest(type_future_closure,
+             Failure({obj_futurenullablefunction, tav_null, tav_null}));
+  RunTTSTest(type_future_t, Failure({obj_futurenullablefunction,
+                                     tav_nullable_closure, tav_null}));
+  RunTTSTest(type_future_t, Failure({obj_futurenullablefunction,
+                                     tav_legacy_closure, tav_null}));
+  RunTTSTest(type_future_t,
+             Failure({obj_futurenullablefunction, tav_closure, tav_null}));
+
+  if (strict_null_safety) {
+    RunTTSTest(type_future_function_int_nullary,
+               Failure({obj_futurenullablefunction, tav_null, tav_null,
+                        /*should_specialize=*/false}));
+    RunTTSTest(type_future_object,
+               Failure({obj_futurenullablefunction, tav_null, tav_null}));
+    RunTTSTest(type_future_function,
+               Failure({obj_futurenullablefunction, tav_null, tav_null}));
+    RunTTSTest(type_future_t,
+               Failure({obj_futurenullablefunction, tav_object, tav_null}));
+    RunTTSTest(type_future_t,
+               Failure({obj_futurenullablefunction, tav_function, tav_null}));
+    RunTTSTest(type_future_t, Failure({obj_futurenullablefunction,
+                                       tav_function_int_nullary, tav_null}));
+  }
 }
 
 ISOLATE_UNIT_TEST_CASE(TTS_Regress40964) {
@@ -1408,25 +1832,78 @@
   const char* kScript =
       R"(
       class B<T> {}
+
+      class C {}
+      class D extends C {}
+      class E extends D {}
+
       F<A>() {}
-      createB() => B<int>();
+      createBE() => B<E>();
+      createBENullable() => B<E?>();
+      createBNull() => B<Null>();
+      createBNever() => B<Never>();
 )";
 
   const auto& root_library = Library::Handle(LoadTestScript(kScript));
   const auto& class_b = Class::Handle(GetClass(root_library, "B"));
+  const auto& class_c = Class::Handle(GetClass(root_library, "C"));
+  const auto& class_d = Class::Handle(GetClass(root_library, "D"));
+  const auto& class_e = Class::Handle(GetClass(root_library, "E"));
   const auto& fun_f = Function::Handle(GetFunction(root_library, "F"));
-  const auto& obj_b = Object::Handle(Invoke(root_library, "createB"));
+  const auto& obj_b_e = Object::Handle(Invoke(root_library, "createBE"));
+  const auto& obj_b_e_nullable =
+      Object::Handle(Invoke(root_library, "createBENullable"));
+  const auto& obj_b_null = Object::Handle(Invoke(root_library, "createBNull"));
+  const auto& obj_b_never =
+      Object::Handle(Invoke(root_library, "createBNever"));
 
   const auto& tav_null = Object::null_type_arguments();
-  auto& tav_int = TypeArguments::Handle(TypeArguments::New(1));
-  tav_int.SetTypeAt(0, Type::Handle(Type::IntType()));
-  CanonicalizeTAV(&tav_int);
+  auto& tav_nullable_object = TypeArguments::Handle(TypeArguments::New(1));
+  tav_nullable_object.SetTypeAt(
+      0, Type::Handle(
+             IsolateGroup::Current()->object_store()->nullable_object_type()));
+  CanonicalizeTAV(&tav_nullable_object);
+  auto& tav_legacy_object = TypeArguments::Handle(TypeArguments::New(1));
+  tav_legacy_object.SetTypeAt(
+      0, Type::Handle(
+             IsolateGroup::Current()->object_store()->legacy_object_type()));
+  CanonicalizeTAV(&tav_legacy_object);
   auto& tav_object = TypeArguments::Handle(TypeArguments::New(1));
-  tav_object.SetTypeAt(0, Type::Handle(Type::ObjectType()));
+  tav_object.SetTypeAt(
+      0, Type::Handle(IsolateGroup::Current()->object_store()->object_type()));
   CanonicalizeTAV(&tav_object);
-  auto& tav_num = TypeArguments::Handle(TypeArguments::New(1));
-  tav_num.SetTypeAt(0, Type::Handle(Type::Number()));
-  CanonicalizeTAV(&tav_num);
+
+  auto& type_e =
+      Type::Handle(Type::New(class_e, tav_null, Nullability::kNonNullable));
+  FinalizeAndCanonicalize(&type_e);
+  auto& type_d =
+      Type::Handle(Type::New(class_d, tav_null, Nullability::kNonNullable));
+  FinalizeAndCanonicalize(&type_d);
+  auto& type_c =
+      Type::Handle(Type::New(class_c, tav_null, Nullability::kNonNullable));
+  FinalizeAndCanonicalize(&type_c);
+  auto& type_c_nullable =
+      Type::Handle(Type::New(class_c, tav_null, Nullability::kNullable));
+  FinalizeAndCanonicalize(&type_c_nullable);
+  auto& type_c_legacy =
+      Type::Handle(Type::New(class_c, tav_null, Nullability::kLegacy));
+  FinalizeAndCanonicalize(&type_c_legacy);
+
+  auto& tav_e = TypeArguments::Handle(TypeArguments::New(1));
+  tav_e.SetTypeAt(0, type_e);
+  CanonicalizeTAV(&tav_e);
+  auto& tav_d = TypeArguments::Handle(TypeArguments::New(1));
+  tav_d.SetTypeAt(0, type_d);
+  CanonicalizeTAV(&tav_d);
+  auto& tav_c = TypeArguments::Handle(TypeArguments::New(1));
+  tav_c.SetTypeAt(0, type_c);
+  CanonicalizeTAV(&tav_c);
+  auto& tav_nullable_c = TypeArguments::Handle(TypeArguments::New(1));
+  tav_nullable_c.SetTypeAt(0, type_c_nullable);
+  CanonicalizeTAV(&tav_nullable_c);
+  auto& tav_legacy_c = TypeArguments::Handle(TypeArguments::New(1));
+  tav_legacy_c.SetTypeAt(0, type_c_legacy);
+  CanonicalizeTAV(&tav_legacy_c);
 
   // One case where optimized TTSes can be partial is if the type is
   // uninstantiated with a type parameter at the same position as one of the
@@ -1438,41 +1915,51 @@
       TypeParameter::Handle(GetFunctionTypeParameter(fun_f, 0));
   auto& tav_a = TypeArguments::Handle(TypeArguments::New(1));
   tav_a.SetTypeAt(0, type_a);
-  auto& type_b2_a = AbstractType::Handle(Type::New(class_b, tav_a));
-  FinalizeAndCanonicalize(&type_b2_a);
-  TTSTestState state(thread, type_b2_a);
+  CanonicalizeTAV(&tav_a);
+  auto& type_b_a = AbstractType::Handle(
+      Type::New(class_b, tav_a, Nullability::kNonNullable));
+  FinalizeAndCanonicalize(&type_b_a);
+  TTSTestState state(thread, type_b_a);
 
-  TTSTestCase positive_test_case{obj_b, tav_null, tav_int};
-  TTSTestCase first_false_negative_test_case =
-      FalseNegative({obj_b, tav_null, tav_object});
-  TTSTestCase second_false_negative_test_case =
-      FalseNegative({obj_b, tav_null, tav_num});
-  // No test case should possibly hit the same STC entry as another.
-  ASSERT(!first_false_negative_test_case.HasSameSTCEntry(positive_test_case));
-  ASSERT(!second_false_negative_test_case.HasSameSTCEntry(positive_test_case));
-  ASSERT(!second_false_negative_test_case.HasSameSTCEntry(
-      first_false_negative_test_case));
-  // The type with the tested stub must be the same in all test cases.
-  ASSERT(state.TypeToTest(positive_test_case) ==
-         state.TypeToTest(first_false_negative_test_case));
-  ASSERT(state.TypeToTest(positive_test_case) ==
-         state.TypeToTest(second_false_negative_test_case));
+  TTSTestCase b_e_testcase{obj_b_e, tav_null, tav_e};
+  TTSTestCase b_d_testcase = FalseNegative({obj_b_e, tav_null, tav_d});
+  TTSTestCase b_c_testcase = FalseNegative({obj_b_e, tav_null, tav_c});
 
   // First, test that the positive test case is handled by the TTS.
-  state.InvokeLazilySpecializedStub(positive_test_case);
-  state.InvokeExistingStub(positive_test_case);
+  state.InvokeLazilySpecializedStub(b_e_testcase);
+  state.InvokeExistingStub(b_e_testcase);
 
   // Now restart, using the false negative test cases.
   state.ClearCache();
 
-  state.InvokeLazilySpecializedStub(first_false_negative_test_case);
-  state.InvokeExistingStub(first_false_negative_test_case);
-  state.InvokeEagerlySpecializedStub(first_false_negative_test_case);
+  state.InvokeLazilySpecializedStub(b_d_testcase);
+  state.InvokeExistingStub(b_d_testcase);
+  state.InvokeEagerlySpecializedStub(b_d_testcase);
 
-  state.InvokeExistingStub(positive_test_case);
-  state.InvokeExistingStub(second_false_negative_test_case);
-  state.InvokeExistingStub(first_false_negative_test_case);
-  state.InvokeExistingStub(positive_test_case);
+  state.InvokeExistingStub(b_e_testcase);
+  state.InvokeExistingStub(b_c_testcase);
+  state.InvokeExistingStub(b_d_testcase);
+  state.InvokeExistingStub(b_e_testcase);
+
+  state.InvokeExistingStub({obj_b_never, tav_null, tav_d});
+  state.InvokeExistingStub({obj_b_null, tav_null, tav_nullable_c});
+  state.InvokeExistingStub({obj_b_null, tav_null, tav_legacy_c});
+  if (IsolateGroup::Current()->use_strict_null_safety_checks()) {
+    state.InvokeExistingStub(Failure({obj_b_null, tav_null, tav_c}));
+  } else {
+    state.InvokeExistingStub({obj_b_null, tav_null, tav_c});
+  }
+
+  state.InvokeExistingStub({obj_b_e, tav_null, tav_nullable_object});
+  state.InvokeExistingStub({obj_b_e_nullable, tav_null, tav_nullable_object});
+  state.InvokeExistingStub({obj_b_e, tav_null, tav_legacy_object});
+  state.InvokeExistingStub({obj_b_e_nullable, tav_null, tav_legacy_object});
+  state.InvokeExistingStub({obj_b_e, tav_null, tav_object});
+  if (IsolateGroup::Current()->use_strict_null_safety_checks()) {
+    state.InvokeExistingStub(Failure({obj_b_e_nullable, tav_null, tav_object}));
+  } else {
+    state.InvokeExistingStub({obj_b_e_nullable, tav_null, tav_object});
+  }
 }
 
 ISOLATE_UNIT_TEST_CASE(TTS_Partial_Incremental) {
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index 0e130aa..7fb3ed5 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.dart
@@ -36,7 +36,7 @@
 ///
 /// void main() async {
 ///   // Creates dir/ and dir/subdir/.
-///   var directory = await Directory('dir/subdir').create(recursive: true)
+///   var directory = await Directory('dir/subdir').create(recursive: true);
 ///   print(directory.path);
 /// }
 /// ```
diff --git a/sdk/lib/io/platform.dart b/sdk/lib/io/platform.dart
index cedaeba..df6013c 100644
--- a/sdk/lib/io/platform.dart
+++ b/sdk/lib/io/platform.dart
@@ -45,7 +45,7 @@
 /// [operatingSystem] getter. You can also use one of the static boolean
 /// getters: [isMacOS], [isLinux], and [isWindows].
 /// ```dart
-/// import 'dart:io' show Platform, stdout;
+/// import 'dart:io' show Platform;
 ///
 /// void main() {
 ///   // Get the operating system as a string.
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 6089df4..7c9e1b7 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -8,7 +8,6 @@
 Language/Expressions/Constants/literal_number_t01: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Constants/math_operators_t01: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Constants/math_operators_t06: SkipByDesign # uses integer literal not representable as JavaScript number
-Language/Expressions/Null/instance_of_class_null_t01: SkipByDesign # dart:mirrors not supported https://github.com/dart-lang/co19/issues/522.
 Language/Expressions/Numbers/integer_size_t03: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Numbers/static_type_of_int_t01: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Numbers/syntax_t06: SkipByDesign # uses integer literal not representable as JavaScript number
diff --git a/tests/co19/co19-dartdevc.status b/tests/co19/co19-dartdevc.status
index ef9405d..683bc51 100644
--- a/tests/co19/co19-dartdevc.status
+++ b/tests/co19/co19-dartdevc.status
@@ -8,7 +8,6 @@
 Language/Expressions/Constants/literal_number_t01: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Constants/math_operators_t01: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Constants/math_operators_t06: SkipByDesign # uses integer literal not representable as JavaScript number
-Language/Expressions/Null/instance_of_class_null_t01: SkipByDesign # dart:mirrors not supported https://github.com/dart-lang/co19/issues/522
 Language/Expressions/Numbers/integer_size_t03: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Numbers/static_type_of_int_t01: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Numbers/syntax_t06: SkipByDesign # uses integer literal not representable as JavaScript number
@@ -45,7 +44,6 @@
 LibTest/core/DateTime/DateTime.fromMicrosecondsSinceEpoch_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
 LibTest/core/DateTime/microsecond_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
 LibTest/core/DateTime/microsecondsSinceEpoch_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
-LibTest/core/DateTime/parse_A01_t03: SkipByDesign # microseconds are not supported in JavaScript
 LibTest/core/DateTime/to8601String_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
 LibTest/core/DateTime/to8601String_A01_t02: SkipByDesign # microseconds are not supported in JavaScript
 LibTest/core/DateTime/to8601String_A01_t03: SkipByDesign # microseconds are not supported in JavaScript
@@ -59,21 +57,23 @@
 LibTest/io/*: SkipByDesign # dart:io not supported.
 LibTest/isolate/*: SkipByDesign # dart:isolate not supported.
 LibTest/mirrors/*: SkipByDesign # dart:mirrors is not supported
-LibTest/typed_data/ByteBuffer/*: SkipByDesign # not supported on the web
-LibTest/typed_data/ByteData/getInt64_A01_t01: SkipByDesign # uses integer literal not representable as JavaScript number
-LibTest/typed_data/ByteData/getInt64_A02_t01: SkipByDesign # Int64 accessor not supported by dart2js
-LibTest/typed_data/ByteData/getInt64_A02_t02: SkipByDesign # Int64 accessor not supported by dart2js
-LibTest/typed_data/ByteData/getUint64_A01_t01: SkipByDesign # uses integer literal not representable as JavaScript number
-LibTest/typed_data/ByteData/getUint64_A02_t01: SkipByDesign # Int64 accessor not supported by dart2js
-LibTest/typed_data/ByteData/getUint64_A02_t02: SkipByDesign # Int64 accessor not supported by dart2js
-LibTest/typed_data/ByteData/setInt64_A01_t01: SkipByDesign # Buses integer literal not representable as JavaScript number
-LibTest/typed_data/ByteData/setInt64_A02_t01: SkipByDesign # Int64 accessor not supported by dart2js
-LibTest/typed_data/ByteData/setInt64_A02_t02: SkipByDesign # Int64 accessor not supported by dart2js
-LibTest/typed_data/ByteData/setUint64_A01_t01: SkipByDesign # uses integer literal not representable as JavaScript number
-LibTest/typed_data/ByteData/setUint64_A02_t01: SkipByDesign # Uint64 accessor not supported by dart2js
-LibTest/typed_data/ByteData/setUint64_A02_t02: SkipByDesign # Uint64 accessor not supported by dart2js
-LibTest/typed_data/Int32x4/operator_OR_A01_t01: SkipByDesign # Bitwise operations in JS are unsigned.
-LibTest/typed_data/Int32x4List/join_A01_t01: SkipByDesign # Different string represrntation on VM and in JS
-LibTest/typed_data/Int32x4List/join_A01_t02: SkipByDesign # Different string represrntation on VM and in JS
+LibTest/typed_data/ByteBuffer/asInt64List_A01_t01: SkipByDesign # Int64List not supported on the web
+LibTest/typed_data/ByteBuffer/asInt64List_A02_t01: SkipByDesign # Int64List not supported on the web
+LibTest/typed_data/ByteBuffer/asInt64List_A03_t01: SkipByDesign # Int64List not supported on the web
+LibTest/typed_data/ByteBuffer/asUint64List_A01_t01: SkipByDesign # UInt64List not supported on the web
+LibTest/typed_data/ByteBuffer/asUint64List_A02_t01: SkipByDesign # UInt64List not supported on the web
+LibTest/typed_data/ByteBuffer/asUint64List_A03_t01: SkipByDesign # UInt64List not supported on the web
+LibTest/typed_data/ByteData/getInt64_A01_t01: SkipByDesign # 64-bit int not supported on the web
+LibTest/typed_data/ByteData/getInt64_A02_t01: SkipByDesign # 64-bit int not supported on the web
+LibTest/typed_data/ByteData/getInt64_A02_t02: SkipByDesign # 64-bit int not supported on the web
+LibTest/typed_data/ByteData/getUint64_A01_t01: SkipByDesign # 64-bit int not supported on the web
+LibTest/typed_data/ByteData/getUint64_A02_t01: SkipByDesign # 64-bit int not supported on the web
+LibTest/typed_data/ByteData/getUint64_A02_t02: SkipByDesign # 64-bit int not supported on the web
+LibTest/typed_data/ByteData/setInt64_A01_t01: SkipByDesign # 64-bit int not supported on the web
+LibTest/typed_data/ByteData/setInt64_A02_t01: SkipByDesign # 64-bit int not supported on the web
+LibTest/typed_data/ByteData/setInt64_A02_t02: SkipByDesign # 64-bit int not supported on the web
+LibTest/typed_data/ByteData/setUint64_A01_t01: SkipByDesign # 64-bit int not supported on the web
+LibTest/typed_data/ByteData/setUint64_A02_t01: SkipByDesign # 64-bit int not supported on the web
+LibTest/typed_data/ByteData/setUint64_A02_t02: SkipByDesign # 64-bit int not supported on the web
 LibTest/typed_data/Int64List/*: SkipByDesign # Int64List not supported on the web
 LibTest/typed_data/Uint64List/*: SkipByDesign # Uint64List not supported on the web
diff --git a/tests/co19_2/co19_2-co19.status b/tests/co19_2/co19_2-co19.status
index ff5abb6..f8609dc 100644
--- a/tests/co19_2/co19_2-co19.status
+++ b/tests/co19_2/co19_2-co19.status
@@ -8,8 +8,7 @@
 Language/Generics/typedef_A08_t02: SkipByDesign # https://github.com/dart-lang/sdk/issues/46483
 Language/Generics/typedef_A08_t03: SkipByDesign # https://github.com/dart-lang/sdk/issues/46483
 Language/Generics/typedef_A08_t04: SkipByDesign # https://github.com/dart-lang/sdk/issues/46483
-Language/Libraries_and_Scripts/Scripts/top_level_main_t01: Skip # https://github.com/dart-lang/co19/issues/1137
-Language/Libraries_and_Scripts/Scripts/top_level_main_t06: Skip # https://github.com/dart-lang/co19/issues/1137
+LibTest/io/RawDatagramSocket/*: Skip # https://github.com/dart-lang/co19/issues/195
 
 [ $compiler == dart2js || $compiler == dartdevk ]
 Language/Libraries_and_Scripts/Scripts/top_level_main_t01: SkipByDesign # Uses dart:io.
diff --git a/tests/co19_2/co19_2-dart2js.status b/tests/co19_2/co19_2-dart2js.status
index 177ae2a..29cbe78 100644
--- a/tests/co19_2/co19_2-dart2js.status
+++ b/tests/co19_2/co19_2-dart2js.status
@@ -3,7 +3,13 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2js ]
-Language/Expressions/Null/instance_of_class_null_t01: SkipByDesign # dart:mirrors not supported https://github.com/dart-lang/co19/issues/522.
+Language/Expressions/Constants/integer_size_t03: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/integer_size_t04: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/literal_number_t01: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/math_operators_t01: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/math_operators_t06: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Numbers/integer_size_t03: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Numbers/static_type_of_int_t01: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Numbers/syntax_t06: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Numbers/syntax_t09: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Object_Identity/object_t02: SkipByDesign # https://github.com/dart-lang/sdk/issues/42222#issuecomment-640431711
@@ -12,6 +18,18 @@
 Language/Libraries_and_Scripts/Scripts/top_level_syntax_t01: SkipByDesign # Non-JS-interop external members are not supported
 Language/Libraries_and_Scripts/top_level_syntax_t01: SkipByDesign # Non-JS-interop external members are not supported
 Language/Metadata/before*: SkipByDesign # dart:mirrors not supported https://github.com/dart-lang/co19/issues/523.
+Language/Reference/Operator_Precedence/precedence_15_unary_prefix_t08: SkipByDesign # binary '~' produces different results in JavaScript and Dart
+LibTest/core/DateTime/DateTime.fromMicrosecondsSinceEpoch_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
+LibTest/core/DateTime/microsecond_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
+LibTest/core/DateTime/microsecondsSinceEpoch_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
+LibTest/core/DateTime/parse_A01_t03: SkipByDesign # microseconds are not supported in JavaScript
+LibTest/core/DateTime/to8601String_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
+LibTest/core/DateTime/to8601String_A01_t02: SkipByDesign # microseconds are not supported in JavaScript
+LibTest/core/DateTime/to8601String_A01_t03: SkipByDesign # microseconds are not supported in JavaScript
+LibTest/core/int/operator_remainder_A01_t03: SkipByDesign # Division by zero is not an error in JavaScript
+LibTest/core/int/operator_truncating_division_A01_t02: SkipByDesign # Division by zero is not an error in JavaScript
+LibTest/core/int/parse_A01_t02: SkipByDesign # big integers cannot be represented in JavaScript
+LibTest/core/int/remainder_A01_t03: SkipByDesign # Division by zero is not an error in JavaScript
 LibTest/io/*: SkipByDesign # dart:io not supported.
 LibTest/isolate/*: SkipByDesign # dart:isolate not supported.
 LibTest/typed_data/ByteBuffer/asInt64List_A01_t01: SkipByDesign # Int64List not supported on the web
diff --git a/tests/co19_2/co19_2-dartdevc.status b/tests/co19_2/co19_2-dartdevc.status
index 4129481..13e01d6 100644
--- a/tests/co19_2/co19_2-dartdevc.status
+++ b/tests/co19_2/co19_2-dartdevc.status
@@ -52,18 +52,36 @@
 Language/Classes/Instance_Variables/definition_t02: SkipSlow
 Language/Classes/Instance_Variables/definition_t04: SkipSlow
 Language/Classes/Setters/instance_setter_t01: SkipSlow
+Language/Expressions/Constants/integer_size_t03: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/integer_size_t04: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/literal_number_t01: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/math_operators_t01: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Constants/math_operators_t06: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Function_Invocation/async_generator_invokation_t08: SkipSlow
 Language/Expressions/Function_Invocation/async_generator_invokation_t10: SkipSlow
-Language/Expressions/Null/instance_of_class_null_t01: SkipByDesign # dart:mirrors not supported https://github.com/dart-lang/co19/issues/522.
+Language/Expressions/Numbers/integer_size_t03: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Numbers/static_type_of_int_t01: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Numbers/syntax_t06: SkipByDesign # uses integer literal not representable as JavaScript number
 Language/Expressions/Numbers/syntax_t09: SkipByDesign # uses integer literal not representable as JavaScript number
+Language/Expressions/Object_Identity/object_t02: SkipByDesign # https://github.com/dart-lang/sdk/issues/42222#issuecomment-640431711
 Language/Expressions/Spawning_an_Isolate/new_isolate_t01: SkipByDesign # dart:isolate not supported.
 Language/Functions/External_Functions/not_connected_to_a_body_t01: SkipByDesign # External variables are not supported
 Language/Libraries_and_Scripts/Scripts/top_level_syntax_t01: SkipByDesign # External variables are not supported
 Language/Libraries_and_Scripts/top_level_syntax_t01: SkipByDesign # External variables are not supported
 Language/Metadata/before*: SkipByDesign # dart:mirrors not supported https://github.com/dart-lang/co19/issues/523.
+Language/Reference/Operator_Precedence/precedence_15_unary_prefix_t08: SkipByDesign # binary '~' produces different results in JavaScript and Dart
 Language/Types/Interface_Types/subtype_t27: SkipSlow
 Language/Types/Interface_Types/subtype_t28: SkipSlow
+LibTest/core/DateTime/DateTime.fromMicrosecondsSinceEpoch_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
+LibTest/core/DateTime/microsecond_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
+LibTest/core/DateTime/microsecondsSinceEpoch_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
+LibTest/core/DateTime/to8601String_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
+LibTest/core/DateTime/to8601String_A01_t02: SkipByDesign # microseconds are not supported in JavaScript
+LibTest/core/DateTime/to8601String_A01_t03: SkipByDesign # microseconds are not supported in JavaScript
+LibTest/core/int/operator_remainder_A01_t03: SkipByDesign # Division by zero is not an error in JavaScript
+LibTest/core/int/operator_truncating_division_A01_t02: SkipByDesign # Division by zero is not an error in JavaScript
+LibTest/core/int/parse_A01_t02: SkipByDesign # big integers cannot be represented in JavaScript
+LibTest/core/int/remainder_A01_t03: SkipByDesign # Division by zero is not an error in JavaScript
 LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t03: SkipSlow
 LibTest/html/Element/blur_A01_t01: SkipSlow
 LibTest/html/Element/focus_A01_t01: SkipSlow
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
index 660bb98..0ea8baf 100644
--- a/tests/co19_2/co19_2-kernel.status
+++ b/tests/co19_2/co19_2-kernel.status
@@ -2,12 +2,20 @@
 # 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.
 
-[ $compiler == dartk ]
-Language/Libraries_and_Scripts/Scripts/top_level_main_t01: Crash
-
 [ $compiler == fasta ]
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t04: SkipByDesign # Won't fix. See https://github.com/dart-lang/sdk/issues/46288
 
+[ $runtime == dart_precompiled ]
+LibTest/io/RawDatagramSocket/join_A01_t01: Skip # https://github.com/dart-lang/co19/issues/195
+LibTest/io/RawDatagramSocket/join_A01_t02: Skip # https://github.com/dart-lang/co19/issues/195
+LibTest/io/RawDatagramSocket/join_A02_t01: Skip # https://github.com/dart-lang/co19/issues/195
+LibTest/io/RawDatagramSocket/multicastInterface_A01_t01: Skip # https://github.com/dart-lang/co19/issues/195
+LibTest/io/RawDatagramSocket/receive_A02_t02: Skip # https://github.com/dart-lang/co19/issues/195
+LibTest/io/RawDatagramSocket/reduce_A01_t01: Skip # https://github.com/dart-lang/co19/issues/195
+LibTest/io/RawDatagramSocket/reduce_A02_t02: Skip # https://github.com/dart-lang/co19/issues/195
+LibTest/io/RawDatagramSocket/reduce_A04_t01: Skip # https://github.com/dart-lang/co19/issues/195
+LibTest/mirrors/*: SkipByDesign # dart:mirrors is not supported
+
 [ $runtime == vm ]
 LibTest/collection/ListBase/ListBase_class_A01_t02: Slow, Pass # Does many calls
 LibTest/collection/ListMixin/ListMixin_class_A01_t02: Slow, Pass # Does many calls
@@ -22,10 +30,13 @@
 LibTest/core/List/List_class_A01_t02: Slow, Pass
 LibTest/core/List/List_class_A01_t03: Slow, Pass
 
+[ $runtime == dart_precompiled && ($arch == simarm64 || $arch == simarm64c) ]
+LibTest/collection/ListBase/ListBase_class_A01_t01: SkipSlow # Issue 43036
+LibTest/collection/ListMixin/ListMixin_class_A01_t01: SkipSlow # Issue 43036
+
 # It makes no sense to run any test that uses spawnURI under the simulator
 # as that would involve running CFE (the front end) in simulator mode
 # to compile the URI file specified in spawnURI code.
 # These Isolate tests that use spawnURI are hence skipped on purpose.
 [ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
 LibTest/isolate/Isolate/spawnUri*: Skip
-
diff --git a/tests/co19_2/co19_2-runtime.status b/tests/co19_2/co19_2-runtime.status
index c9cfe7d..2871e90 100644
--- a/tests/co19_2/co19_2-runtime.status
+++ b/tests/co19_2/co19_2-runtime.status
@@ -2,16 +2,9 @@
 # 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.
 
-[ $runtime != none ]
-LibTest/core/Uri/hasEmptyPath_A01_t01: RuntimeError
-LibTest/core/Uri/parse_A05_t01: RuntimeError
-
 [ $system == windows ]
 LibTest/io/ProcessResult/exitCode_A01_t02: Skip # Issue 43645
 
-[ $compiler != dart2js && $runtime != none && $runtime != vm && !$checked ]
-LibTest/async/Future/catchError_A03_t05: RuntimeError
-
 [ $mode == debug && $runtime == dart_precompiled ]
 LibTest/collection/ListBase/ListBase_class_A01_t03: SkipSlow # Very slow compilation in debug mode.
 LibTest/collection/ListBase/ListBase_class_A01_t04: SkipSlow # Very slow compilation in debug mode.
@@ -22,6 +15,9 @@
 LibTest/collection/ListMixin/ListMixin_class_A01_t05: SkipSlow # Very slow compilation in debug mode.
 LibTest/collection/ListMixin/ListMixin_class_A01_t06: SkipSlow # Very slow compilation in debug mode.
 
+[ $runtime == dart_precompiled && ($arch == simarm64 || $arch == simarm64c) ]
+LibTest/async/Stream/Stream.periodic_all_t02: Skip # Issue 42898
+
 [ $arch == simarm || $arch == simarm64 || $arch == simarm64c ]
 LibTest/collection/ListBase/ListBase_class_A01_t01: SkipSlow # Very slow on sim* architectures.
 LibTest/collection/ListBase/ListBase_class_A01_t04: SkipSlow # Very slow on sim* architectures.
diff --git a/tools/VERSION b/tools/VERSION
index 47236c6..4291b21 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 151
+PRERELEASE 152
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/verify_docs/README.md b/tools/verify_docs/README.md
new file mode 100644
index 0000000..13f72bd
--- /dev/null
+++ b/tools/verify_docs/README.md
@@ -0,0 +1,24 @@
+## Whats' this?
+
+A tool to validate the documentation comments for the `dart:` libraries.
+
+## Running the tool
+
+To validate all the dart: libraries, run:
+
+```
+dart tools/verify_docs/bin/verify_docs.dart
+```
+
+Or to validate an individual library (async, collection, js_util, ...), run:
+
+```
+dart tools/verify_docs/bin/verify_docs.dart sdk/lib/<lib-name>
+```
+
+The tool should be run from the root of the sdk repository.
+
+## Authoring code samples
+
+TODO(devoncarew): Document the conventions for code samples in the dart: libraries
+and the tools available to configure them.
diff --git a/tools/verify_docs/bin/verify_docs.dart b/tools/verify_docs/bin/verify_docs.dart
new file mode 100644
index 0000000..ebd4822
--- /dev/null
+++ b/tools/verify_docs/bin/verify_docs.dart
@@ -0,0 +1,308 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/analysis/utilities.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/diagnostic/diagnostic.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/file_system/overlay_file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/src/dart/error/hint_codes.dart';
+import 'package:analyzer/src/util/comment.dart';
+import 'package:path/path.dart' as path;
+
+void main(List<String> args) async {
+  final libDir = Directory('sdk/lib');
+  if (!libDir.existsSync()) {
+    print('Please run this tool from the root of the sdk repo.');
+    exit(1);
+  }
+
+  print('Validating the dartdoc code samples from the dart: libraries.');
+  print('');
+  print('To run this tool, run `dart tools/verify_docs/bin/verify_docs.dart`.');
+  print('For documentation about how to author dart: code samples,'
+      ' see tools/verify_docs/README.md');
+
+  final coreLibraries = args.isEmpty
+      ? libDir.listSync().whereType<Directory>().toList()
+      : args.map((arg) => Directory(arg)).toList();
+  coreLibraries.sort((a, b) => a.path.compareTo(b.path));
+
+  // Skip some dart: libraries.
+  const skipLibraries = {
+    'html',
+    'indexed_db',
+    'svg',
+    'vmservice',
+    'web_audio',
+    'web_gl',
+    'web_sql'
+  };
+  coreLibraries.removeWhere(
+    (lib) => skipLibraries.contains(path.basename(lib.path)),
+  );
+
+  var hadErrors = false;
+  for (final dir in coreLibraries) {
+    hadErrors |= await validateLibrary(dir);
+  }
+
+  exitCode = hadErrors ? 1 : 0;
+}
+
+Future<bool> validateLibrary(Directory dir) async {
+  final libName = path.basename(dir.path);
+
+  print('## dart:$libName');
+  print('');
+
+  var hadErrors = false;
+
+  for (final file in dir
+      .listSync(recursive: true)
+      .whereType<File>()
+      .where((file) => file.path.endsWith('.dart'))) {
+    hadErrors |= await verifyFile(libName, file, dir);
+  }
+
+  return hadErrors;
+}
+
+Future<bool> verifyFile(String coreLibName, File file, Directory parent) async {
+  final text = file.readAsStringSync();
+  var parseResult = parseString(
+    content: text,
+    featureSet: FeatureSet.latestLanguageVersion(),
+    path: file.path,
+    throwIfDiagnostics: false,
+  );
+
+  // Throw if there are syntactic errors.
+  var syntacticErrors = parseResult.errors.where((error) {
+    return error.errorCode.type == ErrorType.SYNTACTIC_ERROR;
+  }).toList();
+  if (syntacticErrors.isNotEmpty) {
+    // todo: have a better failure mode
+    throw Exception(syntacticErrors);
+  }
+
+  var visitor = ValidateCommentCodeSamplesVisitor(
+    coreLibName,
+    file.path,
+    parseResult.lineInfo,
+  );
+  await visitor.process(parseResult);
+  if (visitor.errors.isNotEmpty) {
+    print('${path.relative(file.path, from: parent.parent.path)}');
+    print('${visitor.errors.toString()}');
+  }
+
+  return visitor.errors.isEmpty;
+}
+
+/// todo: doc
+class ValidateCommentCodeSamplesVisitor extends GeneralizingAstVisitor {
+  final String coreLibName;
+  final String filePath;
+  final LineInfo lineInfo;
+
+  ValidateCommentCodeSamplesVisitor(
+    this.coreLibName,
+    this.filePath,
+    this.lineInfo,
+  );
+
+  final List<CodeSample> samples = [];
+  final StringBuffer errors = StringBuffer();
+
+  Future process(ParseStringResult parseResult) async {
+    // collect code samples
+    visitCompilationUnit(parseResult.unit);
+
+    // analyze them
+    for (CodeSample sample in samples) {
+      await validateCodeSample(sample);
+    }
+  }
+
+  @override
+  void visitAnnotatedNode(AnnotatedNode node) {
+    // todo: ignore (or fail?) doc comments on non-public symbols
+    _handleDocumentableNode(node);
+    super.visitAnnotatedNode(node);
+  }
+
+  void _handleDocumentableNode(AnnotatedNode node) {
+    final docComment = node.documentationComment;
+    if (docComment == null || !docComment.isDocumentation) {
+      return;
+    }
+
+    const sampleStart = '```dart';
+    const sampleEnd = '```';
+
+    final text = getCommentNodeRawText(docComment)!;
+    final commentOffset = docComment.offset;
+    final commentLineStart = lineInfo.getLocation(commentOffset).lineNumber;
+    if (!text.contains(sampleStart)) {
+      return;
+    }
+
+    var offset = text.indexOf(sampleStart);
+    while (offset != -1) {
+      offset = text.indexOf('\n', offset) + 1;
+      final end = text.indexOf(sampleEnd, offset);
+
+      var snippet = text.substring(offset, end);
+      snippet = snippet.substring(0, snippet.lastIndexOf('\n'));
+
+      List<String> lines = snippet.split('\n');
+
+      // TODO(devoncarew): Also look for template directives.
+
+      samples.add(
+        CodeSample(
+          coreLibName,
+          lines.map((e) => '  ${cleanDocLine(e)}').join('\n'),
+          commentLineStart +
+              text.substring(0, offset - 1).split('\n').length -
+              1,
+        ),
+      );
+
+      offset = text.indexOf(sampleStart, offset);
+    }
+  }
+
+  Future validateCodeSample(CodeSample sample) async {
+    // TODO(devoncarew): Support <!-- template: none --> ?
+    // TODO(devoncarew): Support <!-- template: main --> ?
+
+    final resourceProvider =
+        OverlayResourceProvider(PhysicalResourceProvider.INSTANCE);
+
+    var text = sample.text;
+    final lines = sample.text.split('\n').map((l) => l.trim()).toList();
+
+    final hasImports = text.contains("import '") || text.contains('import "');
+    var useDefaultTemplate = true;
+
+    if (lines.any((line) =>
+        line.startsWith('class ') ||
+        line.startsWith('enum ') ||
+        line.startsWith('extension '))) {
+      useDefaultTemplate = false;
+    }
+
+    if (lines
+        .any((line) => line.startsWith('main(') || line.contains(' main('))) {
+      useDefaultTemplate = false;
+    }
+
+    if (!hasImports) {
+      if (useDefaultTemplate) {
+        text = "main() async {\n${text.trimRight()}\n}\n";
+      }
+
+      if (sample.coreLibName != 'internal') {
+        text = "import 'dart:${sample.coreLibName}';\n$text";
+      }
+    }
+
+    // Note: the file paths used below will currently only work on posix
+    // filesystems.
+    final sampleFilePath = '/sample.dart';
+
+    resourceProvider.setOverlay(
+      sampleFilePath,
+      content: text,
+      modificationStamp: 0,
+    );
+
+    // TODO(devoncarew): refactor to use AnalysisContextCollection to avoid
+    // re-creating analysis contexts.
+    final result = await resolveFile2(
+      path: sampleFilePath,
+      resourceProvider: resourceProvider,
+    );
+
+    resourceProvider.removeOverlay(sampleFilePath);
+
+    if (result is ResolvedUnitResult) {
+      // Filter out unused imports, since we speculatively add imports to some
+      // samples.
+      var errors =
+          result.errors.where((e) => e.errorCode != HintCode.UNUSED_IMPORT);
+
+      // Also, don't worry about 'unused_local_variable' and related; this may
+      // be intentional in samples.
+      errors = errors.where(
+        (e) =>
+            e.errorCode != HintCode.UNUSED_LOCAL_VARIABLE &&
+            e.errorCode != HintCode.UNUSED_ELEMENT,
+      );
+
+      if (errors.isNotEmpty) {
+        print('$filePath:${sample.lineStart}: ${errors.length} errors');
+
+        for (final error in errors) {
+          final location = result.lineInfo.getLocation(error.offset);
+          print(
+            '  ${_severity(error.severity)}: ${error.message} '
+            '[$location] (${error.errorCode.name.toLowerCase()})',
+          );
+        }
+        print('');
+
+        // Print out the code sample.
+        print(sample.text
+            .split('\n')
+            .map((line) =>
+                '  >${line.length >= 5 ? line.substring(5) : line.trimLeft()}')
+            .join('\n'));
+        print('');
+      }
+    } else {
+      throw 'unexpected result type: ${result}';
+    }
+
+    return;
+  }
+}
+
+String cleanDocLine(String line) {
+  var copy = line.trimLeft();
+  if (copy.startsWith('///')) {
+    copy = copy.substring(3);
+  } else if (copy.startsWith('*')) {
+    copy = copy.substring(1);
+  }
+  return copy.padLeft(line.length, ' ');
+}
+
+class CodeSample {
+  final String coreLibName;
+  final String text;
+  final int lineStart;
+
+  CodeSample(this.coreLibName, this.text, this.lineStart);
+}
+
+String _severity(Severity severity) {
+  switch (severity) {
+    case Severity.info:
+      return 'info';
+    case Severity.warning:
+      return 'warning';
+    case Severity.error:
+      return 'error';
+  }
+}
diff --git a/tools/verify_docs/pubspec.yaml b/tools/verify_docs/pubspec.yaml
new file mode 100644
index 0000000..c9898e5
--- /dev/null
+++ b/tools/verify_docs/pubspec.yaml
@@ -0,0 +1,12 @@
+name: verify_docs
+description: A tool to validate the documentation comments for the `dart:` libraries.
+
+# This package is not intended for consumption on pub.dev. DO NOT publish.
+publish_to: none
+
+environment:
+  sdk: '>=2.12.0 <3.0.0'
+
+dependencies:
+  analyzer: any
+  path: any