FIR: Fix capturing of flexible types
This commit is contained in:
@@ -207,7 +207,7 @@ fun Candidate.resolvePlainArgumentType(
|
|||||||
val position = SimpleConstraintSystemConstraintPosition //TODO
|
val position = SimpleConstraintSystemConstraintPosition //TODO
|
||||||
|
|
||||||
val session = sink.components.session
|
val session = sink.components.session
|
||||||
val capturedType = prepareCapturedType(argumentType, session)
|
val capturedType = prepareCapturedType(argumentType)
|
||||||
|
|
||||||
val nullableExpectedType = expectedType.withNullability(ConeNullability.NULLABLE, session.inferenceContext)
|
val nullableExpectedType = expectedType.withNullability(ConeNullability.NULLABLE, session.inferenceContext)
|
||||||
if (isReceiver && isSafeCall) {
|
if (isReceiver && isSafeCall) {
|
||||||
@@ -220,12 +220,20 @@ fun Candidate.resolvePlainArgumentType(
|
|||||||
checkApplicabilityForArgumentType(csBuilder, capturedType, expectedType, position, isReceiver, isDispatch, nullableExpectedType, sink)
|
checkApplicabilityForArgumentType(csBuilder, capturedType, expectedType, position, isReceiver, isDispatch, nullableExpectedType, sink)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Candidate.prepareCapturedType(argumentType: ConeKotlinType, session: FirSession): ConeKotlinType {
|
fun Candidate.prepareCapturedType(argumentType: ConeKotlinType): ConeKotlinType {
|
||||||
if (argumentType.typeArguments.isEmpty() || argumentType !is ConeClassLikeType) return argumentType
|
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(
|
return bodyResolveComponents.inferenceComponents.ctx.captureFromArguments(
|
||||||
argumentType, CaptureStatus.FROM_EXPRESSION
|
argumentType, CaptureStatus.FROM_EXPRESSION
|
||||||
) as? ConeKotlinType ?: argumentType
|
) as? ConeKotlinType
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkApplicabilityForArgumentType(
|
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|>()
|
||||||
|
}
|
||||||
Generated
+5
@@ -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);
|
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")
|
@TestMetadata("complexFlexibleInference.kt")
|
||||||
public void testComplexFlexibleInference() throws Exception {
|
public void testComplexFlexibleInference() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/j+k/complexFlexibleInference.kt");
|
runTest("compiler/fir/resolve/testData/resolve/stdlib/j+k/complexFlexibleInference.kt");
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ import java.util.stream.IntStream
|
|||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
val xs = IntStream.range(0, 10).mapToObj { it.toString() }
|
val xs = IntStream.range(0, 10).mapToObj { it.toString() }
|
||||||
.<!INAPPLICABLE_CANDIDATE!>collect<!>(Collectors.toList())
|
.collect(Collectors.toList())
|
||||||
<!UNRESOLVED_REFERENCE!>xs[0]<!>
|
<!UNRESOLVED_REFERENCE!>xs[0]<!>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import java.util.stream.Collectors
|
|||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
|
|
||||||
fun test(a: Stream<String>) {
|
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
|
// 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) {
|
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 }
|
y.stream().filter { it.length > 0 }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user