Report error on typeOf<suspend ...>()
Otherwise an invalid type is constructed which causes kotlin-reflect to crash, and stdlib implementation to render the type incorrectly. The reason is that suspend functional types are not properly supported in reflection. Once they are supported, this error can be removed. #KT-47562
This commit is contained in:
@@ -2971,8 +2971,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
if (isDefaultCompilation) {
|
||||
return new InlineCodegenForDefaultBody(functionDescriptor, this, state, signature, sourceCompiler);
|
||||
} else {
|
||||
return new PsiInlineCodegen(this, state, functionDescriptor, signature, typeParameterMappings, sourceCompiler,
|
||||
typeMapper.mapImplementationOwner(functionDescriptor), typeMapper.mapOwner(descriptor));
|
||||
return new PsiInlineCodegen(
|
||||
this, state, functionDescriptor, signature, typeParameterMappings, sourceCompiler,
|
||||
typeMapper.mapImplementationOwner(functionDescriptor), typeMapper.mapOwner(descriptor), callElement
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,11 +43,12 @@ class PsiInlineCodegen(
|
||||
typeParameterMappings: TypeParameterMappings<KotlinType>,
|
||||
sourceCompiler: SourceCompilerForInline,
|
||||
private val methodOwner: Type,
|
||||
private val actualDispatchReceiver: Type
|
||||
private val actualDispatchReceiver: Type,
|
||||
reportErrorsOn: KtElement,
|
||||
) : InlineCodegen<ExpressionCodegen>(
|
||||
codegen, state, signature, typeParameterMappings, sourceCompiler,
|
||||
ReifiedTypeInliner(
|
||||
typeParameterMappings, PsiInlineIntrinsicsSupport(state), codegen.typeSystem,
|
||||
typeParameterMappings, PsiInlineIntrinsicsSupport(state, reportErrorsOn), codegen.typeSystem,
|
||||
state.languageVersionSettings, state.unifiedNullChecks
|
||||
),
|
||||
), CallGenerator {
|
||||
|
||||
+10
-1
@@ -12,8 +12,10 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.TYPEOF_SUSPEND_TYPE
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -21,7 +23,10 @@ import org.jetbrains.org.objectweb.asm.Type.INT_TYPE
|
||||
import org.jetbrains.org.objectweb.asm.Type.VOID_TYPE
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class PsiInlineIntrinsicsSupport(override val state: GenerationState) : ReifiedTypeInliner.IntrinsicsSupport<KotlinType> {
|
||||
class PsiInlineIntrinsicsSupport(
|
||||
override val state: GenerationState,
|
||||
private val reportErrorsOn: KtElement,
|
||||
) : ReifiedTypeInliner.IntrinsicsSupport<KotlinType> {
|
||||
override fun putClassInstance(v: InstructionAdapter, type: KotlinType) {
|
||||
DescriptorAsmUtil.putJavaLangClassInstance(v, state.typeMapper.mapType(type), type, state.typeMapper)
|
||||
}
|
||||
@@ -64,4 +69,8 @@ class PsiInlineIntrinsicsSupport(override val state: GenerationState) : ReifiedT
|
||||
}
|
||||
|
||||
override fun toKotlinType(type: KotlinType): KotlinType = type
|
||||
|
||||
override fun reportSuspendTypeUnsupported() {
|
||||
state.diagnostics.report(TYPEOF_SUSPEND_TYPE.on(reportErrorsOn))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,8 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
|
||||
fun isMutableCollectionType(type: KT): Boolean
|
||||
|
||||
fun toKotlinType(type: KT): KotlinType
|
||||
|
||||
fun reportSuspendTypeUnsupported()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
|
||||
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||
@@ -90,6 +91,10 @@ fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateTypeOf(
|
||||
|
||||
v.invokestatic(REFLECTION, methodName, signature, false)
|
||||
|
||||
if (intrinsicsSupport.toKotlinType(type).isSuspendFunctionType) {
|
||||
intrinsicsSupport.reportSuspendTypeUnsupported()
|
||||
}
|
||||
|
||||
if (intrinsicsSupport.state.stableTypeOf) {
|
||||
if (intrinsicsSupport.isMutableCollectionType(type)) {
|
||||
v.invokestatic(REFLECTION, "mutableCollectionType", Type.getMethodDescriptor(K_TYPE, K_TYPE), false)
|
||||
|
||||
+2
@@ -208,6 +208,8 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
|
||||
|
||||
MAP.put(VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION, "Value classes without @JvmInline annotation are not supported yet");
|
||||
MAP.put(JVM_INLINE_WITHOUT_VALUE_CLASS, "@JvmInline annotation is only applicable to value classes");
|
||||
|
||||
MAP.put(TYPEOF_SUSPEND_TYPE, "Suspend functional types are not supported in typeOf");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -175,6 +175,8 @@ public interface ErrorsJvm {
|
||||
DiagnosticFactory0<PsiElement> VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> JVM_INLINE_WITHOUT_VALUE_CLASS = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<PsiElement> TYPEOF_SUSPEND_TYPE = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
Object _initializer = new Object() {
|
||||
{
|
||||
|
||||
+1
-1
@@ -1448,7 +1448,7 @@ class ExpressionCodegen(
|
||||
|
||||
val reifiedTypeInliner = ReifiedTypeInliner(
|
||||
mappings,
|
||||
IrInlineIntrinsicsSupport(context, typeMapper),
|
||||
IrInlineIntrinsicsSupport(context, typeMapper, element, irFunction.fileParent),
|
||||
context.typeSystem,
|
||||
state.languageVersionSettings,
|
||||
state.unifiedNullChecks,
|
||||
|
||||
+9
-1
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
@@ -22,6 +23,7 @@ import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.TYPEOF_SUSPEND_TYPE
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -31,7 +33,9 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class IrInlineIntrinsicsSupport(
|
||||
private val context: JvmBackendContext,
|
||||
private val typeMapper: IrTypeMapper
|
||||
private val typeMapper: IrTypeMapper,
|
||||
private val reportErrorsOn: IrExpression,
|
||||
private val containingFile: IrFile,
|
||||
) : ReifiedTypeInliner.IntrinsicsSupport<IrType> {
|
||||
override val state: GenerationState
|
||||
get() = context.state
|
||||
@@ -107,4 +111,8 @@ class IrInlineIntrinsicsSupport(
|
||||
}
|
||||
|
||||
override fun toKotlinType(type: IrType): KotlinType = type.toIrBasedKotlinType()
|
||||
|
||||
override fun reportSuspendTypeUnsupported() {
|
||||
context.psiErrorBuilder.at(reportErrorsOn, containingFile).report(TYPEOF_SUSPEND_TYPE)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.IrInlineIntrinsicsSupport
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.fileParent
|
||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
|
||||
import org.jetbrains.kotlin.codegen.inline.generateTypeOf
|
||||
import org.jetbrains.kotlin.codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter
|
||||
@@ -19,7 +20,8 @@ object TypeOf : IntrinsicMethod() {
|
||||
if (putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.TYPE_OF)) {
|
||||
mv.aconst(null) // see ReifiedTypeInliner.processTypeOf
|
||||
} else {
|
||||
typeMapper.typeSystem.generateTypeOf(mv, type, IrInlineIntrinsicsSupport(context, typeMapper))
|
||||
val support = IrInlineIntrinsicsSupport(context, typeMapper, expression, codegen.irFunction.fileParent)
|
||||
typeMapper.typeSystem.generateTypeOf(mv, type, support)
|
||||
}
|
||||
expression.onStack
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// WITH_RUNTIME
|
||||
// USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
|
||||
import kotlin.reflect.*
|
||||
|
||||
inline fun <reified X> f() = g<List<X>>()
|
||||
inline fun <reified Y> g() = typeOf<Y>()
|
||||
|
||||
fun test() {
|
||||
<!TYPEOF_SUSPEND_TYPE!>typeOf<suspend () -> Int>()<!>
|
||||
<!TYPEOF_SUSPEND_TYPE!>f<suspend (String) -> Unit>()<!>
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package
|
||||
|
||||
public inline fun </*0*/ reified X> f(): kotlin.reflect.KType
|
||||
public inline fun </*0*/ reified Y> g(): kotlin.reflect.KType
|
||||
public fun test(): kotlin.Unit
|
||||
+16
@@ -663,6 +663,22 @@ public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnostic
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithJvmBackend/typeOf")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class TypeOf {
|
||||
@Test
|
||||
public void testAllFilesPresentInTypeOf() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/typeOf"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendType.kt")
|
||||
public void testSuspendType() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithJvmBackend/typeOf/suspendType.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithJvmBackend/valueClasses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+16
@@ -651,6 +651,22 @@ public class DiagnosticsTestWithOldJvmBackendGenerated extends AbstractDiagnosti
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithJvmBackend/typeOf")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class TypeOf {
|
||||
@Test
|
||||
public void testAllFilesPresentInTypeOf() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJvmBackend/typeOf"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_OLD, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendType.kt")
|
||||
public void testSuspendType() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithJvmBackend/typeOf/suspendType.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithJvmBackend/valueClasses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
Reference in New Issue
Block a user