FIR: Allow to skip specifying type arguments for members from raw type
^KT-54666 Fixed ^KT-54526 Related
This commit is contained in:
committed by
Space Team
parent
c0e0900344
commit
1e368bcd86
+6
@@ -24181,6 +24181,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
|||||||
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/kt47459.kt");
|
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/kt47459.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("noTypeArgumentsForRawScopedMembers.kt")
|
||||||
|
public void testNoTypeArgumentsForRawScopedMembers() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/noTypeArgumentsForRawScopedMembers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("nonGenericRawMember.kt")
|
@TestMetadata("nonGenericRawMember.kt")
|
||||||
public void testNonGenericRawMember() throws Exception {
|
public void testNonGenericRawMember() throws Exception {
|
||||||
|
|||||||
+6
@@ -24181,6 +24181,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/kt47459.kt");
|
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/kt47459.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("noTypeArgumentsForRawScopedMembers.kt")
|
||||||
|
public void testNoTypeArgumentsForRawScopedMembers() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/noTypeArgumentsForRawScopedMembers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("nonGenericRawMember.kt")
|
@TestMetadata("nonGenericRawMember.kt")
|
||||||
public void testNonGenericRawMember() throws Exception {
|
public void testNonGenericRawMember() throws Exception {
|
||||||
|
|||||||
+6
@@ -24181,6 +24181,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
|||||||
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/kt47459.kt");
|
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/kt47459.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("noTypeArgumentsForRawScopedMembers.kt")
|
||||||
|
public void testNoTypeArgumentsForRawScopedMembers() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/noTypeArgumentsForRawScopedMembers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("nonGenericRawMember.kt")
|
@TestMetadata("nonGenericRawMember.kt")
|
||||||
public void testNonGenericRawMember() throws Exception {
|
public void testNonGenericRawMember() throws Exception {
|
||||||
|
|||||||
+35
-3
@@ -5,11 +5,17 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.calls
|
package org.jetbrains.kotlin.fir.resolve.calls
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
|
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeTypeIntersector
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildPlaceholderProjection
|
import org.jetbrains.kotlin.fir.types.builder.buildPlaceholderProjection
|
||||||
|
import org.jetbrains.kotlin.fir.types.builder.buildTypeProjectionWithVariance
|
||||||
|
import org.jetbrains.kotlin.fir.types.isRaw
|
||||||
|
import org.jetbrains.kotlin.fir.types.toFirResolvedTypeRef
|
||||||
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
sealed class TypeArgumentMapping {
|
sealed class TypeArgumentMapping {
|
||||||
abstract operator fun get(typeParameterIndex: Int): FirTypeProjection
|
abstract operator fun get(typeParameterIndex: Int): FirTypeProjection
|
||||||
@@ -28,13 +34,17 @@ sealed class TypeArgumentMapping {
|
|||||||
internal object MapTypeArguments : ResolutionStage() {
|
internal object MapTypeArguments : ResolutionStage() {
|
||||||
override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) {
|
override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) {
|
||||||
val typeArguments = callInfo.typeArguments
|
val typeArguments = callInfo.typeArguments
|
||||||
|
val owner = candidate.symbol.fir as FirTypeParameterRefsOwner
|
||||||
|
|
||||||
if (typeArguments.isEmpty()) {
|
if (typeArguments.isEmpty()) {
|
||||||
candidate.typeArgumentMapping = TypeArgumentMapping.NoExplicitArguments
|
if (owner is FirCallableDeclaration && owner.dispatchReceiverType?.isRaw() == true) {
|
||||||
|
candidate.typeArgumentMapping = computeDefaultMappingForRawTypeMember(owner, context)
|
||||||
|
} else {
|
||||||
|
candidate.typeArgumentMapping = TypeArgumentMapping.NoExplicitArguments
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val owner = candidate.symbol.fir as FirTypeParameterRefsOwner
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
typeArguments.size == owner.typeParameters.size ||
|
typeArguments.size == owner.typeParameters.size ||
|
||||||
callInfo.callKind == CallKind.DelegatingConstructorCall ||
|
callInfo.callKind == CallKind.DelegatingConstructorCall ||
|
||||||
@@ -46,6 +56,28 @@ internal object MapTypeArguments : ResolutionStage() {
|
|||||||
sink.yieldDiagnostic(InapplicableCandidate)
|
sink.yieldDiagnostic(InapplicableCandidate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun computeDefaultMappingForRawTypeMember(
|
||||||
|
owner: FirTypeParameterRefsOwner,
|
||||||
|
context: ResolutionContext
|
||||||
|
): TypeArgumentMapping.Mapped {
|
||||||
|
// There might be some minor inconsistencies where in K2, there might be a raw type, while in K1, there was a regular flexible type
|
||||||
|
// And in that case for K2 we would start a regular inference process leads to TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER because raw scopes
|
||||||
|
// don't leave type variables there (see KT-54526)
|
||||||
|
// Also, it might be a separate feature of K2, because even in cases where both compilers had a raw type, it's convenient not to
|
||||||
|
// require explicit type arguments for the places where it doesn't make sense
|
||||||
|
// (See `generic1.foo(w)` call in testData/diagnostics/tests/platformTypes/rawTypes/noTypeArgumentsForRawScopedMembers.fir.kt)
|
||||||
|
val resultArguments = owner.typeParameters.map { typeParameterRef ->
|
||||||
|
buildTypeProjectionWithVariance {
|
||||||
|
typeRef =
|
||||||
|
ConeTypeIntersector.intersectTypes(
|
||||||
|
context.typeContext, typeParameterRef.symbol.resolvedBounds.map { it.type }
|
||||||
|
).toFirResolvedTypeRef()
|
||||||
|
variance = Variance.INVARIANT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TypeArgumentMapping.Mapped(resultArguments)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal object NoTypeArguments : ResolutionStage() {
|
internal object NoTypeArguments : ResolutionStage() {
|
||||||
|
|||||||
compiler/testData/diagnostics/tests/platformTypes/rawTypes/noTypeArgumentsForRawScopedMembers.fir.kt
Vendored
+23
@@ -0,0 +1,23 @@
|
|||||||
|
// SKIP_TXT
|
||||||
|
// FILE: Generic.java
|
||||||
|
public class Generic<T> {
|
||||||
|
public static class ML<E> {}
|
||||||
|
public static Generic create() { return null; }
|
||||||
|
public <E> void foo(ML<E> w) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
import Generic.ML
|
||||||
|
|
||||||
|
fun main(w: ML<String>) {
|
||||||
|
val generic1 = Generic.create()
|
||||||
|
val generic2 = Generic.create() ?: return
|
||||||
|
|
||||||
|
// Not enough information to infer E (both K1 and K2 after KT-41794 is done)
|
||||||
|
// Because generic information is erased from the raw type scope of `generic1`
|
||||||
|
// But the parameter E is still there (that is a questionable behavior)
|
||||||
|
generic1.foo(w)
|
||||||
|
|
||||||
|
// `generic2` does have just non-raw type `Generic<Any!>..Generic<*>?`
|
||||||
|
generic2.foo(w) // OK in K1, fails in K2 after KT-41794 is done
|
||||||
|
}
|
||||||
Vendored
+23
@@ -0,0 +1,23 @@
|
|||||||
|
// SKIP_TXT
|
||||||
|
// FILE: Generic.java
|
||||||
|
public class Generic<T> {
|
||||||
|
public static class ML<E> {}
|
||||||
|
public static Generic create() { return null; }
|
||||||
|
public <E> void foo(ML<E> w) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
import Generic.ML
|
||||||
|
|
||||||
|
fun main(w: ML<String>) {
|
||||||
|
val generic1 = Generic.create()
|
||||||
|
val generic2 = Generic.create() ?: return
|
||||||
|
|
||||||
|
// Not enough information to infer E (both K1 and K2 after KT-41794 is done)
|
||||||
|
// Because generic information is erased from the raw type scope of `generic1`
|
||||||
|
// But the parameter E is still there (that is a questionable behavior)
|
||||||
|
generic1.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>(w)
|
||||||
|
|
||||||
|
// `generic2` does have just non-raw type `Generic<Any!>..Generic<*>?`
|
||||||
|
generic2.foo(w) // OK in K1, fails in K2 after KT-41794 is done
|
||||||
|
}
|
||||||
Generated
+6
@@ -24187,6 +24187,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/kt47459.kt");
|
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/kt47459.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("noTypeArgumentsForRawScopedMembers.kt")
|
||||||
|
public void testNoTypeArgumentsForRawScopedMembers() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/noTypeArgumentsForRawScopedMembers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("nonGenericRawMember.kt")
|
@TestMetadata("nonGenericRawMember.kt")
|
||||||
public void testNonGenericRawMember() throws Exception {
|
public void testNonGenericRawMember() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user