[CFE] Demonstrate changing interfaceTargetReference via noSuchMethod on recompilation

http://dartbug.com/48892

Change-Id: I85dd6afdc2bb0eb0e04602666cbdf7be30b7e6ce
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/242444
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/testcases/incremental.status b/pkg/front_end/testcases/incremental.status
index 39b3507..4f768a0 100644
--- a/pkg/front_end/testcases/incremental.status
+++ b/pkg/front_end/testcases/incremental.status
@@ -11,3 +11,4 @@
 late_lowering: EquivalenceError
 constant_fileoffset_and_typedef: EquivalenceError
 no_change_but_changed_type: EquivalenceError
+no_such_method_forwarder: EquivalenceError
diff --git a/pkg/front_end/testcases/incremental/no_such_method_forwarder.yaml b/pkg/front_end/testcases/incremental/no_such_method_forwarder.yaml
new file mode 100644
index 0000000..eb1b359
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/no_such_method_forwarder.yaml
@@ -0,0 +1,35 @@
+# 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.md file.
+
+# Recompiling shouldn't change the InstanceInvocation.interfaceTargetReference.
+# http://dartbug.com/48892
+
+type: newworld
+worlds:
+  - entry: main.dart
+    sources:
+      main.dart: |
+        import "lib1.dart";
+        main() {
+          Y y = new Y();
+          y.foo();
+        }
+      lib1.dart: |
+        class X {
+          void foo() => print("foo");
+        }
+        class Y implements X {
+          void noSuchMethod(Invocation _) {
+            print("Hello from noSuchMethod");
+          }
+        }
+    expectedLibraryCount: 2
+
+  - entry: main.dart
+    worldType: updated
+    compareToPrevious: true
+    expectInitializeFromDill: false
+    invalidate:
+      - main.dart
+    expectedLibraryCount: 2
diff --git a/pkg/front_end/testcases/incremental/no_such_method_forwarder.yaml.world.1.expect b/pkg/front_end/testcases/incremental/no_such_method_forwarder.yaml.world.1.expect
new file mode 100644
index 0000000..f9a6cfb
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/no_such_method_forwarder.yaml.world.1.expect
@@ -0,0 +1,36 @@
+main = main::main;
+library from "org-dartlang-test:///lib1.dart" as lib1 {
+
+  class X extends dart.core::Object {
+    synthetic constructor •() → lib1::X
+      : super dart.core::Object::•()
+      ;
+    method foo() → void
+      return dart.core::print("foo");
+  }
+  class Y extends dart.core::Object implements lib1::X {
+    synthetic constructor •() → lib1::Y
+      : super dart.core::Object::•()
+      ;
+    method noSuchMethod(dart.core::Invocation _) → void {
+      dart.core::print("Hello from noSuchMethod");
+    }
+    no-such-method-forwarder method foo() → void
+      return this.{lib1::Y::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → void};
+  }
+}
+library from "org-dartlang-test:///main.dart" as main {
+
+  import "org-dartlang-test:///lib1.dart";
+
+  static method main() → dynamic {
+    lib1::Y y = new lib1::Y::•();
+    y.{lib1::X::foo}(){() → void};
+  }
+}
+constants  {
+  #C1 = #foo
+  #C2 = <dart.core::Type*>[]
+  #C3 = <dynamic>[]
+  #C4 = <dart.core::Symbol*, dynamic>{)
+}
diff --git a/pkg/front_end/testcases/incremental/no_such_method_forwarder.yaml.world.2.expect b/pkg/front_end/testcases/incremental/no_such_method_forwarder.yaml.world.2.expect
new file mode 100644
index 0000000..b99b734
--- /dev/null
+++ b/pkg/front_end/testcases/incremental/no_such_method_forwarder.yaml.world.2.expect
@@ -0,0 +1,36 @@
+main = main::main;
+library from "org-dartlang-test:///lib1.dart" as lib1 {
+
+  class X extends dart.core::Object {
+    synthetic constructor •() → lib1::X
+      : super dart.core::Object::•()
+      ;
+    method foo() → void
+      return dart.core::print("foo");
+  }
+  class Y extends dart.core::Object implements lib1::X {
+    synthetic constructor •() → lib1::Y
+      : super dart.core::Object::•()
+      ;
+    method noSuchMethod(dart.core::Invocation _) → void {
+      dart.core::print("Hello from noSuchMethod");
+    }
+    no-such-method-forwarder method foo() → void
+      return this.{lib1::Y::noSuchMethod}(new dart.core::_InvocationMirror::_withType(#C1, 0, #C2, #C3, dart.core::Map::unmodifiable<dart.core::Symbol*, dynamic>(#C4))){(dart.core::Invocation) → void};
+  }
+}
+library from "org-dartlang-test:///main.dart" as main {
+
+  import "org-dartlang-test:///lib1.dart";
+
+  static method main() → dynamic {
+    lib1::Y y = new lib1::Y::•();
+    y.{lib1::Y::foo}(){() → void};
+  }
+}
+constants  {
+  #C1 = #foo
+  #C2 = <dart.core::Type*>[]
+  #C3 = <dynamic>[]
+  #C4 = <dart.core::Symbol*, dynamic>{)
+}