[vm] Fix nullability checks for FutureOr in Class::IsSubtypeOf.

TEST=vm/dart/regress_48522

Fixed: https://github.com/dart-lang/sdk/issues/48522
Change-Id: I228ff30bd6223a01acd7ab8eea45bf5e35c55cc5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/237082
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
diff --git a/runtime/tests/vm/dart/regress_48522_test.dart b/runtime/tests/vm/dart/regress_48522_test.dart
new file mode 100644
index 0000000..d01562b
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_48522_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for https://github.com/dart-lang/sdk/issues/48522.
+// Test that FutureOr<T?> = FutureOr<T?>? <: Future<T?>?.
+
+import 'dart:async';
+
+import 'package:expect/expect.dart';
+
+Future<String?>? foo() {
+  return null;
+}
+
+FutureOr<String?>? bar() {
+  return null;
+}
+
+FutureOr<String?> baz() {
+  return null;
+}
+
+typedef F = FutureOr<String?> Function();
+typedef G = FutureOr<String?>? Function();
+
+void main() {
+  // Check Future<T?>? <: FutureOr<T?>?.
+  print(foo.runtimeType);
+  Expect.isTrue(foo is G);
+  (foo as dynamic) as G; // Should not throw.
+
+  final G v1 = foo;
+  print(v1.runtimeType);
+  Expect.isTrue(v1 is G);
+  (v1 as dynamic) as G; // Should not throw.
+
+  // Check Future<T?>? <: FutureOr<T?>.
+  print(foo.runtimeType);
+  Expect.isTrue(foo is F);
+  (foo as dynamic) as F; // Should not throw.
+
+  final F v2 = foo;
+  print(v2.runtimeType);
+  Expect.isTrue(v2 is F);
+  (v2 as dynamic) as F; // Should not throw.
+
+  // Check FutureOr<T?> = FutureOr<T?>?.
+  print(bar.runtimeType);
+  Expect.isTrue(bar is F);
+  (bar as dynamic) as F; // Should not throw.
+  print(baz.runtimeType);
+  Expect.isTrue(baz is G);
+  (baz as dynamic) as G; // Should not throw.
+}
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 241097c..2b6b9c2 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -5416,7 +5416,9 @@
             AbstractType::Handle(zone, type_arguments.TypeAtNullSafe(0));
         // If T0 is Future<S0>, then T0 <: Future<S1>, iff S0 <: S1.
         if (type_arg.IsSubtypeOf(other_type_arg, space, trail)) {
-          if (verified_nullability) {
+          // verified_nullability doesn't take into account the nullability of
+          // S1, just of the FutureOr type.
+          if (verified_nullability || !other_type_arg.IsNonNullable()) {
             return true;
           }
         }