FIR: Fix capturing of flexible types

This commit is contained in:
Denis Zharkov
2020-01-29 15:30:17 +03:00
parent ac2b5beb4e
commit d28e1f156a
7 changed files with 29 additions and 9 deletions
@@ -207,7 +207,7 @@ fun Candidate.resolvePlainArgumentType(
val position = SimpleConstraintSystemConstraintPosition //TODO
val session = sink.components.session
val capturedType = prepareCapturedType(argumentType, session)
val capturedType = prepareCapturedType(argumentType)
val nullableExpectedType = expectedType.withNullability(ConeNullability.NULLABLE, session.inferenceContext)
if (isReceiver && isSafeCall) {
@@ -220,12 +220,20 @@ fun Candidate.resolvePlainArgumentType(
checkApplicabilityForArgumentType(csBuilder, capturedType, expectedType, position, isReceiver, isDispatch, nullableExpectedType, sink)
}
fun Candidate.prepareCapturedType(argumentType: ConeKotlinType, session: FirSession): ConeKotlinType {
if (argumentType.typeArguments.isEmpty() || argumentType !is ConeClassLikeType) return argumentType
fun Candidate.prepareCapturedType(argumentType: ConeKotlinType): ConeKotlinType {
return captureTypeFromExpressionOrNull(argumentType) ?: argumentType
}
private fun Candidate.captureTypeFromExpressionOrNull(argumentType: ConeKotlinType): ConeKotlinType? {
if (argumentType is ConeFlexibleType) {
return captureTypeFromExpressionOrNull(argumentType.lowerBound)
}
if (argumentType.typeArguments.isEmpty() || argumentType !is ConeClassLikeType) return null
return bodyResolveComponents.inferenceComponents.ctx.captureFromArguments(
argumentType, CaptureStatus.FROM_EXPRESSION
) as? ConeKotlinType ?: argumentType
) as? ConeKotlinType
}
private fun checkApplicabilityForArgumentType(
@@ -0,0 +1,3 @@
fun foo(z: java.util.zip.ZipFile) {
z.entries().asSequence()
}
@@ -0,0 +1,4 @@
FILE: capturedFlexible.kt
public final fun foo(z: R|java/util/zip/ZipFile|): R|kotlin/Unit| {
R|<local>/z|.R|java/util/zip/ZipFile.entries|().R|kotlin/sequences/asSequence|<R|captured type: lowerType = null|>()
}
@@ -464,6 +464,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/stdlib/j+k"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("capturedFlexible.kt")
public void testCapturedFlexible() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/j+k/capturedFlexible.kt");
}
@TestMetadata("complexFlexibleInference.kt")
public void testComplexFlexibleInference() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/j+k/complexFlexibleInference.kt");
+2 -2
View File
@@ -6,6 +6,6 @@ import java.util.stream.IntStream
fun main() {
val xs = IntStream.range(0, 10).mapToObj { it.toString() }
.<!INAPPLICABLE_CANDIDATE!>collect<!>(Collectors.toList())
.collect(Collectors.toList())
<!UNRESOLVED_REFERENCE!>xs[0]<!>
}
}
@@ -7,8 +7,8 @@ import java.util.stream.Collectors
import java.util.stream.Stream
fun test(a: Stream<String>) {
a.<!INAPPLICABLE_CANDIDATE!>collect<!>(Collectors.toList()) <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><MutableList<String>>() }
a.collect(Collectors.toList()) checkType { <!UNRESOLVED_REFERENCE!>_<!><MutableList<String>>() }
// actually the inferred type is platform
a.<!INAPPLICABLE_CANDIDATE!>collect<!>(Collectors.toList()) <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!UNRESOLVED_REFERENCE!>_<!><List<String?>>() }
a.collect(Collectors.toList()) checkType { <!UNRESOLVED_REFERENCE!>_<!><List<String?>>() }
}
@@ -8,6 +8,6 @@ interface A : Collection<String> {
}
fun foo(x: List<String>, y: A) {
x.stream().filter { it.length > 0 }.<!INAPPLICABLE_CANDIDATE!>collect<!>(Collectors.toList())
x.stream().filter { it.length > 0 }.collect(Collectors.toList())
y.stream().filter { it.length > 0 }
}