[fasta] Fix crash when override inference depends on field inference

Change-Id: I34a273185ba09f2740783cf8a25ac6d5f754c621
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/104762
Reviewed-by: Aske Simon Christensen <askesc@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index 5aa6fb8..040d468 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -911,7 +911,7 @@
       debug?.log(
           "${cls.fullNameForErrors} -> ${bCls.fullNameForErrors} $bSubstitution");
     }
-    if (bSubstitution != null) {
+    if (bSubstitution != null && inheritedType is! ImplicitFieldType) {
       inheritedType = bSubstitution.substituteType(inheritedType);
     }
 
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart
new file mode 100644
index 0000000..ebc84b6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A<X> {
+  final foo = "bar";
+}
+
+class B<Y> extends A<Y> {
+  final foo;
+
+  B(this.foo);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.hierarchy.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.hierarchy.expect
new file mode 100644
index 0000000..6bb747c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A<Y>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.legacy.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.legacy.expect
new file mode 100644
index 0000000..d00064e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.legacy.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+  final field dynamic foo = "bar";
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+class B<Y extends core::Object = dynamic> extends self::A<self::B::Y> {
+  final field dynamic foo;
+  constructor •(dynamic foo) → self::B<self::B::Y>
+    : self::B::foo = foo, super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.legacy.transformed.expect
new file mode 100644
index 0000000..d00064e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.legacy.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+  final field dynamic foo = "bar";
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+class B<Y extends core::Object = dynamic> extends self::A<self::B::Y> {
+  final field dynamic foo;
+  constructor •(dynamic foo) → self::B<self::B::Y>
+    : self::B::foo = foo, super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.outline.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.outline.expect
new file mode 100644
index 0000000..0a5257b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.outline.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+  final field dynamic foo;
+  synthetic constructor •() → self::A<self::A::X>
+    ;
+}
+class B<Y extends core::Object = dynamic> extends self::A<self::B::Y> {
+  final field dynamic foo;
+  constructor •(dynamic foo) → self::B<self::B::Y>
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.strong.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.strong.expect
new file mode 100644
index 0000000..faa19da
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.strong.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+  final field core::String foo = "bar";
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+class B<Y extends core::Object = dynamic> extends self::A<self::B::Y> {
+  final field core::String foo;
+  constructor •(core::String foo) → self::B<self::B::Y>
+    : self::B::foo = foo, super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.strong.transformed.expect
new file mode 100644
index 0000000..faa19da
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+  final field core::String foo = "bar";
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+class B<Y extends core::Object = dynamic> extends self::A<self::B::Y> {
+  final field core::String foo;
+  constructor •(core::String foo) → self::B<self::B::Y>
+    : self::B::foo = foo, super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 0147dc9..43c0eb4 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -474,6 +474,7 @@
 inference/null_literal_should_not_infer_as_bottom: TextSerializationFailure # Was: Pass
 inference/overloaded_int_operators: TextSerializationFailure # Was: Pass
 inference/override_equals: TextSerializationFailure # Was: RuntimeError
+inference/override_inference_depends_on_field_inference: TextSerializationFailure
 inference/parameter_defaults_downwards: TextSerializationFailure # Was: Pass
 inference/parameter_defaults_upwards: TextSerializationFailure # Was: Pass
 inference/promote_bounds: TextSerializationFailure # Was: Pass