From 4cd07f59a07376ba8a77cea7cf699d2438ae35bf Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Wed, 17 Jan 2018 18:27:12 +0300 Subject: [PATCH] [NI] Don't fail on captured type that contains type variable --- .../TypeCheckerContextForConstraintSystem.kt | 30 +++++++++++-------- .../capturedTypeWithTypeVariableSubtyping.kt | 22 ++++++++++++++ .../capturedTypeWithTypeVariableSubtyping.txt | 10 +++++++ .../tests/inference/dependantOnVariance.kt | 2 +- .../tests/regressions/OutProjections.kt | 2 +- .../checkers/DiagnosticsTestGenerated.java | 6 ++++ .../DiagnosticsUsingJavacTestGenerated.java | 6 ++++ 7 files changed, 63 insertions(+), 15 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypeWithTypeVariableSubtyping.kt create mode 100644 compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypeWithTypeVariableSubtyping.txt diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeCheckerContextForConstraintSystem.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeCheckerContextForConstraintSystem.kt index 92fc20794b1..79e78bfab6c 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeCheckerContextForConstraintSystem.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeCheckerContextForConstraintSystem.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.resolve.calls.inference.components @@ -83,10 +72,25 @@ abstract class TypeCheckerContextForConstraintSystem : TypeCheckerContext(errorT if (subType.anyBound(this::isMyTypeVariable)) { return simplifyUpperConstraint(subType, superType) && (answer ?: true) } else { + extractTypeVariableForSubtype(subType)?.let { + return simplifyUpperConstraint(it, superType) && (answer ?: true) + } + return simplifyConstraintForPossibleIntersectionSubType(subType, superType) ?: answer } } + // extract type variable only from type like Captured(out T) + private fun extractTypeVariableForSubtype(type: UnwrappedType): UnwrappedType? { + if (type !is NewCapturedType) return null + + val projection = type.constructor.projection + return if (projection.projectionKind == Variance.OUT_VARIANCE) + projection.type.takeIf { it is SimpleType && isMyTypeVariable(it) }?.unwrap() + else + null + } + /** * Foo <: T -- leave as is * diff --git a/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypeWithTypeVariableSubtyping.kt b/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypeWithTypeVariableSubtyping.kt new file mode 100644 index 00000000000..bd4e8035bb6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypeWithTypeVariableSubtyping.kt @@ -0,0 +1,22 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun takeCovArray(a: Array) {} +fun takeInArray(a: Array) {} + +fun foo(): Array = TODO() +fun bar(): Array = TODO() + +fun id(x: X): X = x +fun arrayInId(z: Array): Array = z +fun arrayOutId(z: Array): Array = z + +fun test() { + takeCovArray(foo()) + takeInArray(bar()) + + takeCovArray(id(foo())) + takeInArray(id(bar())) + + takeCovArray(arrayOutId(foo())) + takeInArray(arrayInId(bar())) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypeWithTypeVariableSubtyping.txt b/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypeWithTypeVariableSubtyping.txt new file mode 100644 index 00000000000..5835d79f2ae --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypeWithTypeVariableSubtyping.txt @@ -0,0 +1,10 @@ +package + +public fun arrayInId(/*0*/ z: kotlin.Array): kotlin.Array +public fun arrayOutId(/*0*/ z: kotlin.Array): kotlin.Array +public fun bar(): kotlin.Array +public fun foo(): kotlin.Array +public fun id(/*0*/ x: X): X +public fun takeCovArray(/*0*/ a: kotlin.Array): kotlin.Unit +public fun takeInArray(/*0*/ a: kotlin.Array): kotlin.Unit +public fun test(): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/inference/dependantOnVariance.kt b/compiler/testData/diagnostics/tests/inference/dependantOnVariance.kt index 7d80b88e614..c8fd293dcb9 100644 --- a/compiler/testData/diagnostics/tests/inference/dependantOnVariance.kt +++ b/compiler/testData/diagnostics/tests/inference/dependantOnVariance.kt @@ -18,7 +18,7 @@ fun test1(int: Int, any: Any) { val a2 : MyList = getMyList(int) - val a3 : MyList = getMyListToReadFrom(int) + val a3 : MyList = getMyListToReadFrom(int) val a4 : MyList = getMyList(any) diff --git a/compiler/testData/diagnostics/tests/regressions/OutProjections.kt b/compiler/testData/diagnostics/tests/regressions/OutProjections.kt index b7a94fe10b1..c35554e7d8c 100644 --- a/compiler/testData/diagnostics/tests/regressions/OutProjections.kt +++ b/compiler/testData/diagnostics/tests/regressions/OutProjections.kt @@ -18,5 +18,5 @@ fun fout(expression : T) : Out< { val p = Point(); - return fout(p); + return fout(p); } \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index b5b33109a24..0d9c7fbbd9a 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -10660,6 +10660,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("capturedTypeWithTypeVariableSubtyping.kt") + public void testCapturedTypeWithTypeVariableSubtyping() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypeWithTypeVariableSubtyping.kt"); + doTest(fileName); + } + @TestMetadata("expectedTypeMismatchWithInVariance.kt") public void testExpectedTypeMismatchWithInVariance() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/expectedTypeMismatchWithInVariance.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index e1afb270cb9..3c4d9bdfc5f 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -10660,6 +10660,12 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing doTest(fileName); } + @TestMetadata("capturedTypeWithTypeVariableSubtyping.kt") + public void testCapturedTypeWithTypeVariableSubtyping() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypeWithTypeVariableSubtyping.kt"); + doTest(fileName); + } + @TestMetadata("expectedTypeMismatchWithInVariance.kt") public void testExpectedTypeMismatchWithInVariance() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/expectedTypeMismatchWithInVariance.kt");