Psi2IR: workaround for IR-based descriptors
Since KotlinTypes involving IR-Based descriptors are distinct from KotlinTypes involving original descriptors of the same declarations, subtyping check breaks in InsertImplicitCasts.
This commit is contained in:
+22
-3
@@ -28,15 +28,15 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||||
|
import org.jetbrains.kotlin.ir.descriptors.IrBasedDeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
@@ -355,7 +355,7 @@ internal class InsertImplicitCasts(
|
|||||||
valueType.hasEnhancedNullability() && !expectedType.acceptsNullValues() ->
|
valueType.hasEnhancedNullability() && !expectedType.acceptsNullValues() ->
|
||||||
implicitNonNull(valueType, expectedType)
|
implicitNonNull(valueType, expectedType)
|
||||||
|
|
||||||
KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType, expectedType.makeNullable()) ->
|
KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType.toNonIrBased(), expectedType.toNonIrBased().makeNullable()) ->
|
||||||
this
|
this
|
||||||
|
|
||||||
KotlinBuiltIns.isInt(valueType) && notNullableExpectedType.isBuiltInIntegerType() ->
|
KotlinBuiltIns.isInt(valueType) && notNullableExpectedType.isBuiltInIntegerType() ->
|
||||||
@@ -485,4 +485,23 @@ internal class InsertImplicitCasts(
|
|||||||
this
|
this
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KotlinType subtype checking fails when one of the types uses IR-based descriptors, the other one regular descriptors.
|
||||||
|
// This is a kludge to remove IR-based descriptors where possible.
|
||||||
|
private fun KotlinType.toNonIrBased(): KotlinType {
|
||||||
|
if (this !is SimpleType) return this
|
||||||
|
val newDescriptor = constructor.declarationDescriptor?.let {
|
||||||
|
if (it is IrBasedDeclarationDescriptor<*> && it.owner.symbol.hasDescriptor)
|
||||||
|
it.owner.symbol.descriptor as ClassifierDescriptor
|
||||||
|
else
|
||||||
|
it
|
||||||
|
} ?: return this
|
||||||
|
val newArguments = arguments.mapIndexed { index, it ->
|
||||||
|
if (it.isStarProjection)
|
||||||
|
StarProjectionImpl((newDescriptor as ClassDescriptor).typeConstructor.parameters[index])
|
||||||
|
else
|
||||||
|
TypeProjectionImpl(it.projectionKind, it.type.toNonIrBased())
|
||||||
|
}
|
||||||
|
return newDescriptor.defaultType.replace(newArguments = newArguments).makeNullableAsSpecified(isMarkedNullable)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -157,7 +157,7 @@ fun testSmartCastWithSuspendConversion(a: Any) {
|
|||||||
callee.invoke()
|
callee.invoke()
|
||||||
}
|
}
|
||||||
|
|
||||||
a::suspendConversion0
|
a /*as Function0<Unit> */::suspendConversion0
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ fun testSmartCastOnVarWithSuspendConversion(a: Any) {
|
|||||||
callee.invoke()
|
callee.invoke()
|
||||||
}
|
}
|
||||||
|
|
||||||
b::suspendConversion0
|
b /*as Function0<Unit> */::suspendConversion0
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -227,7 +227,8 @@ FILE fqName:<root> fileName:/suspendConversionOnArbitraryExpression.kt
|
|||||||
CALL 'public abstract fun invoke (): R of kotlin.Function0 [operator] declared in kotlin.Function0' type=kotlin.Unit origin=null
|
CALL 'public abstract fun invoke (): R of kotlin.Function0 [operator] declared in kotlin.Function0' type=kotlin.Unit origin=null
|
||||||
$this: GET_VAR 'callee: kotlin.Function0<kotlin.Unit> declared in <root>.testSmartCastWithSuspendConversion.suspendConversion0' type=kotlin.Function0<kotlin.Unit> origin=null
|
$this: GET_VAR 'callee: kotlin.Function0<kotlin.Unit> declared in <root>.testSmartCastWithSuspendConversion.suspendConversion0' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||||
FUNCTION_REFERENCE 'local final fun suspendConversion0 (): kotlin.Unit [suspend] declared in <root>.testSmartCastWithSuspendConversion' type=kotlin.coroutines.SuspendFunction0<kotlin.Unit> origin=SUSPEND_CONVERSION reflectionTarget=null
|
FUNCTION_REFERENCE 'local final fun suspendConversion0 (): kotlin.Unit [suspend] declared in <root>.testSmartCastWithSuspendConversion' type=kotlin.coroutines.SuspendFunction0<kotlin.Unit> origin=SUSPEND_CONVERSION reflectionTarget=null
|
||||||
$receiver: GET_VAR 'a: kotlin.Any declared in <root>.testSmartCastWithSuspendConversion' type=kotlin.Any origin=null
|
$receiver: TYPE_OP type=kotlin.Function0<kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function0<kotlin.Unit>
|
||||||
|
GET_VAR 'a: kotlin.Any declared in <root>.testSmartCastWithSuspendConversion' type=kotlin.Any origin=null
|
||||||
FUN name:testSmartCastOnVarWithSuspendConversion visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit
|
FUN name:testSmartCastOnVarWithSuspendConversion visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit
|
||||||
VALUE_PARAMETER name:a index:0 type:kotlin.Any
|
VALUE_PARAMETER name:a index:0 type:kotlin.Any
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
@@ -244,7 +245,8 @@ FILE fqName:<root> fileName:/suspendConversionOnArbitraryExpression.kt
|
|||||||
CALL 'public abstract fun invoke (): R of kotlin.Function0 [operator] declared in kotlin.Function0' type=kotlin.Unit origin=null
|
CALL 'public abstract fun invoke (): R of kotlin.Function0 [operator] declared in kotlin.Function0' type=kotlin.Unit origin=null
|
||||||
$this: GET_VAR 'callee: kotlin.Function0<kotlin.Unit> declared in <root>.testSmartCastOnVarWithSuspendConversion.suspendConversion0' type=kotlin.Function0<kotlin.Unit> origin=null
|
$this: GET_VAR 'callee: kotlin.Function0<kotlin.Unit> declared in <root>.testSmartCastOnVarWithSuspendConversion.suspendConversion0' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||||
FUNCTION_REFERENCE 'local final fun suspendConversion0 (): kotlin.Unit [suspend] declared in <root>.testSmartCastOnVarWithSuspendConversion' type=kotlin.coroutines.SuspendFunction0<kotlin.Unit> origin=SUSPEND_CONVERSION reflectionTarget=null
|
FUNCTION_REFERENCE 'local final fun suspendConversion0 (): kotlin.Unit [suspend] declared in <root>.testSmartCastOnVarWithSuspendConversion' type=kotlin.coroutines.SuspendFunction0<kotlin.Unit> origin=SUSPEND_CONVERSION reflectionTarget=null
|
||||||
$receiver: GET_VAR 'var b: kotlin.Any [var] declared in <root>.testSmartCastOnVarWithSuspendConversion' type=kotlin.Any origin=null
|
$receiver: TYPE_OP type=kotlin.Function0<kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function0<kotlin.Unit>
|
||||||
|
GET_VAR 'var b: kotlin.Any [var] declared in <root>.testSmartCastOnVarWithSuspendConversion' type=kotlin.Any origin=null
|
||||||
FUN name:testSmartCastVsSuspendConversion visibility:public modality:FINAL <> (a:kotlin.Function0<kotlin.Unit>) returnType:kotlin.Unit
|
FUN name:testSmartCastVsSuspendConversion visibility:public modality:FINAL <> (a:kotlin.Function0<kotlin.Unit>) returnType:kotlin.Unit
|
||||||
VALUE_PARAMETER name:a index:0 type:kotlin.Function0<kotlin.Unit>
|
VALUE_PARAMETER name:a index:0 type:kotlin.Function0<kotlin.Unit>
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
|
|||||||
Reference in New Issue
Block a user