Fix for-in iterator over list of boxed inline class values
#KT-25325 Fixed
This commit is contained in:
+4
-1
@@ -44,6 +44,7 @@ abstract class AbstractForLoopGenerator(
|
|||||||
|
|
||||||
protected var loopParameterVar: Int = -1
|
protected var loopParameterVar: Int = -1
|
||||||
protected lateinit var loopParameterType: Type
|
protected lateinit var loopParameterType: Type
|
||||||
|
protected lateinit var loopParameterKotlinType: KotlinType
|
||||||
|
|
||||||
override fun beforeLoop() {
|
override fun beforeLoop() {
|
||||||
val loopParameter = forExpression.loopParameter ?: return
|
val loopParameter = forExpression.loopParameter ?: return
|
||||||
@@ -51,11 +52,13 @@ abstract class AbstractForLoopGenerator(
|
|||||||
if (multiParameter != null) {
|
if (multiParameter != null) {
|
||||||
// E tmp<e> = tmp<iterator>.next()
|
// E tmp<e> = tmp<iterator>.next()
|
||||||
loopParameterType = asmElementType
|
loopParameterType = asmElementType
|
||||||
|
loopParameterKotlinType = elementType
|
||||||
loopParameterVar = createLoopTempVariable(asmElementType)
|
loopParameterVar = createLoopTempVariable(asmElementType)
|
||||||
} else {
|
} else {
|
||||||
// E e = tmp<iterator>.next()
|
// E e = tmp<iterator>.next()
|
||||||
val parameterDescriptor = bindingContext.get(BindingContext.VALUE_PARAMETER, loopParameter)
|
val parameterDescriptor = bindingContext.get(BindingContext.VALUE_PARAMETER, loopParameter)
|
||||||
loopParameterType = codegen.asmType(parameterDescriptor!!.type)
|
loopParameterKotlinType = parameterDescriptor!!.type
|
||||||
|
loopParameterType = codegen.asmType(loopParameterKotlinType)
|
||||||
loopParameterVar = codegen.myFrameMap.enter(parameterDescriptor, loopParameterType)
|
loopParameterVar = codegen.myFrameMap.enter(parameterDescriptor, loopParameterType)
|
||||||
scheduleLeaveVariable(Runnable {
|
scheduleLeaveVariable(Runnable {
|
||||||
codegen.myFrameMap.leave(parameterDescriptor)
|
codegen.myFrameMap.leave(parameterDescriptor)
|
||||||
|
|||||||
+9
-5
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.resolve.BindingContext.*
|
|||||||
import org.jetbrains.kotlin.resolve.BindingContextUtils.getNotNull
|
import org.jetbrains.kotlin.resolve.BindingContextUtils.getNotNull
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.org.objectweb.asm.Label
|
import org.jetbrains.org.objectweb.asm.Label
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
|
||||||
@@ -33,6 +34,7 @@ class IteratorForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForE
|
|||||||
private var iteratorVarIndex: Int = 0
|
private var iteratorVarIndex: Int = 0
|
||||||
private val iteratorCall: ResolvedCall<FunctionDescriptor>
|
private val iteratorCall: ResolvedCall<FunctionDescriptor>
|
||||||
private val nextCall: ResolvedCall<FunctionDescriptor>
|
private val nextCall: ResolvedCall<FunctionDescriptor>
|
||||||
|
private val iteratorType: KotlinType
|
||||||
private val asmTypeForIterator: Type
|
private val asmTypeForIterator: Type
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -43,7 +45,7 @@ class IteratorForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForE
|
|||||||
"No .iterator() function " + PsiDiagnosticUtils.atLocation(loopRange)
|
"No .iterator() function " + PsiDiagnosticUtils.atLocation(loopRange)
|
||||||
)
|
)
|
||||||
|
|
||||||
val iteratorType = iteratorCall.resultingDescriptor.returnType!!
|
this.iteratorType = iteratorCall.resultingDescriptor.returnType!!
|
||||||
this.asmTypeForIterator = codegen.asmType(iteratorType)
|
this.asmTypeForIterator = codegen.asmType(iteratorType)
|
||||||
|
|
||||||
this.nextCall = getNotNull(
|
this.nextCall = getNotNull(
|
||||||
@@ -58,7 +60,9 @@ class IteratorForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForE
|
|||||||
|
|
||||||
// Iterator<E> tmp<iterator> = c.iterator()
|
// Iterator<E> tmp<iterator> = c.iterator()
|
||||||
iteratorVarIndex = createLoopTempVariable(asmTypeForIterator)
|
iteratorVarIndex = createLoopTempVariable(asmTypeForIterator)
|
||||||
StackValue.local(iteratorVarIndex, asmTypeForIterator).store(codegen.invokeFunction(iteratorCall, StackValue.none()), v)
|
StackValue
|
||||||
|
.local(iteratorVarIndex, asmTypeForIterator, iteratorType)
|
||||||
|
.store(codegen.invokeFunction(iteratorCall, StackValue.none()), v)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun checkEmptyLoop(loopExit: Label) {}
|
override fun checkEmptyLoop(loopExit: Label) {}
|
||||||
@@ -73,7 +77,7 @@ class IteratorForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForE
|
|||||||
"No hasNext() function " + PsiDiagnosticUtils.atLocation(loopRange)
|
"No hasNext() function " + PsiDiagnosticUtils.atLocation(loopRange)
|
||||||
)
|
)
|
||||||
val fakeCall = codegen.makeFakeCall(TransientReceiver(iteratorCall.resultingDescriptor.returnType!!))
|
val fakeCall = codegen.makeFakeCall(TransientReceiver(iteratorCall.resultingDescriptor.returnType!!))
|
||||||
val result = codegen.invokeFunction(fakeCall, hasNextCall, StackValue.local(iteratorVarIndex, asmTypeForIterator))
|
val result = codegen.invokeFunction(fakeCall, hasNextCall, StackValue.local(iteratorVarIndex, asmTypeForIterator, iteratorType))
|
||||||
result.put(Type.BOOLEAN_TYPE, v)
|
result.put(Type.BOOLEAN_TYPE, v)
|
||||||
|
|
||||||
v.ifeq(loopExit)
|
v.ifeq(loopExit)
|
||||||
@@ -81,9 +85,9 @@ class IteratorForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForE
|
|||||||
|
|
||||||
override fun assignToLoopParameter() {
|
override fun assignToLoopParameter() {
|
||||||
val fakeCall = codegen.makeFakeCall(TransientReceiver(iteratorCall.resultingDescriptor.returnType!!))
|
val fakeCall = codegen.makeFakeCall(TransientReceiver(iteratorCall.resultingDescriptor.returnType!!))
|
||||||
val value = codegen.invokeFunction(fakeCall, nextCall, StackValue.local(iteratorVarIndex, asmTypeForIterator))
|
val value = codegen.invokeFunction(fakeCall, nextCall, StackValue.local(iteratorVarIndex, asmTypeForIterator, iteratorType))
|
||||||
|
|
||||||
StackValue.local(loopParameterVar, loopParameterType).store(value, v)
|
StackValue.local(loopParameterVar, loopParameterType, loopParameterKotlinType).store(value, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun checkPostConditionAndIncrement(loopExit: Label) {}
|
override fun checkPostConditionAndIncrement(loopExit: Label) {}
|
||||||
|
|||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
// !LANGUAGE: +InlineClasses
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// IGNORE_BACKEND: JVM_IR
|
||||||
|
// IGNORE_BACKEND: JS_IR
|
||||||
|
|
||||||
|
inline class Foo(val arg: String)
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val ls = listOf(Foo("abc"), Foo("def"))
|
||||||
|
var res = ""
|
||||||
|
for (el in ls) {
|
||||||
|
res += el.arg
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (res != "abcdef") "Fail" else "OK"
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
// WITH_UNSIGNED
|
||||||
|
// IGNORE_BACKEND: JVM_IR
|
||||||
|
// IGNORE_BACKEND: JS_IR
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var sum = 0u
|
||||||
|
val ls = listOf(1u, 2u, 3u)
|
||||||
|
for (el in ls) {
|
||||||
|
sum += el
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (sum != 6u) "Fail" else "OK"
|
||||||
|
}
|
||||||
Generated
+10
@@ -11131,6 +11131,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/iterateOverArrayOfInlineClassValues.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/iterateOverArrayOfInlineClassValues.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("iterateOverListOfInlineClassValues.kt")
|
||||||
|
public void testIterateOverListOfInlineClassValues() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/iterateOverListOfInlineClassValues.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
||||||
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
||||||
@@ -21252,6 +21257,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverArrayOfUnsignedValues.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverArrayOfUnsignedValues.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("iterateOverListOfBoxedUnsignedValues.kt")
|
||||||
|
public void testIterateOverListOfBoxedUnsignedValues() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverListOfBoxedUnsignedValues.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("unsignedLiteralsWithSignedOverflow.kt")
|
@TestMetadata("unsignedLiteralsWithSignedOverflow.kt")
|
||||||
public void testUnsignedLiteralsWithSignedOverflow() throws Exception {
|
public void testUnsignedLiteralsWithSignedOverflow() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLiteralsWithSignedOverflow.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLiteralsWithSignedOverflow.kt");
|
||||||
|
|||||||
+10
@@ -11131,6 +11131,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/iterateOverArrayOfInlineClassValues.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/iterateOverArrayOfInlineClassValues.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("iterateOverListOfInlineClassValues.kt")
|
||||||
|
public void testIterateOverListOfInlineClassValues() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/iterateOverListOfInlineClassValues.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
||||||
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
||||||
@@ -21252,6 +21257,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverArrayOfUnsignedValues.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverArrayOfUnsignedValues.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("iterateOverListOfBoxedUnsignedValues.kt")
|
||||||
|
public void testIterateOverListOfBoxedUnsignedValues() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverListOfBoxedUnsignedValues.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("unsignedLiteralsWithSignedOverflow.kt")
|
@TestMetadata("unsignedLiteralsWithSignedOverflow.kt")
|
||||||
public void testUnsignedLiteralsWithSignedOverflow() throws Exception {
|
public void testUnsignedLiteralsWithSignedOverflow() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLiteralsWithSignedOverflow.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLiteralsWithSignedOverflow.kt");
|
||||||
|
|||||||
+10
@@ -11131,6 +11131,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/iterateOverArrayOfInlineClassValues.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/iterateOverArrayOfInlineClassValues.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("iterateOverListOfInlineClassValues.kt")
|
||||||
|
public void testIterateOverListOfInlineClassValues() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/iterateOverListOfInlineClassValues.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
||||||
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
||||||
@@ -21252,6 +21257,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverArrayOfUnsignedValues.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverArrayOfUnsignedValues.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("iterateOverListOfBoxedUnsignedValues.kt")
|
||||||
|
public void testIterateOverListOfBoxedUnsignedValues() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverListOfBoxedUnsignedValues.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("unsignedLiteralsWithSignedOverflow.kt")
|
@TestMetadata("unsignedLiteralsWithSignedOverflow.kt")
|
||||||
public void testUnsignedLiteralsWithSignedOverflow() throws Exception {
|
public void testUnsignedLiteralsWithSignedOverflow() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLiteralsWithSignedOverflow.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLiteralsWithSignedOverflow.kt");
|
||||||
|
|||||||
+10
@@ -9781,6 +9781,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/iterateOverArrayOfInlineClassValues.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/iterateOverArrayOfInlineClassValues.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("iterateOverListOfInlineClassValues.kt")
|
||||||
|
public void testIterateOverListOfInlineClassValues() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/iterateOverListOfInlineClassValues.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
||||||
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
||||||
@@ -19262,6 +19267,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverArrayOfUnsignedValues.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverArrayOfUnsignedValues.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("iterateOverListOfBoxedUnsignedValues.kt")
|
||||||
|
public void testIterateOverListOfBoxedUnsignedValues() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverListOfBoxedUnsignedValues.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("varargsOfUnsignedTypes.kt")
|
@TestMetadata("varargsOfUnsignedTypes.kt")
|
||||||
public void testVarargsOfUnsignedTypes() throws Exception {
|
public void testVarargsOfUnsignedTypes() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/unsignedTypes/varargsOfUnsignedTypes.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/varargsOfUnsignedTypes.kt");
|
||||||
|
|||||||
+10
@@ -10776,6 +10776,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/iterateOverArrayOfInlineClassValues.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/iterateOverArrayOfInlineClassValues.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("iterateOverListOfInlineClassValues.kt")
|
||||||
|
public void testIterateOverListOfInlineClassValues() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/iterateOverListOfInlineClassValues.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
||||||
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
||||||
@@ -20257,6 +20262,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverArrayOfUnsignedValues.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverArrayOfUnsignedValues.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("iterateOverListOfBoxedUnsignedValues.kt")
|
||||||
|
public void testIterateOverListOfBoxedUnsignedValues() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/unsignedTypes/iterateOverListOfBoxedUnsignedValues.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("varargsOfUnsignedTypes.kt")
|
@TestMetadata("varargsOfUnsignedTypes.kt")
|
||||||
public void testVarargsOfUnsignedTypes() throws Exception {
|
public void testVarargsOfUnsignedTypes() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/unsignedTypes/varargsOfUnsignedTypes.kt");
|
runTest("compiler/testData/codegen/box/unsignedTypes/varargsOfUnsignedTypes.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user