From f8582c192950aea4946359639fb6cb7ca65b0a98 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Thu, 6 Dec 2018 16:54:35 +0300 Subject: [PATCH] psi2ir: ersatz type approximation for intersection types Emulate old JVM back-end behavior for intersection type mapping. IrType renderer should render the IR type, not the original Kotlin type. --- .../kotlin/ir/util/RenderIrElement.kt | 111 +++++++--- .../jetbrains/kotlin/ir/util/RenderIrType.kt | 14 -- .../kotlin/ir/util/TypeTranslator.kt | 74 ++++--- .../box/regressions/nestedIntersection.kt | 1 - .../ir/irText/types/intersectionType1.kt | 15 ++ .../ir/irText/types/intersectionType1.txt | 72 +++++++ .../ir/irText/types/intersectionType2.kt | 16 ++ .../ir/irText/types/intersectionType2.txt | 106 +++++++++ .../ir/irText/types/intersectionType3.kt | 30 +++ .../ir/irText/types/intersectionType3.txt | 203 ++++++++++++++++++ .../kotlin/ir/IrTextTestCaseGenerated.java | 28 +++ 11 files changed, 599 insertions(+), 71 deletions(-) delete mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrType.kt create mode 100644 compiler/testData/ir/irText/types/intersectionType1.kt create mode 100644 compiler/testData/ir/irText/types/intersectionType1.txt create mode 100644 compiler/testData/ir/irText/types/intersectionType2.kt create mode 100644 compiler/testData/ir/irText/types/intersectionType2.txt create mode 100644 compiler/testData/ir/irText/types/intersectionType3.kt create mode 100644 compiler/testData/ir/irText/types/intersectionType3.txt diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt index e80677c6094..dea3d11e330 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt @@ -22,12 +22,15 @@ import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.types.* +import org.jetbrains.kotlin.ir.types.impl.originalKotlinType import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.renderer.ClassifierNamePolicy import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.renderer.DescriptorRendererModifier import org.jetbrains.kotlin.renderer.OverrideRenderingPolicy import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.utils.addIfNotNull fun IrElement.render() = accept(RenderIrElementVisitor(), null) @@ -351,38 +354,84 @@ class RenderIrElementVisitor : IrElementVisitor { override fun visitErrorCallExpression(expression: IrErrorCallExpression, data: Nothing?): String = "ERROR_CALL '${expression.description}' type=${expression.type.render()}" +} - companion object { - val DECLARATION_RENDERER = DescriptorRenderer.withOptions { - withDefinedIn = false - overrideRenderingPolicy = OverrideRenderingPolicy.RENDER_OPEN_OVERRIDE - includePropertyConstant = true - classifierNamePolicy = ClassifierNamePolicy.FULLY_QUALIFIED - verbose = false - modifiers = DescriptorRendererModifier.ALL +private val DECLARATION_RENDERER = DescriptorRenderer.withOptions { + withDefinedIn = false + overrideRenderingPolicy = OverrideRenderingPolicy.RENDER_OPEN_OVERRIDE + includePropertyConstant = true + classifierNamePolicy = ClassifierNamePolicy.FULLY_QUALIFIED + verbose = false + modifiers = DescriptorRendererModifier.ALL +} + +private val REFERENCE_RENDERER = DescriptorRenderer.ONLY_NAMES_WITH_SHORT_TYPES + +internal fun IrDeclaration.name(): String = + descriptor.name.toString() + +internal fun DescriptorRenderer.renderDescriptor(descriptor: DeclarationDescriptor): String = + if (descriptor is ReceiverParameterDescriptor) + "this@${descriptor.containingDeclaration.name}: ${descriptor.type}" + else + render(descriptor) + +internal fun IrDeclaration.renderDeclared(): String = + DECLARATION_RENDERER.renderDescriptor(this.descriptor) + +internal fun DeclarationDescriptor.ref(): String = + REFERENCE_RENDERER.renderDescriptor(this.original) + +internal fun KotlinType.render(): String = + DECLARATION_RENDERER.renderType(this) + +internal fun IrDeclaration.renderOriginIfNonTrivial(): String = + if (origin != IrDeclarationOrigin.DEFINED) origin.toString() + " " else "" + +internal fun IrType.renderTypeInner(): String = + when (this) { + is IrDynamicType -> "dynamic" + + is IrErrorType -> "ERROR" + + is IrSimpleType -> buildString { + append(DECLARATION_RENDERER.renderClassifierName(classifier.descriptor)) // TODO get rid of descriptors + if (arguments.isNotEmpty()) { + append( + arguments.joinToString(prefix = "<", postfix = ">", separator = ", ") { + it.renderTypeArgument() + } + ) + } + if (hasQuestionMark) { + append('?') + } } - val REFERENCE_RENDERER = DescriptorRenderer.ONLY_NAMES_WITH_SHORT_TYPES - - internal fun IrDeclaration.name(): String = - descriptor.name.toString() - - internal fun DescriptorRenderer.renderDescriptor(descriptor: DeclarationDescriptor): String = - if (descriptor is ReceiverParameterDescriptor) - "this@${descriptor.containingDeclaration.name}: ${descriptor.type}" - else - render(descriptor) - - internal fun IrDeclaration.renderDeclared(): String = - DECLARATION_RENDERER.renderDescriptor(this.descriptor) - - internal fun DeclarationDescriptor.ref(): String = - REFERENCE_RENDERER.renderDescriptor(this.original) - - internal fun KotlinType.render(): String = - DECLARATION_RENDERER.renderType(this) - - internal fun IrDeclaration.renderOriginIfNonTrivial(): String = - if (origin != IrDeclarationOrigin.DEFINED) origin.toString() + " " else "" + else -> + originalKotlinType?.let { + DECLARATION_RENDERER.renderType(it) + } ?: "IrType without originalKotlinType: $this" } -} \ No newline at end of file + +private fun IrTypeArgument.renderTypeArgument(): String = + when (this) { + is IrStarProjection -> "*" + + is IrTypeProjection -> buildString { + append(variance.label) + if (variance != Variance.INVARIANT) append(' ') + append(type.render()) + } + + else -> "IrTypeArgument[$this]" + } + +internal fun renderTypeAnnotations(annotations: List) = + if (annotations.isEmpty()) + "" + else + annotations.joinToString(prefix = "", postfix = " ", separator = " ") { "@[${it.render()}]" } + +fun IrType.render() = "${renderTypeAnnotations(annotations)}${renderTypeInner()}" + diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrType.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrType.kt deleted file mode 100644 index a5e0dd109a2..00000000000 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrType.kt +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 2010-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.ir.util - -import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.impl.originalKotlinType - -fun IrType.render() = - originalKotlinType?.let { - RenderIrElementVisitor.DECLARATION_RENDERER.renderType(it) - } ?: "IrType without originalKotlinType: $this" \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/TypeTranslator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/TypeTranslator.kt index 3f8d1d8fd22..f4a9382fe7c 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/TypeTranslator.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/TypeTranslator.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections import org.jetbrains.kotlin.types.typesApproximation.approximateCapturedTypes class TypeTranslator( @@ -33,14 +34,14 @@ class TypeTranslator( fun enterScope(irElement: IrTypeParametersContainer) { typeParametersResolver.enterTypeParameterScope(irElement) - if(enterTableScope) { + if (enterTableScope) { symbolTable.enterScope(irElement.descriptor) } } fun leaveScope(irElement: IrTypeParametersContainer) { typeParametersResolver.leaveTypeParameterScope() - if(enterTableScope) { + if (enterTableScope) { symbolTable.leaveScope(irElement.descriptor) } } @@ -54,43 +55,45 @@ class TypeTranslator( private fun resolveTypeParameter(typeParameterDescriptor: TypeParameterDescriptor) = typeParametersResolver.resolveScopedTypeParameter(typeParameterDescriptor) - ?: symbolTable.referenceTypeParameter(typeParameterDescriptor) + ?: symbolTable.referenceTypeParameter(typeParameterDescriptor) fun translateType(ktType: KotlinType): IrType = translateType(ktType, Variance.INVARIANT).type - private fun translateType(ktType0: KotlinType, variance: Variance): IrTypeProjection { - // TODO "old" JVM BE does this for reified type arguments. Is it ok for arbitrary subexpressions? - - val ktTypeUpper = ktType0.approximate(languageVersionSettings) + private fun translateType(ktType: KotlinType, variance: Variance): IrTypeProjection { + val approximatedType = LegacyTypeApproximation().approximate(ktType) when { - ktTypeUpper.isError -> return IrErrorTypeImpl(ktTypeUpper, translateTypeAnnotations(ktTypeUpper.annotations), variance) - ktTypeUpper.isDynamic() -> return IrDynamicTypeImpl(ktTypeUpper, translateTypeAnnotations(ktTypeUpper.annotations), variance) - ktTypeUpper.isFlexible() -> return translateType(ktTypeUpper.upperIfFlexible(), variance) + approximatedType.isError -> + return IrErrorTypeImpl(approximatedType, translateTypeAnnotations(approximatedType.annotations), variance) + approximatedType.isDynamic() -> + return IrDynamicTypeImpl(approximatedType, translateTypeAnnotations(approximatedType.annotations), variance) + approximatedType.isFlexible() -> + return translateType(approximatedType.upperIfFlexible(), variance) } - val ktTypeConstructor = ktTypeUpper.constructor - val ktTypeDescriptor = ktTypeConstructor.declarationDescriptor ?: throw AssertionError("No descriptor for type $ktTypeUpper") + val ktTypeConstructor = approximatedType.constructor + val ktTypeDescriptor = ktTypeConstructor.declarationDescriptor + ?: throw AssertionError("No descriptor for type $approximatedType") return when (ktTypeDescriptor) { is TypeParameterDescriptor -> IrSimpleTypeImpl( - ktTypeUpper, + approximatedType, resolveTypeParameter(ktTypeDescriptor), - ktTypeUpper.isMarkedNullable, + approximatedType.isMarkedNullable, emptyList(), - translateTypeAnnotations(ktTypeUpper.annotations), + translateTypeAnnotations(approximatedType.annotations), variance ) is ClassDescriptor -> IrSimpleTypeImpl( - ktTypeUpper, + approximatedType, symbolTable.referenceClass(ktTypeDescriptor), - ktTypeUpper.isMarkedNullable, - translateTypeArguments(ktTypeUpper.arguments), - translateTypeAnnotations(ktTypeUpper.annotations), + approximatedType.isMarkedNullable, + translateTypeArguments(approximatedType.arguments), + translateTypeAnnotations(approximatedType.annotations), variance ) @@ -99,15 +102,36 @@ class TypeTranslator( } } - private fun KotlinType.approximate(languageVersionSettings: LanguageVersionSettings): KotlinType { - if (this.constructor.isDenotable) return this + private inner class LegacyTypeApproximation { + + fun approximate(ktType: KotlinType): KotlinType { + val properlyApproximatedType = approximateByKotlinRules(ktType) + + // If there's an intersection type, take the most common supertype of its intermediate supertypes. + // That's what old back-end effectively does. + val typeConstructor = properlyApproximatedType.constructor + if (typeConstructor is IntersectionTypeConstructor) { + val commonSupertype = CommonSupertypes.commonSupertype(typeConstructor.supertypes) + return approximate(commonSupertype.replaceArgumentsWithStarProjections()) + } + + // Other types should be approximated properly. Right? Riiight? + return properlyApproximatedType + } + + + private fun approximateByKotlinRules(ktType: KotlinType): KotlinType { + if (ktType.constructor.isDenotable) return ktType + + return if (languageVersionSettings.supportsFeature(LanguageFeature.NewInference)) + typeApproximatorForNI.approximateDeclarationType(ktType, local = false, languageVersionSettings = languageVersionSettings) + else + approximateCapturedTypes(ktType).upper + } - return if (languageVersionSettings.supportsFeature(LanguageFeature.NewInference)) - typeApproximatorForNI.approximateDeclarationType(this, local = false, languageVersionSettings = languageVersionSettings) - else - approximateCapturedTypes(this).upper } + private fun translateTypeAnnotations(annotations: Annotations): List = annotations.map(constantValueGenerator::generateAnnotationConstructorCall) diff --git a/compiler/testData/codegen/box/regressions/nestedIntersection.kt b/compiler/testData/codegen/box/regressions/nestedIntersection.kt index 17aa7eb01d7..764a35d01cd 100644 --- a/compiler/testData/codegen/box/regressions/nestedIntersection.kt +++ b/compiler/testData/codegen/box/regressions/nestedIntersection.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/ir/irText/types/intersectionType1.kt b/compiler/testData/ir/irText/types/intersectionType1.kt new file mode 100644 index 00000000000..333daf95d22 --- /dev/null +++ b/compiler/testData/ir/irText/types/intersectionType1.kt @@ -0,0 +1,15 @@ +class In + +fun select(x: S, y: S): S = x + +fun foo(a: Array>, b: Array>) = + select(a, b)[0].ofType(true) + +inline fun In.ofType(y: Any?) = + y is K + +fun test() { + val a1 = arrayOf(In()) + val a2 = arrayOf(In()) + foo(a1, a2) +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/types/intersectionType1.txt b/compiler/testData/ir/irText/types/intersectionType1.txt new file mode 100644 index 00000000000..a7dce85b9e9 --- /dev/null +++ b/compiler/testData/ir/irText/types/intersectionType1.txt @@ -0,0 +1,72 @@ +FILE fqName: fileName:/intersectionType1.kt + CLASS CLASS name:In modality:FINAL visibility:public flags: superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:In flags: + TYPE_PARAMETER name:I index:0 variance:in superTypes:[kotlin.Any?] + CONSTRUCTOR visibility:public <> () returnType:In flags:primary + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'constructor Any()' + INSTANCE_INITIALIZER_CALL classDescriptor='In' + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + overridden: + FUN IR_EXTERNAL_DECLARATION_STUB name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + VALUE_PARAMETER name:other index:0 type:kotlin.Any? flags: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + overridden: + FUN IR_EXTERNAL_DECLARATION_STUB name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + overridden: + FUN IR_EXTERNAL_DECLARATION_STUB name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + FUN name:select visibility:public modality:FINAL (x:S, y:S) returnType:S flags: + TYPE_PARAMETER name:S index:0 variance: superTypes:[kotlin.Any?] + VALUE_PARAMETER name:x index:0 type:S flags: + VALUE_PARAMETER name:y index:1 type:S flags: + BLOCK_BODY + RETURN type=kotlin.Nothing from='select(S, S): S' + GET_VAR 'value-parameter x: S' type=S origin=null + FUN name:foo visibility:public modality:FINAL (a:kotlin.Array>, b:kotlin.Array>) returnType:kotlin.Boolean flags: + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + VALUE_PARAMETER name:a index:0 type:kotlin.Array> flags: + VALUE_PARAMETER name:b index:1 type:kotlin.Array> flags: + BLOCK_BODY + RETURN type=kotlin.Nothing from='foo(Array>, Array>): Boolean' + CALL 'ofType(Any?) on In: Boolean' type=kotlin.Boolean origin=null + : kotlin.Any? + $receiver: CALL 'get(Int): T' type=In origin=GET_ARRAY_ELEMENT + $this: CALL 'select(S, S): S' type=kotlin.Array> origin=null + : kotlin.Array> + x: GET_VAR 'value-parameter a: Array>' type=kotlin.Array> origin=null + y: GET_VAR 'value-parameter b: Array>' type=kotlin.Array> origin=null + index: CONST Int type=kotlin.Int value=0 + y: CONST Boolean type=kotlin.Boolean value=true + FUN name:ofType visibility:public modality:FINAL ($receiver:In, y:kotlin.Any?) returnType:kotlin.Boolean flags:inline + TYPE_PARAMETER name:K index:0 variance: superTypes:[kotlin.Any?] + $receiver: VALUE_PARAMETER name: type:In flags: + VALUE_PARAMETER name:y index:0 type:kotlin.Any? flags: + BLOCK_BODY + RETURN type=kotlin.Nothing from='ofType(Any?) on In: Boolean' + TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=K + typeOperand: TYPE_PARAMETER name:K index:0 variance: superTypes:[kotlin.Any?] + GET_VAR 'value-parameter y: Any?' type=kotlin.Any? origin=null + FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit flags: + BLOCK_BODY + VAR name:a1 type:kotlin.Array> flags:val + CALL 'arrayOf(vararg T): Array' type=kotlin.Array> origin=null + : In + elements: VARARG type=kotlin.Array> varargElementType=In + CALL 'constructor In()' type=In origin=null + : kotlin.Int + VAR name:a2 type:kotlin.Array> flags:val + CALL 'arrayOf(vararg T): Array' type=kotlin.Array> origin=null + : In + elements: VARARG type=kotlin.Array> varargElementType=In + CALL 'constructor In()' type=In origin=null + : kotlin.String + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public flags: superTypes:[kotlin.Any] + CALL 'foo(Array>, Array>): Boolean' type=kotlin.Boolean origin=null + : kotlin.Int + a: GET_VAR 'a1: Array>' type=kotlin.Array> origin=null + b: GET_VAR 'a2: Array>' type=kotlin.Array> origin=null diff --git a/compiler/testData/ir/irText/types/intersectionType2.kt b/compiler/testData/ir/irText/types/intersectionType2.kt new file mode 100644 index 00000000000..16cc92a379b --- /dev/null +++ b/compiler/testData/ir/irText/types/intersectionType2.kt @@ -0,0 +1,16 @@ +interface A +interface Foo + +open class B : Foo, A +open class C : Foo, A + +fun run(fn: () -> T) = fn() + +fun foo() = run { + val mm = B() + val nn = C() + + val c = if (true) mm else nn + + c +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/types/intersectionType2.txt b/compiler/testData/ir/irText/types/intersectionType2.txt new file mode 100644 index 00000000000..05f116e6558 --- /dev/null +++ b/compiler/testData/ir/irText/types/intersectionType2.txt @@ -0,0 +1,106 @@ +FILE fqName: fileName:/intersectionType2.kt + CLASS INTERFACE name:A modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:A flags: + TYPE_PARAMETER name:T index:0 variance:out superTypes:[kotlin.Any?] + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + overridden: + FUN IR_EXTERNAL_DECLARATION_STUB name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + VALUE_PARAMETER name:other index:0 type:kotlin.Any? flags: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + overridden: + FUN IR_EXTERNAL_DECLARATION_STUB name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + overridden: + FUN IR_EXTERNAL_DECLARATION_STUB name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + CLASS INTERFACE name:Foo modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:Foo flags: + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + overridden: + FUN IR_EXTERNAL_DECLARATION_STUB name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + VALUE_PARAMETER name:other index:0 type:kotlin.Any? flags: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + overridden: + FUN IR_EXTERNAL_DECLARATION_STUB name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + overridden: + FUN IR_EXTERNAL_DECLARATION_STUB name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + CLASS CLASS name:B modality:OPEN visibility:public flags: superTypes:[Foo; A] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:B flags: + CONSTRUCTOR visibility:public <> () returnType:B flags:primary + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'constructor Any()' + INSTANCE_INITIALIZER_CALL classDescriptor='B' + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + overridden: + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + VALUE_PARAMETER name:other index:0 type:kotlin.Any? flags: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + overridden: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + overridden: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + CLASS CLASS name:C modality:OPEN visibility:public flags: superTypes:[Foo; A] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:C flags: + CONSTRUCTOR visibility:public <> () returnType:C flags:primary + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'constructor Any()' + INSTANCE_INITIALIZER_CALL classDescriptor='C' + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + overridden: + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + VALUE_PARAMETER name:other index:0 type:kotlin.Any? flags: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + overridden: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + overridden: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + FUN name:run visibility:public modality:FINAL (fn:kotlin.Function0) returnType:T flags: + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + VALUE_PARAMETER name:fn index:0 type:kotlin.Function0 flags: + BLOCK_BODY + RETURN type=kotlin.Nothing from='run(() -> T): T' + CALL 'invoke(): R' type=T origin=INVOKE + $this: GET_VAR 'value-parameter fn: () -> T' type=kotlin.Function0 origin=VARIABLE_AS_FUNCTION + FUN name:foo visibility:public modality:FINAL <> () returnType:kotlin.Any flags: + BLOCK_BODY + RETURN type=kotlin.Nothing from='foo(): Any' + CALL 'run(() -> T): T' type=kotlin.Any origin=null + : kotlin.Any + fn: BLOCK type=kotlin.Function0 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:kotlin.Any flags: + BLOCK_BODY + VAR name:mm type:B flags:val + CALL 'constructor B()' type=B origin=null + VAR name:nn type:C flags:val + CALL 'constructor C()' type=C origin=null + VAR name:c type:kotlin.Any flags:val + WHEN type=kotlin.Any origin=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'mm: B' type=B origin=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'nn: C' type=C origin=null + RETURN type=kotlin.Nothing from='(): Any' + GET_VAR 'c: Any' type=kotlin.Any origin=null + FUNCTION_REFERENCE '(): Any' type=kotlin.Function0 origin=LAMBDA diff --git a/compiler/testData/ir/irText/types/intersectionType3.kt b/compiler/testData/ir/irText/types/intersectionType3.kt new file mode 100644 index 00000000000..825c47ad354 --- /dev/null +++ b/compiler/testData/ir/irText/types/intersectionType3.kt @@ -0,0 +1,30 @@ +interface In + +inline fun In.isT(): Boolean = + this is T + +inline fun In.asT() { this as T } + +fun sel(x: S, y: S): S = x + +interface A +interface B + +interface A1 : A +interface A2 : A + +interface Z1 : A, B +interface Z2 : A, B + + +fun testInIs1(x: In, y: In) = sel(x, y).isT() + +fun testInIs2(x: In, y: In) = sel(x, y).isT() + +fun testInIs3(x: In, y: In) = sel(x, y).isT() + +fun testInAs1(x: In, y: In) = sel(x, y).asT() + +fun testInAs2(x: In, y: In) = sel(x, y).asT() + +fun testInAs3(x: In, y: In) = sel(x, y).asT() diff --git a/compiler/testData/ir/irText/types/intersectionType3.txt b/compiler/testData/ir/irText/types/intersectionType3.txt new file mode 100644 index 00000000000..80d8cc843f0 --- /dev/null +++ b/compiler/testData/ir/irText/types/intersectionType3.txt @@ -0,0 +1,203 @@ +FILE fqName: fileName:/intersectionType3.kt + CLASS INTERFACE name:In modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:In flags: + TYPE_PARAMETER name:T index:0 variance:in superTypes:[kotlin.Any?] + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + overridden: + FUN IR_EXTERNAL_DECLARATION_STUB name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + VALUE_PARAMETER name:other index:0 type:kotlin.Any? flags: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + overridden: + FUN IR_EXTERNAL_DECLARATION_STUB name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + overridden: + FUN IR_EXTERNAL_DECLARATION_STUB name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + FUN name:isT visibility:public modality:FINAL ($receiver:In) returnType:kotlin.Boolean flags:inline + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + $receiver: VALUE_PARAMETER name: type:In flags: + BLOCK_BODY + RETURN type=kotlin.Nothing from='isT() on In: Boolean' + TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=T + typeOperand: TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + GET_VAR 'this@isT: In' type=In origin=null + FUN name:asT visibility:public modality:FINAL ($receiver:In) returnType:kotlin.Unit flags:inline + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + $receiver: VALUE_PARAMETER name: type:In flags: + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public flags: superTypes:[kotlin.Any] + TYPE_OP type=T origin=CAST typeOperand=T + typeOperand: TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] + GET_VAR 'this@asT: In' type=In origin=null + FUN name:sel visibility:public modality:FINAL (x:S, y:S) returnType:S flags: + TYPE_PARAMETER name:S index:0 variance: superTypes:[kotlin.Any?] + VALUE_PARAMETER name:x index:0 type:S flags: + VALUE_PARAMETER name:y index:1 type:S flags: + BLOCK_BODY + RETURN type=kotlin.Nothing from='sel(S, S): S' + GET_VAR 'value-parameter x: S' type=S origin=null + CLASS INTERFACE name:A modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:A flags: + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + overridden: + FUN IR_EXTERNAL_DECLARATION_STUB name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + VALUE_PARAMETER name:other index:0 type:kotlin.Any? flags: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + overridden: + FUN IR_EXTERNAL_DECLARATION_STUB name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + overridden: + FUN IR_EXTERNAL_DECLARATION_STUB name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + CLASS INTERFACE name:B modality:ABSTRACT visibility:public flags: superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:B flags: + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + overridden: + FUN IR_EXTERNAL_DECLARATION_STUB name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + VALUE_PARAMETER name:other index:0 type:kotlin.Any? flags: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + overridden: + FUN IR_EXTERNAL_DECLARATION_STUB name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + overridden: + FUN IR_EXTERNAL_DECLARATION_STUB name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + CLASS INTERFACE name:A1 modality:ABSTRACT visibility:public flags: superTypes:[A] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:A1 flags: + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + overridden: + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + VALUE_PARAMETER name:other index:0 type:kotlin.Any? flags: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + overridden: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + overridden: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + CLASS INTERFACE name:A2 modality:ABSTRACT visibility:public flags: superTypes:[A] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:A2 flags: + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + overridden: + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + VALUE_PARAMETER name:other index:0 type:kotlin.Any? flags: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + overridden: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + overridden: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + CLASS INTERFACE name:Z1 modality:ABSTRACT visibility:public flags: superTypes:[A; B] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:Z1 flags: + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + overridden: + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + VALUE_PARAMETER name:other index:0 type:kotlin.Any? flags: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + overridden: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + overridden: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + CLASS INTERFACE name:Z2 modality:ABSTRACT visibility:public flags: superTypes:[A; B] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:Z2 flags: + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + overridden: + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + VALUE_PARAMETER name:other index:0 type:kotlin.Any? flags: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + overridden: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + overridden: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: + $this: VALUE_PARAMETER name: type:kotlin.Any flags: + FUN name:testInIs1 visibility:public modality:FINAL <> (x:In, y:In) returnType:kotlin.Boolean flags: + VALUE_PARAMETER name:x index:0 type:In flags: + VALUE_PARAMETER name:y index:1 type:In flags: + BLOCK_BODY + RETURN type=kotlin.Nothing from='testInIs1(In, In): Boolean' + CALL 'isT() on In: Boolean' type=kotlin.Boolean origin=null + : kotlin.Any + $receiver: CALL 'sel(S, S): S' type=In origin=null + : In + x: GET_VAR 'value-parameter x: In' type=In origin=null + y: GET_VAR 'value-parameter y: In' type=In origin=null + FUN name:testInIs2 visibility:public modality:FINAL <> (x:In, y:In) returnType:kotlin.Boolean flags: + VALUE_PARAMETER name:x index:0 type:In flags: + VALUE_PARAMETER name:y index:1 type:In flags: + BLOCK_BODY + RETURN type=kotlin.Nothing from='testInIs2(In, In): Boolean' + CALL 'isT() on In: Boolean' type=kotlin.Boolean origin=null + : kotlin.Any + $receiver: CALL 'sel(S, S): S' type=In origin=null + : In + x: GET_VAR 'value-parameter x: In' type=In origin=null + y: GET_VAR 'value-parameter y: In' type=In origin=null + FUN name:testInIs3 visibility:public modality:FINAL <> (x:In, y:In) returnType:kotlin.Boolean flags: + VALUE_PARAMETER name:x index:0 type:In flags: + VALUE_PARAMETER name:y index:1 type:In flags: + BLOCK_BODY + RETURN type=kotlin.Nothing from='testInIs3(In, In): Boolean' + CALL 'isT() on In: Boolean' type=kotlin.Boolean origin=null + : A + $receiver: CALL 'sel(S, S): S' type=In origin=null + : In + x: GET_VAR 'value-parameter x: In' type=In origin=null + y: GET_VAR 'value-parameter y: In' type=In origin=null + FUN name:testInAs1 visibility:public modality:FINAL <> (x:In, y:In) returnType:kotlin.Unit flags: + VALUE_PARAMETER name:x index:0 type:In flags: + VALUE_PARAMETER name:y index:1 type:In flags: + BLOCK_BODY + RETURN type=kotlin.Nothing from='testInAs1(In, In): Unit' + CALL 'asT() on In: Unit' type=kotlin.Unit origin=null + : kotlin.Any + $receiver: CALL 'sel(S, S): S' type=In origin=null + : In + x: GET_VAR 'value-parameter x: In' type=In origin=null + y: GET_VAR 'value-parameter y: In' type=In origin=null + FUN name:testInAs2 visibility:public modality:FINAL <> (x:In, y:In) returnType:kotlin.Unit flags: + VALUE_PARAMETER name:x index:0 type:In flags: + VALUE_PARAMETER name:y index:1 type:In flags: + BLOCK_BODY + RETURN type=kotlin.Nothing from='testInAs2(In, In): Unit' + CALL 'asT() on In: Unit' type=kotlin.Unit origin=null + : kotlin.Any + $receiver: CALL 'sel(S, S): S' type=In origin=null + : In + x: GET_VAR 'value-parameter x: In' type=In origin=null + y: GET_VAR 'value-parameter y: In' type=In origin=null + FUN name:testInAs3 visibility:public modality:FINAL <> (x:In, y:In) returnType:kotlin.Unit flags: + VALUE_PARAMETER name:x index:0 type:In flags: + VALUE_PARAMETER name:y index:1 type:In flags: + BLOCK_BODY + RETURN type=kotlin.Nothing from='testInAs3(In, In): Unit' + CALL 'asT() on In: Unit' type=kotlin.Unit origin=null + : A + $receiver: CALL 'sel(S, S): S' type=In origin=null + : In + x: GET_VAR 'value-parameter x: In' type=In origin=null + y: GET_VAR 'value-parameter y: In' type=In origin=null diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index 4bafd1ed6b8..90f7a6d853f 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -1485,4 +1485,32 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { runTest("compiler/testData/ir/irText/stubs/simple.kt"); } } + + @TestMetadata("compiler/testData/ir/irText/types") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Types extends AbstractIrTextTestCase { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInTypes() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/ir/irText/types"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("intersectionType1.kt") + public void testIntersectionType1() throws Exception { + runTest("compiler/testData/ir/irText/types/intersectionType1.kt"); + } + + @TestMetadata("intersectionType2.kt") + public void testIntersectionType2() throws Exception { + runTest("compiler/testData/ir/irText/types/intersectionType2.kt"); + } + + @TestMetadata("intersectionType3.kt") + public void testIntersectionType3() throws Exception { + runTest("compiler/testData/ir/irText/types/intersectionType3.kt"); + } + } }