From 0009ca7b1bedf27defbd3fd539a8081fcbb72d40 Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Wed, 24 Oct 2018 01:06:25 +0000 Subject: [PATCH] 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 Reviewed-by: Konstantin Shcheglov Commit-Queue: Paul Berry --- .../lib/src/generated/type_system.dart | 6 ++++- .../generated/non_error_resolver_test.dart | 23 +++++++++++++++++++ tests/language_2/issue34907_test.dart | 18 +++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 tests/language_2/issue34907_test.dart diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart index 1cb22ad9a84..beb11602467 100644 --- a/pkg/analyzer/lib/src/generated/type_system.dart +++ b/pkg/analyzer/lib/src/generated/type_system.dart @@ -508,13 +508,17 @@ class GenericInferrer { // // 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 a40a5eb6fbb..be2fa811e79 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 @@ enum E { verify([source]); } + test_methodCallTypeInference_mixinType() async { + Source source = addSource(''' +main() { + C c = f(); +} + +class C {} + +mixin M on C {} + +M f() => 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'); + } + 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 00000000000..85fdf2825cd --- /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 {} + +mixin M on C {} + +M f() { + Expect.equals(T, int); + return null; +} + +main() { + C c = f(); +}