[IR] Forbid to interpret expressions that involves unsigned numbers
We want to forbid expressions of type `Unsigned == Unsigned` or similar. Working with unsigned numbers we can only inline them on the call site or use in `String.plus` expression. This commit fixes problem in test `unsignedTypesInAnnotations`. Here interpreter thinks that expression `ONE_UINT != 1u` can be evaluated, but fails to do it. This fail prevent us from inlining `ONE_UINT` and on runtime we get error about missing getter. Earlier this property would have been inlined by `ConstLowering`, but we got rid of it.
This commit is contained in:
+19
-4
@@ -7,10 +7,14 @@ package org.jetbrains.kotlin.ir.interpreter.checker
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.ir.BuiltInOperatorNames
|
import org.jetbrains.kotlin.ir.BuiltInOperatorNames
|
||||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.interpreter.*
|
|
||||||
import org.jetbrains.kotlin.ir.interpreter.hasAnnotation
|
import org.jetbrains.kotlin.ir.interpreter.hasAnnotation
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.intrinsicConstEvaluationAnnotation
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.property
|
||||||
import org.jetbrains.kotlin.ir.types.isPrimitiveType
|
import org.jetbrains.kotlin.ir.types.isPrimitiveType
|
||||||
import org.jetbrains.kotlin.ir.types.isString
|
import org.jetbrains.kotlin.ir.types.isString
|
||||||
import org.jetbrains.kotlin.ir.types.isUnsignedType
|
import org.jetbrains.kotlin.ir.types.isUnsignedType
|
||||||
@@ -74,7 +78,15 @@ enum class EvaluationMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun canEvaluateBlock(block: IrBlock): Boolean = block.statements.size == 1
|
override fun canEvaluateBlock(block: IrBlock): Boolean = block.statements.size == 1
|
||||||
override fun canEvaluateExpression(expression: IrExpression): Boolean = expression is IrCall
|
override fun canEvaluateExpression(expression: IrExpression): Boolean {
|
||||||
|
if (expression !is IrCall) return false
|
||||||
|
|
||||||
|
if (expression.getAllArgumentsWithIr().any { it.second?.type?.isUnsigned() == true }) {
|
||||||
|
return expression.symbol.owner.fqNameWhenAvailable?.asString() == "kotlin.String.plus"
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
ONLY_INTRINSIC_CONST {
|
ONLY_INTRINSIC_CONST {
|
||||||
@@ -88,7 +100,10 @@ enum class EvaluationMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun canEvaluateBlock(block: IrBlock): Boolean = block.origin == IrStatementOrigin.WHEN || block.statements.size == 1
|
override fun canEvaluateBlock(block: IrBlock): Boolean = block.origin == IrStatementOrigin.WHEN || block.statements.size == 1
|
||||||
override fun canEvaluateExpression(expression: IrExpression): Boolean = expression is IrCall || expression is IrWhen
|
|
||||||
|
override fun canEvaluateExpression(expression: IrExpression): Boolean {
|
||||||
|
return ONLY_BUILTINS.canEvaluateExpression(expression) || expression is IrWhen
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
open fun canEvaluateFunction(function: IrFunction): Boolean = false
|
open fun canEvaluateFunction(function: IrFunction): Boolean = false
|
||||||
|
|||||||
Reference in New Issue
Block a user