diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/CallBasedArgumentGenerator.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/CallBasedArgumentGenerator.java index 0e022854215..539d3440dda 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/CallBasedArgumentGenerator.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/CallBasedArgumentGenerator.java @@ -1,17 +1,6 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-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.codegen; @@ -28,7 +17,7 @@ import org.jetbrains.org.objectweb.asm.Type; import java.util.List; -import static org.jetbrains.kotlin.codegen.StackValue.*; +import static org.jetbrains.kotlin.codegen.StackValue.createDefaultValue; public class CallBasedArgumentGenerator extends ArgumentGenerator { private final ExpressionCodegen codegen; @@ -64,7 +53,12 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator { @Override protected void generateDefault(int i, @NotNull DefaultValueArgument argument) { - callGenerator.putValueIfNeeded(valueParameterTypes.get(i), createDefaultValue(valueParameterTypes.get(i)), ValueKind.DEFAULT_PARAMETER, i); + callGenerator.putValueIfNeeded( + getJvmKotlinType(valueParameterTypes, valueParameters, i), + createDefaultValue(valueParameterTypes.get(i)), + ValueKind.DEFAULT_PARAMETER, + i + ); } @Override @@ -73,7 +67,7 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator { // Upper bound for type of vararg parameter should always have a form of 'Array', // while its lower bound may be Nothing-typed after approximation StackValue lazyVararg = codegen.genVarargs(argument, FlexibleTypesKt.upperIfFlexible(parameter.getType())); - callGenerator.putValueIfNeeded(valueParameterTypes.get(i), lazyVararg, ValueKind.GENERAL_VARARG, i); + callGenerator.putValueIfNeeded(getJvmKotlinType(valueParameterTypes, valueParameters, i), lazyVararg, ValueKind.GENERAL_VARARG, i); } @Override @@ -84,11 +78,19 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator { codegen.typeMapper ); - callGenerator.putValueIfNeeded(valueParameterTypes.get(i), argumentValue); + callGenerator.putValueIfNeeded(getJvmKotlinType(valueParameterTypes, valueParameters, i), argumentValue); } @Override protected void reorderArgumentsIfNeeded(@NotNull List actualArgsWithDeclIndex) { callGenerator.reorderArgumentsIfNeeded(actualArgsWithDeclIndex, valueParameterTypes); } + + @NotNull + private static JvmKotlinType getJvmKotlinType( + @NotNull List valueParameterTypes, + @NotNull List valueParameters, int i + ) { + return new JvmKotlinType(valueParameterTypes.get(i), valueParameters.get(i).getOriginal().getType()); + } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/CallGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/CallGenerator.kt index c24a31d348f..08796ff1a88 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/CallGenerator.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/CallGenerator.kt @@ -59,8 +59,8 @@ interface CallGenerator { stackValue.put(stackValue.type, codegen.v) } - override fun putValueIfNeeded(parameterType: Type, value: StackValue, kind: ValueKind, parameterIndex: Int) { - value.put(value.type, codegen.v) + override fun putValueIfNeeded(parameterType: JvmKotlinType, value: StackValue, kind: ValueKind, parameterIndex: Int) { + value.put(value.type, value.kotlinType, codegen.v) } override fun reorderArgumentsIfNeeded(actualArgsWithDeclIndex: List, valueParameterTypes: List) { @@ -104,13 +104,13 @@ interface CallGenerator { parameterIndex: Int) fun putValueIfNeeded( - parameterType: Type, + parameterType: JvmKotlinType, value: StackValue) { putValueIfNeeded(parameterType, value, ValueKind.GENERAL) } fun putValueIfNeeded( - parameterType: Type, + parameterType: JvmKotlinType, value: StackValue, kind: ValueKind = ValueKind.GENERAL, parameterIndex: Int = -1) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultCallArgs.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultCallArgs.kt index 1d2ac95b713..989e41a42ae 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultCallArgs.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultCallArgs.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-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.codegen @@ -55,11 +44,15 @@ class DefaultCallArgs(val size: Int) { val toInts = toInts() if (!toInts.isEmpty()) { for (mask in toInts) { - callGenerator.putValueIfNeeded(Type.INT_TYPE, StackValue.constant(mask, Type.INT_TYPE), ValueKind.DEFAULT_MASK) + callGenerator.putValueIfNeeded( + JvmKotlinType(Type.INT_TYPE), StackValue.constant(mask, Type.INT_TYPE), ValueKind.DEFAULT_MASK + ) } val parameterType = if (isConstructor) AsmTypes.DEFAULT_CONSTRUCTOR_MARKER else AsmTypes.OBJECT_TYPE - callGenerator.putValueIfNeeded(parameterType, StackValue.constant(null, parameterType), ValueKind.METHOD_HANDLE_IN_DEFAULT) + callGenerator.putValueIfNeeded( + JvmKotlinType(parameterType), StackValue.constant(null, parameterType), ValueKind.METHOD_HANDLE_IN_DEFAULT + ) } return toInts.isNotEmpty() } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 8055b799b85..0a605fbe4d5 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -2342,7 +2342,9 @@ public class ExpressionCodegen extends KtVisitor impleme List callableParameters = ((CallableMethod) callableMethod).getValueParameters(); for (JvmMethodParameterSignature parameter: callableParameters) { if (parameter.getKind() == JvmMethodParameterKind.CONSTRUCTOR_MARKER) { - callGenerator.putValueIfNeeded(parameter.getAsmType(), StackValue.constant(null, parameter.getAsmType())); + callGenerator.putValueIfNeeded( + new JvmKotlinType(parameter.getAsmType(), null), StackValue.constant(null, parameter.getAsmType()) + ); } } } @@ -2584,10 +2586,13 @@ public class ExpressionCodegen extends KtVisitor impleme @NotNull private StackValue generateExtensionReceiver(@NotNull CallableDescriptor descriptor) { - if (myFrameMap.getIndex(descriptor.getExtensionReceiverParameter()) != -1) { + ReceiverParameterDescriptor parameter = descriptor.getExtensionReceiverParameter(); + if (myFrameMap.getIndex(parameter) != -1) { + KotlinType type = parameter.getReturnType(); return StackValue.local( - myFrameMap.getIndex(descriptor.getExtensionReceiverParameter()), - typeMapper.mapType(descriptor.getExtensionReceiverParameter()) + myFrameMap.getIndex(parameter), + typeMapper.mapType(type), + type ); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index e013a0cf321..060005a8d6e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -1192,7 +1192,7 @@ public class FunctionCodegen { ValueParameterDescriptor parameterDescriptor = valueParameters.get(index); Type type = mappedParameters.get(capturedArgumentsCount + index).getAsmType(); int parameterIndex = frameMap.getIndex(parameterDescriptor); - generator.putValueIfNeeded(type, StackValue.local(parameterIndex, type)); + generator.putValueIfNeeded(new JvmKotlinType(type, null), StackValue.local(parameterIndex, type)); } CallableMethod method = state.getTypeMapper().mapToCallableMethod(functionDescriptor, false); @@ -1264,14 +1264,14 @@ public class FunctionCodegen { ) { int var = 0; if (!isStatic) { - callGenerator.putValueIfNeeded(ownerType, StackValue.local(var, ownerType)); + callGenerator.putValueIfNeeded(new JvmKotlinType(ownerType, null), StackValue.local(var, ownerType)); var += ownerType.getSize(); } for (JvmMethodParameterSignature parameterSignature : signature.getValueParameters()) { if (parameterSignature.getKind() != JvmMethodParameterKind.VALUE) { Type type = parameterSignature.getAsmType(); - callGenerator.putValueIfNeeded(type, StackValue.local(var, type)); + callGenerator.putValueIfNeeded(new JvmKotlinType(type, null), StackValue.local(var, type)); var += type.getSize(); } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java index 70dcf8fbc64..0df69645c44 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java @@ -1294,7 +1294,10 @@ public abstract class StackValue { coerce(topOfStackType, topOfStackKotlinType, lastParameterType, lastParameterKotlinType, v); - getCallGenerator().putValueIfNeeded(lastParameterType, StackValue.onStack(lastParameterType)); + getCallGenerator().putValueIfNeeded( + new JvmKotlinType(lastParameterType, lastParameterKotlinType), + StackValue.onStack(lastParameterType, lastParameterKotlinType) + ); //Convention setter couldn't have default parameters, just getter can have it at last positions //We should remove default parameters of getter from stack*/ @@ -1481,7 +1484,7 @@ public abstract class StackValue { putReceiver(v, false); } callGenerator.processAndPutHiddenParameters(true); - callGenerator.putValueIfNeeded(rightSide.type, rightSide); + callGenerator.putValueIfNeeded(new JvmKotlinType(rightSide.type, rightSide.kotlinType), rightSide); callGenerator.putHiddenParamsIntoLocals(); callGenerator.genCall(setter, resolvedCall, false, codegen); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt index cd6cf71199a..f4fda6eb4a8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/codegenUtil.kt @@ -270,7 +270,7 @@ private fun CallableDescriptor.isJvmStaticIn(predicate: (DeclarationDescriptor) fun Collection.filterOutDescriptorsWithSpecialNames() = filterNot { it.name.isSpecial } -class JvmKotlinType(val type: Type, val kotlinType: KotlinType?) +class JvmKotlinType(val type: Type, val kotlinType: KotlinType? = null) fun KotlinType.asmType(typeMapper: KotlinTypeMapper) = typeMapper.mapType(this) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt index e87e0d5847d..3ed985b917f 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-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.codegen.inline @@ -52,7 +41,6 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.expressions.DoubleColonLHS import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionLiteral import org.jetbrains.kotlin.types.expressions.LabelResolver import org.jetbrains.org.objectweb.asm.Opcodes @@ -326,20 +314,21 @@ abstract class InlineCodegen( } protected fun putArgumentOrCapturedToLocalVal( - type: Type, - stackValue: StackValue, - capturedParamIndex: Int, - parameterIndex: Int, - kind: ValueKind + jvmKotlinType: JvmKotlinType, + stackValue: StackValue, + capturedParamIndex: Int, + parameterIndex: Int, + kind: ValueKind ) { val isDefaultParameter = kind === ValueKind.DEFAULT_PARAMETER - if (!isDefaultParameter && shouldPutGeneralValue(type, stackValue)) { - stackValue.put(type, codegen.v) + val jvmType = jvmKotlinType.type + if (!isDefaultParameter && shouldPutGeneralValue(jvmType, stackValue)) { + stackValue.put(jvmType, jvmKotlinType.kotlinType, codegen.v) } - if (!asFunctionInline && Type.VOID_TYPE !== type) { + if (!asFunctionInline && Type.VOID_TYPE !== jvmType) { //TODO remap only inlinable closure => otherwise we could get a lot of problem - val couldBeRemapped = !shouldPutGeneralValue(type, stackValue) && kind !== ValueKind.DEFAULT_PARAMETER + val couldBeRemapped = !shouldPutGeneralValue(jvmType, stackValue) && kind !== ValueKind.DEFAULT_PARAMETER val remappedValue = if (couldBeRemapped) stackValue else null val info: ParameterInfo @@ -349,7 +338,7 @@ abstract class InlineCodegen( info.setRemapValue(remappedValue) } else { - info = invocationParamBuilder.addNextValueParameter(type, false, remappedValue, parameterIndex) + info = invocationParamBuilder.addNextValueParameter(jvmType, false, remappedValue, parameterIndex) } recordParameterValueInLocalVal( @@ -413,7 +402,7 @@ abstract class InlineCodegen( protected fun rememberCapturedForDefaultLambda(defaultLambda: DefaultLambda) { for ((paramIndex, captured) in defaultLambda.capturedVars.withIndex()) { putArgumentOrCapturedToLocalVal( - captured.type, + JvmKotlinType(captured.type), //HACK: actually parameter would be placed on stack in default function // also see ValueKind.DEFAULT_LAMBDA_CAPTURED_PARAMETER check StackValue.onStack(captured.type), @@ -736,7 +725,12 @@ class PsiInlineCodegen( } else { val value = codegen.gen(argumentExpression) - putValueIfNeeded(parameterType, value, ValueKind.GENERAL, valueParameterDescriptor.index) + putValueIfNeeded( + JvmKotlinType(parameterType, valueParameterDescriptor.original.type), + value, + ValueKind.GENERAL, + valueParameterDescriptor.index + ) } } @@ -753,7 +747,7 @@ class PsiInlineCodegen( } } - override fun putValueIfNeeded(parameterType: Type, value: StackValue, kind: ValueKind, parameterIndex: Int) { + override fun putValueIfNeeded(parameterType: JvmKotlinType, value: StackValue, kind: ValueKind, parameterIndex: Int) { if (processDefaultMaskOrMethodHandler(value, kind)) return assert(maskValues.isEmpty()) { "Additional default call arguments should be last ones, but " + value } @@ -762,7 +756,9 @@ class PsiInlineCodegen( } override fun putCapturedValueOnStack(stackValue: StackValue, valueType: Type, paramIndex: Int) { - putArgumentOrCapturedToLocalVal(stackValue.type, stackValue, paramIndex, paramIndex, ValueKind.CAPTURED) + putArgumentOrCapturedToLocalVal( + JvmKotlinType(stackValue.type, stackValue.kotlinType), stackValue, paramIndex, paramIndex, ValueKind.CAPTURED + ) } override fun reorderArgumentsIfNeeded(actualArgsWithDeclIndex: List, valueParameterTypes: List) = Unit diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenForDefaultBody.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenForDefaultBody.kt index 1f0e86694a1..d066b86515a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenForDefaultBody.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenForDefaultBody.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-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.codegen.inline @@ -92,7 +81,7 @@ class InlineCodegenForDefaultBody( throw UnsupportedOperationException("Shouldn't be called") } - override fun putValueIfNeeded(parameterType: Type, value: StackValue, kind: ValueKind, parameterIndex: Int) { + override fun putValueIfNeeded(parameterType: JvmKotlinType, value: StackValue, kind: ValueKind, parameterIndex: Int) { //original method would be inlined directly into default impl body without any inline magic //so we no need to load variables on stack to further method call } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt index 61dd79b1b82..c2ceec0f729 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt @@ -1,22 +1,12 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-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.backend.jvm.codegen import org.jetbrains.kotlin.codegen.Callable +import org.jetbrains.kotlin.codegen.JvmKotlinType import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.ValueKind import org.jetbrains.kotlin.codegen.inline.* @@ -62,17 +52,19 @@ class IrInlineCodegen( } override fun putValueIfNeeded(parameterType: Type, value: StackValue, kind: ValueKind, parameterIndex: Int, codegen: ExpressionCodegen) { - putArgumentOrCapturedToLocalVal(value.type, value, -1, parameterIndex, ValueKind.CAPTURED) + putArgumentOrCapturedToLocalVal(JvmKotlinType(value.type, value.kotlinType), value, -1, parameterIndex, ValueKind.CAPTURED) } fun putCapturedValueOnStack(argumentExpression: IrExpression, valueType: Type, capturedParamindex: Int) { val onStack = codegen.gen(argumentExpression, valueType, BlockInfo.create()) - putArgumentOrCapturedToLocalVal(onStack.type, onStack, capturedParamindex, capturedParamindex, ValueKind.CAPTURED) + putArgumentOrCapturedToLocalVal( + JvmKotlinType(onStack.type, onStack.kotlinType), onStack, capturedParamindex, capturedParamindex, ValueKind.CAPTURED + ) } fun putValueOnStack(argumentExpression: IrExpression, valueType: Type, paramIndex: Int) { val onStack = codegen.gen(argumentExpression, valueType, BlockInfo.create()) - putArgumentOrCapturedToLocalVal(onStack.type, onStack, -1, paramIndex, ValueKind.CAPTURED) + putArgumentOrCapturedToLocalVal(JvmKotlinType(onStack.type, onStack.kotlinType), onStack, -1, paramIndex, ValueKind.CAPTURED) } override fun beforeValueParametersStart() { diff --git a/compiler/testData/codegen/box/inlineClasses/checkBoxUnboxOfArgumentsOnInlinedFunctions.kt b/compiler/testData/codegen/box/inlineClasses/checkBoxUnboxOfArgumentsOnInlinedFunctions.kt new file mode 100644 index 00000000000..7ecb32798ce --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/checkBoxUnboxOfArgumentsOnInlinedFunctions.kt @@ -0,0 +1,43 @@ +// !LANGUAGE: +InlineClasses + +inline class Foo(val value: Int) + +fun id(x: T): T = x +inline fun inlinedId(x: T): T = x + +fun T.idExtension(): T = this +inline fun T.inlinedIdExtension(): T = this + +fun test(f: Foo) { + inlinedId(f) // box + inlinedId(f).idExtension() // box + + f.inlinedIdExtension() // box + + val a = inlinedId(f).idExtension() // box unbox + val b = inlinedId(f).inlinedIdExtension() // box unbox +} + +fun box(): String { + val f = Foo(11) + + id(inlinedId(f)) + inlinedId(id(f)) + + inlinedId(f) // box + inlinedId(f).idExtension() // box + + f.inlinedIdExtension() // box + + val a = inlinedId(f).idExtension() // box unbox + val b = inlinedId(f).inlinedIdExtension() // box unbox + + if (a.value != 11) return "fail" + if (b.value != 11) return "fail" + + if (inlinedId(Foo(10)).value != 10) return "fail" + if (Foo(20).inlinedIdExtension().value != 20) return "fail" + + return "OK" + +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/boxUnboxOnInlinedParameters.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/boxUnboxOnInlinedParameters.kt new file mode 100644 index 00000000000..36026107ab4 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/boxUnboxOnInlinedParameters.kt @@ -0,0 +1,25 @@ +// !LANGUAGE: +InlineClasses + +inline class Foo(val a: Int) + +fun id(x: T): T = x +inline fun inlinedId(x: T): T = x + +fun T.idExtension(): T = this +inline fun T.inlinedIdExtension(): T = this + +fun test(f: Foo) { + inlinedId(f) // box + inlinedId(f).idExtension() // box + + f.inlinedIdExtension() // box + + val a = inlinedId(f).idExtension() // box unbox + val b = inlinedId(f).inlinedIdExtension() // box unbox +} + +// 5 INVOKESTATIC Foo\$Erased.box +// 2 INVOKEVIRTUAL Foo.unbox + +// 0 valueOf +// 0 intValue \ No newline at end of file diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index f81892adb73..ec9125e4121 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -10407,6 +10407,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("checkBoxUnboxOfArgumentsOnInlinedFunctions.kt") + public void testCheckBoxUnboxOfArgumentsOnInlinedFunctions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkBoxUnboxOfArgumentsOnInlinedFunctions.kt"); + doTest(fileName); + } + @TestMetadata("checkBoxingAfterAssertionOperator.kt") public void testCheckBoxingAfterAssertionOperator() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkBoxingAfterAssertionOperator.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index a099dbbb794..ed679a7f113 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -10407,6 +10407,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("checkBoxUnboxOfArgumentsOnInlinedFunctions.kt") + public void testCheckBoxUnboxOfArgumentsOnInlinedFunctions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkBoxUnboxOfArgumentsOnInlinedFunctions.kt"); + doTest(fileName); + } + @TestMetadata("checkBoxingAfterAssertionOperator.kt") public void testCheckBoxingAfterAssertionOperator() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkBoxingAfterAssertionOperator.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index 105ad81c93c..15979155ea2 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -1938,6 +1938,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { doTest(fileName); } + @TestMetadata("boxUnboxOnInlinedParameters.kt") + public void testBoxUnboxOnInlinedParameters() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/boxUnboxOnInlinedParameters.kt"); + doTest(fileName); + } + @TestMetadata("callMemberMethodsInsideInlineClass.kt") public void testCallMemberMethodsInsideInlineClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/callMemberMethodsInsideInlineClass.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 009e7afef9f..b5741c4023f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -10407,6 +10407,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("checkBoxUnboxOfArgumentsOnInlinedFunctions.kt") + public void testCheckBoxUnboxOfArgumentsOnInlinedFunctions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkBoxUnboxOfArgumentsOnInlinedFunctions.kt"); + doTest(fileName); + } + @TestMetadata("checkBoxingAfterAssertionOperator.kt") public void testCheckBoxingAfterAssertionOperator() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkBoxingAfterAssertionOperator.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 0efeb1a81f8..4e4f2deb8f4 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -11391,6 +11391,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("checkBoxUnboxOfArgumentsOnInlinedFunctions.kt") + public void testCheckBoxUnboxOfArgumentsOnInlinedFunctions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkBoxUnboxOfArgumentsOnInlinedFunctions.kt"); + doTest(fileName); + } + @TestMetadata("checkBoxingAfterAssertionOperator.kt") public void testCheckBoxingAfterAssertionOperator() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/checkBoxingAfterAssertionOperator.kt");