In _matchInterfaceSubtypeOf, account for mixins having null superclass.
Fixes #34907.
Change-Id: I1ba56bf57d6ca5a7a69f262e12df801dc2cc4a4a
Reviewed-on: https://dart-review.googlesource.com/c/81322
Auto-Submit: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 1cb22ad..beb1160 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -508,13 +508,17 @@
//
// We don't need undo logic here because if the classes don't match, nothing
// is added to the constraint set.
- if (guardedInterfaceSubtype(i1.superclass)) return true;
+ var superclass = i1.superclass;
+ if (superclass != null && guardedInterfaceSubtype(superclass)) return true;
for (final parent in i1.interfaces) {
if (guardedInterfaceSubtype(parent)) return true;
}
for (final parent in i1.mixins) {
if (guardedInterfaceSubtype(parent)) return true;
}
+ for (final parent in i1.superclassConstraints) {
+ if (guardedInterfaceSubtype(parent)) return true;
+ }
return false;
}
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index a40a5eb..be2fa81 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -3655,6 +3655,29 @@
verify([source]);
}
+ test_methodCallTypeInference_mixinType() async {
+ Source source = addSource('''
+main() {
+ C<int> c = f();
+}
+
+class C<T> {}
+
+mixin M<T> on C<T> {}
+
+M<T> f<T>() => null;
+''');
+ var result = await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ var main = result.unit.declarations[0] as FunctionDeclaration;
+ var body = main.functionExpression.body as BlockFunctionBody;
+ var cDeclaration = body.block.statements[0] as VariableDeclarationStatement;
+ var fInvocation =
+ cDeclaration.variables.variables[0].initializer as MethodInvocation;
+ expect(fInvocation.staticInvokeType.toString(), '() → M<int>');
+ }
+
test_methodDeclaration_scope_signature() async {
Source source = addSource(r'''
const app = 0;
diff --git a/tests/language_2/issue34907_test.dart b/tests/language_2/issue34907_test.dart
new file mode 100644
index 0000000..85fdf28
--- /dev/null
+++ b/tests/language_2/issue34907_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2018, 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 "package:expect/expect.dart";
+
+class C<T> {}
+
+mixin M<T> on C<T> {}
+
+M<T> f<T>() {
+ Expect.equals(T, int);
+ return null;
+}
+
+main() {
+ C<int> c = f();
+}