FIR: more accurate handling of dispatch receiver values
This commit fixes resolve priorities (see changed test data), e.g. top-levels now have less priority than implicit receiver members
This commit is contained in:
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.resultType
|
||||
import org.jetbrains.kotlin.fir.resolve.typeForQualifier
|
||||
import org.jetbrains.kotlin.fir.resolve.typeFromCallee
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
||||
@@ -36,8 +37,8 @@ import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
||||
|
||||
class FirCallResolver(
|
||||
private val transformer: FirBodyResolveTransformer,
|
||||
private val scopes: List<FirScope>,
|
||||
private val localScopes: List<FirScope>,
|
||||
private val topLevelScopes: List<FirScope>,
|
||||
private val localScopes: List<FirLocalScope>,
|
||||
private val implicitReceiverStack: List<ImplicitReceiverValue>,
|
||||
private val qualifiedResolver: FirQualifiedNameResolver
|
||||
) : BodyResolveComponents by transformer {
|
||||
@@ -64,9 +65,11 @@ class FirCallResolver(
|
||||
file,
|
||||
transformer.container
|
||||
) { it.resultType }
|
||||
val resolver = CallResolver(returnTypeCalculator, inferenceComponents, resolutionStageRunner)
|
||||
resolver.callInfo = info
|
||||
resolver.scopes = (scopes + localScopes).asReversed()
|
||||
val resolver = CallResolver(
|
||||
returnTypeCalculator, inferenceComponents, resolutionStageRunner,
|
||||
topLevelScopes = topLevelScopes.asReversed(),
|
||||
localScopes = localScopes.asReversed()
|
||||
)
|
||||
|
||||
val consumer = createFunctionConsumer(session, name, info, inferenceComponents, resolver.collector, resolver)
|
||||
val result = resolver.runTowerResolver(consumer, implicitReceiverStack.asReversed())
|
||||
@@ -154,9 +157,11 @@ class FirCallResolver(
|
||||
file,
|
||||
transformer.container
|
||||
) { it.resultType }
|
||||
val resolver = CallResolver(returnTypeCalculator, inferenceComponents, resolutionStageRunner)
|
||||
resolver.callInfo = info
|
||||
resolver.scopes = (scopes + localScopes).asReversed()
|
||||
val resolver = CallResolver(
|
||||
returnTypeCalculator, inferenceComponents, resolutionStageRunner,
|
||||
topLevelScopes = topLevelScopes.asReversed(),
|
||||
localScopes = localScopes.asReversed()
|
||||
)
|
||||
|
||||
val consumer = createVariableAndObjectConsumer(
|
||||
session,
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
||||
|
||||
enum class TowerDataKind {
|
||||
EMPTY,
|
||||
@@ -17,10 +18,10 @@ enum class TowerDataKind {
|
||||
class CallResolver(
|
||||
val typeCalculator: ReturnTypeCalculator,
|
||||
val components: InferenceComponents,
|
||||
val resolutionStageRunner: ResolutionStageRunner
|
||||
val resolutionStageRunner: ResolutionStageRunner,
|
||||
val topLevelScopes: List<FirScope>,
|
||||
val localScopes: List<FirLocalScope>
|
||||
) {
|
||||
var callInfo: CallInfo? = null
|
||||
var scopes: List<FirScope>? = null
|
||||
|
||||
val session: FirSession get() = components.session
|
||||
|
||||
@@ -44,10 +45,39 @@ class CallResolver(
|
||||
group++
|
||||
)
|
||||
|
||||
for (scope in scopes!!) {
|
||||
for (scope in localScopes) {
|
||||
towerDataConsumer.consume(
|
||||
TowerDataKind.TOWER_LEVEL,
|
||||
ScopeTowerLevel(session, scope, implicitReceiverValue),
|
||||
ScopeTowerLevel(session, scope, implicitExtensionReceiver = implicitReceiverValue),
|
||||
group++
|
||||
)
|
||||
}
|
||||
|
||||
for (implicitDispatchReceiverValue in implicitReceiverValues) {
|
||||
val implicitScope = implicitDispatchReceiverValue.implicitScope
|
||||
if (implicitScope != null) {
|
||||
towerDataConsumer.consume(
|
||||
TowerDataKind.TOWER_LEVEL,
|
||||
ScopeTowerLevel(session, implicitScope, implicitExtensionReceiver = implicitReceiverValue),
|
||||
group++
|
||||
)
|
||||
}
|
||||
if (implicitDispatchReceiverValue is ImplicitDispatchReceiverValue) {
|
||||
val implicitCompanionScope = implicitDispatchReceiverValue.implicitCompanionScope
|
||||
if (implicitCompanionScope != null) {
|
||||
towerDataConsumer.consume(
|
||||
TowerDataKind.TOWER_LEVEL,
|
||||
ScopeTowerLevel(session, implicitCompanionScope, implicitExtensionReceiver = implicitReceiverValue),
|
||||
group++
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (scope in topLevelScopes) {
|
||||
towerDataConsumer.consume(
|
||||
TowerDataKind.TOWER_LEVEL,
|
||||
ScopeTowerLevel(session, scope, implicitExtensionReceiver = implicitReceiverValue),
|
||||
group++
|
||||
)
|
||||
}
|
||||
@@ -64,15 +94,27 @@ class CallResolver(
|
||||
towerDataConsumer = consumer
|
||||
|
||||
var group = 0
|
||||
// Member of explicit receiver' type
|
||||
towerDataConsumer.consume(TowerDataKind.EMPTY, TowerScopeLevel.Empty, group++)
|
||||
|
||||
for (scope in scopes!!) {
|
||||
// Member of local scope
|
||||
for (scope in localScopes) {
|
||||
towerDataConsumer.consume(TowerDataKind.TOWER_LEVEL, ScopeTowerLevel(session, scope), group++)
|
||||
}
|
||||
|
||||
var blockDispatchReceivers = false
|
||||
|
||||
// Member of implicit receiver' type
|
||||
for (implicitReceiverValue in implicitReceiverValues) {
|
||||
val implicitScope = implicitReceiverValue.implicitScope
|
||||
if (implicitScope != null) {
|
||||
towerDataConsumer.consume(TowerDataKind.TOWER_LEVEL, ScopeTowerLevel(session, implicitScope), group++)
|
||||
}
|
||||
if (implicitReceiverValue is ImplicitDispatchReceiverValue) {
|
||||
val implicitCompanionScope = implicitReceiverValue.implicitCompanionScope
|
||||
if (implicitCompanionScope != null) {
|
||||
towerDataConsumer.consume(TowerDataKind.TOWER_LEVEL, ScopeTowerLevel(session, implicitCompanionScope), group++)
|
||||
}
|
||||
if (blockDispatchReceivers) {
|
||||
continue
|
||||
}
|
||||
@@ -83,6 +125,11 @@ class CallResolver(
|
||||
group = processImplicitReceiver(towerDataConsumer, implicitReceiverValue, collector, group)
|
||||
}
|
||||
|
||||
// Member of top-level scope
|
||||
for (scope in topLevelScopes) {
|
||||
towerDataConsumer.consume(TowerDataKind.TOWER_LEVEL, ScopeTowerLevel(session, scope), group++)
|
||||
}
|
||||
|
||||
return collector
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.classId
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.renderWithType
|
||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.scope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
|
||||
@@ -32,14 +38,28 @@ class ExpressionReceiverValue(
|
||||
?: ConeKotlinErrorType("No type calculated for: ${explicitReceiverExpression.renderWithType()}") // TODO: assert here
|
||||
}
|
||||
|
||||
interface ImplicitReceiverValue : ReceiverValue {
|
||||
abstract class ImplicitReceiverValue(
|
||||
final override val type: ConeKotlinType,
|
||||
useSiteSession: FirSession,
|
||||
scopeSession: ScopeSession
|
||||
) : ReceiverValue {
|
||||
val implicitScope: FirScope? = type.scope(useSiteSession, scopeSession)
|
||||
}
|
||||
|
||||
class ImplicitDispatchReceiverValue(
|
||||
val boundSymbol: FirClassSymbol,
|
||||
override val type: ConeKotlinType
|
||||
) : ImplicitReceiverValue
|
||||
type: ConeKotlinType,
|
||||
symbolProvider: FirSymbolProvider,
|
||||
useSiteSession: FirSession,
|
||||
scopeSession: ScopeSession
|
||||
) : ImplicitReceiverValue(type, useSiteSession, scopeSession) {
|
||||
val implicitCompanionScope: FirScope? = boundSymbol.fir.companionObject?.let { companionObject ->
|
||||
symbolProvider.getClassUseSiteMemberScope(companionObject.classId, useSiteSession, scopeSession)
|
||||
}
|
||||
}
|
||||
|
||||
class ImplicitExtensionReceiverValue(
|
||||
override val type: ConeKotlinType
|
||||
) : ImplicitReceiverValue
|
||||
type: ConeKotlinType,
|
||||
useSiteSession: FirSession,
|
||||
scopeSession: ScopeSession
|
||||
) : ImplicitReceiverValue(type, useSiteSession, scopeSession)
|
||||
|
||||
@@ -69,6 +69,7 @@ abstract class SessionBasedTowerLevel(val session: FirSession) : TowerScopeLevel
|
||||
protected fun AbstractFirBasedSymbol<*>.dispatchReceiverValue(): ClassDispatchReceiverValue? {
|
||||
return when (this) {
|
||||
is FirNamedFunctionSymbol -> fir.dispatchReceiverValue(session)
|
||||
is FirPropertySymbol -> fir.dispatchReceiverValue(session)
|
||||
is FirClassSymbol -> ClassDispatchReceiverValue(fir.symbol)
|
||||
else -> null
|
||||
}
|
||||
|
||||
+42
-49
@@ -53,7 +53,6 @@ open class FirBodyResolveTransformer(
|
||||
private val booleanType = FirImplicitBooleanTypeRef(null)
|
||||
|
||||
final override val symbolProvider = session.service<FirSymbolProvider>()
|
||||
val scopes = mutableListOf<FirScope>()
|
||||
|
||||
private var packageFqName = FqName.ROOT
|
||||
final override lateinit var file: FirFile
|
||||
@@ -67,6 +66,7 @@ open class FirBodyResolveTransformer(
|
||||
}
|
||||
|
||||
private val localScopes = mutableListOf<FirLocalScope>()
|
||||
private val topLevelScopes = mutableListOf<FirScope>()
|
||||
private val implicitReceiverStack = mutableListOf<ImplicitReceiverValue>()
|
||||
final override val inferenceComponents = inferenceComponents(session, returnTypeCalculator, scopeSession)
|
||||
|
||||
@@ -77,7 +77,7 @@ open class FirBodyResolveTransformer(
|
||||
final override val resolutionStageRunner: ResolutionStageRunner = ResolutionStageRunner(inferenceComponents)
|
||||
private val callResolver: FirCallResolver = FirCallResolver(
|
||||
this,
|
||||
scopes,
|
||||
topLevelScopes,
|
||||
localScopes,
|
||||
implicitReceiverStack,
|
||||
qualifiedResolver
|
||||
@@ -94,9 +94,9 @@ open class FirBodyResolveTransformer(
|
||||
override fun transformFile(file: FirFile, data: Any?): CompositeTransformResult<FirFile> {
|
||||
packageFqName = file.packageFqName
|
||||
this.file = file
|
||||
return withScopeCleanup(scopes) {
|
||||
scopes.addImportingScopes(file, session)
|
||||
scopes += FirTopLevelDeclaredMemberScope(file, session)
|
||||
return withScopeCleanup(topLevelScopes) {
|
||||
topLevelScopes.addImportingScopes(file, session)
|
||||
topLevelScopes += FirTopLevelDeclaredMemberScope(file, session)
|
||||
super.transformFile(file, data)
|
||||
}
|
||||
}
|
||||
@@ -139,27 +139,20 @@ open class FirBodyResolveTransformer(
|
||||
}
|
||||
|
||||
override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||
return withScopeCleanup(scopes) {
|
||||
val oldConstructorScope = primaryConstructorParametersScope
|
||||
primaryConstructorParametersScope = null
|
||||
val type = regularClass.defaultType()
|
||||
scopes.addIfNotNull(type.scope(session, scopeSession))
|
||||
val companionObject = regularClass.companionObject
|
||||
if (companionObject != null) {
|
||||
scopes.addIfNotNull(symbolProvider.getClassUseSiteMemberScope(companionObject.classId, session, scopeSession))
|
||||
}
|
||||
val result = withLabelAndReceiverType(regularClass.name, regularClass, type) {
|
||||
val constructor = regularClass.declarations.firstOrNull() as? FirConstructor
|
||||
if (constructor?.isPrimary == true) {
|
||||
primaryConstructorParametersScope = FirLocalScope().apply {
|
||||
constructor.valueParameters.forEach { this.storeDeclaration(it) }
|
||||
}
|
||||
val oldConstructorScope = primaryConstructorParametersScope
|
||||
primaryConstructorParametersScope = null
|
||||
val type = regularClass.defaultType()
|
||||
val result = withLabelAndReceiverType(regularClass.name, regularClass, type) {
|
||||
val constructor = regularClass.declarations.firstOrNull() as? FirConstructor
|
||||
if (constructor?.isPrimary == true) {
|
||||
primaryConstructorParametersScope = FirLocalScope().apply {
|
||||
constructor.valueParameters.forEach { this.storeDeclaration(it) }
|
||||
}
|
||||
super.transformRegularClass(regularClass, data)
|
||||
}
|
||||
primaryConstructorParametersScope = oldConstructorScope
|
||||
result
|
||||
super.transformRegularClass(regularClass, data)
|
||||
}
|
||||
primaryConstructorParametersScope = oldConstructorScope
|
||||
return result
|
||||
}
|
||||
|
||||
override fun transformUncheckedNotNullCast(
|
||||
@@ -359,17 +352,15 @@ open class FirBodyResolveTransformer(
|
||||
): FirAnonymousFunction {
|
||||
val receiverTypeRef = anonymousFunction.receiverTypeRef
|
||||
fun transform(): FirAnonymousFunction {
|
||||
return withScopeCleanup(scopes) {
|
||||
scopes.addIfNotNull(receiverTypeRef?.coneTypeSafe<ConeKotlinType>()?.scope(session, scopeSession))
|
||||
val expectedReturnType = lambdaResolution.expectedReturnTypeRef ?: anonymousFunction.returnTypeRef.takeUnless { it is FirImplicitTypeRef }
|
||||
val expectedReturnType =
|
||||
lambdaResolution.expectedReturnTypeRef ?: anonymousFunction.returnTypeRef.takeUnless { it is FirImplicitTypeRef }
|
||||
val result = super.transformAnonymousFunction(anonymousFunction, expectedReturnType).single as FirAnonymousFunction
|
||||
val body = result.body
|
||||
if (result.returnTypeRef is FirImplicitTypeRef && body != null) {
|
||||
result.transformReturnTypeRef(this, body.resultType)
|
||||
result
|
||||
} else {
|
||||
result
|
||||
}
|
||||
val body = result.body
|
||||
return if (result.returnTypeRef is FirImplicitTypeRef && body != null) {
|
||||
result.transformReturnTypeRef(this, body.resultType)
|
||||
result
|
||||
} else {
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -563,18 +554,14 @@ open class FirBodyResolveTransformer(
|
||||
if (function is FirNamedFunction) {
|
||||
localScopes.lastOrNull()?.storeDeclaration(function)
|
||||
}
|
||||
return withScopeCleanup(scopes) {
|
||||
scopes.addIfNotNull(receiverTypeRef?.coneTypeSafe<ConeKotlinType>()?.scope(session, scopeSession))
|
||||
|
||||
val result = transformFunction(function, returnTypeRef).single as FirFunction<*>
|
||||
val body = result.body
|
||||
if (result is FirTypedDeclaration && result.returnTypeRef is FirImplicitTypeRef && body != null) {
|
||||
result.transformReturnTypeRef(this, body.resultType)
|
||||
result
|
||||
} else {
|
||||
result
|
||||
}.compose()
|
||||
}
|
||||
val result = transformFunction(function, returnTypeRef).single as FirFunction<*>
|
||||
val body = result.body
|
||||
return if (result is FirTypedDeclaration && result.returnTypeRef is FirImplicitTypeRef && body != null) {
|
||||
result.transformReturnTypeRef(this, body.resultType)
|
||||
result
|
||||
} else {
|
||||
result
|
||||
}.compose()
|
||||
}
|
||||
|
||||
override fun transformNamedFunction(namedFunction: FirNamedFunction, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||
@@ -783,10 +770,16 @@ open class FirBodyResolveTransformer(
|
||||
|
||||
private inline fun <T> withLabelAndReceiverType(labelName: Name, owner: FirElement, type: ConeKotlinType, block: () -> T): T {
|
||||
labels.put(labelName, type)
|
||||
when (owner) {
|
||||
is FirRegularClass -> implicitReceiverStack += ImplicitDispatchReceiverValue(owner.symbol, type)
|
||||
is FirFunction<*> -> implicitReceiverStack += ImplicitExtensionReceiverValue(type)
|
||||
else -> throw IllegalArgumentException("Incorrect label & receiver owner: ${owner.javaClass}")
|
||||
implicitReceiverStack += when (owner) {
|
||||
is FirRegularClass -> {
|
||||
ImplicitDispatchReceiverValue(owner.symbol, type, symbolProvider, session, scopeSession)
|
||||
}
|
||||
is FirFunction<*> -> {
|
||||
ImplicitExtensionReceiverValue(type, session, scopeSession)
|
||||
}
|
||||
else -> {
|
||||
throw IllegalArgumentException("Incorrect label & receiver owner: ${owner.javaClass}")
|
||||
}
|
||||
}
|
||||
val result = block()
|
||||
implicitReceiverStack.removeAt(implicitReceiverStack.size - 1)
|
||||
|
||||
@@ -37,11 +37,11 @@ FILE: access.kt
|
||||
}
|
||||
|
||||
public final fun R|Foo|.check(): <ERROR TYPE REF: Inapplicable(INAPPLICABLE): [kotlin/Int.plus, kotlin/Int.plus, kotlin/Int.plus, kotlin/Int.plus, kotlin/Int.plus, kotlin/Int.plus]> {
|
||||
^check R|/Foo.abc|().<Inapplicable(INAPPLICABLE): [kotlin/Int.plus, kotlin/Int.plus, kotlin/Int.plus, kotlin/Int.plus, kotlin/Int.plus, kotlin/Int.plus]>#(R|/bar|())
|
||||
^check R|/Foo.abc|().<Inapplicable(INAPPLICABLE): [kotlin/Int.plus, kotlin/Int.plus, kotlin/Int.plus, kotlin/Int.plus, kotlin/Int.plus, kotlin/Int.plus]>#(R|/Bar.bar|())
|
||||
}
|
||||
|
||||
public final fun R|Foo|.check2(): R|kotlin/String| {
|
||||
^check2 String().R|kotlin/String.plus|(R|/bar|())
|
||||
^check2 String().R|kotlin/String.plus|(R|/Bar.bar|())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+12
@@ -10,4 +10,16 @@ class Foo {
|
||||
operator fun invoke(): Foo { return this }
|
||||
|
||||
fun bar() = x() // Should resolve to invoke
|
||||
}
|
||||
|
||||
class Bar {
|
||||
fun x() {}
|
||||
|
||||
val x: Bar = Bar()
|
||||
|
||||
operator fun invoke(): Bar { return this }
|
||||
|
||||
fun baz() {
|
||||
x() // Should resolve to fun x()
|
||||
}
|
||||
}
|
||||
+20
@@ -18,3 +18,23 @@ FILE: explicitReceiver.kt
|
||||
}
|
||||
|
||||
}
|
||||
public final class Bar : R|kotlin/Any| {
|
||||
public constructor(): R|Bar| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final fun x(): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
public final val x: R|Bar| = R|/Bar.Bar|()
|
||||
public get(): R|Bar|
|
||||
|
||||
public final operator fun invoke(): R|Bar| {
|
||||
^invoke this#
|
||||
}
|
||||
|
||||
public final fun baz(): R|kotlin/Unit| {
|
||||
R|/Bar.x|()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ FILE: extension.kt
|
||||
public final val x: R|kotlin/Int| = Int(0)
|
||||
public get(): R|kotlin/Int|
|
||||
|
||||
public final fun foo(): R|kotlin/Unit| {
|
||||
^foo R|/x|()
|
||||
public final fun foo(): R|Foo| {
|
||||
^foo R|/Foo.x|.R|/Foo.invoke|()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ FILE: recursiveBug.kt
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final val result: R|kotlin/String| = R|kotlin/run|<R|kotlin/String|>(<L> = run@fun <anonymous>(): R|kotlin/String| {
|
||||
public final val result: R|kotlin/String| = R|kotlin/run|<R|Foo|, R|kotlin/String|>(<L> = run@fun R|Foo|.<anonymous>(it: R|Foo|): R|kotlin/String| {
|
||||
R|<local>/name|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/String|>|()
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
FILE fqName:<root> fileName:/implicitCastToNonNull.kt
|
||||
FUN name:test1 visibility:public modality:FINAL <> (x:kotlin.String?) returnType:kotlin.Int
|
||||
FUN name:test1 visibility:public modality:FINAL <> (x:kotlin.String?) returnType:IrErrorType
|
||||
VALUE_PARAMETER name:x index:0 type:kotlin.String?
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun test1 (x: kotlin.String?): kotlin.Int declared in <root>'
|
||||
WHEN type=kotlin.Int origin=IF
|
||||
RETURN type=kotlin.Nothing from='public final fun test1 (x: kotlin.String?): IrErrorType declared in <root>'
|
||||
WHEN type=IrErrorType origin=IF
|
||||
BRANCH
|
||||
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
|
||||
arg0: GET_VAR 'x: kotlin.String? declared in <root>.test1' type=kotlin.String? origin=null
|
||||
@@ -11,13 +11,13 @@ FILE fqName:<root> fileName:/implicitCastToNonNull.kt
|
||||
then: CONST Int type=kotlin.Int value=0
|
||||
BRANCH
|
||||
if: CONST Boolean type=kotlin.Boolean value=true
|
||||
then: ERROR_CALL 'No getter found for R|kotlin/String.length|' type=kotlin.Int
|
||||
FUN name:test2 visibility:public modality:FINAL <T> (x:T of <root>.test2) returnType:kotlin.Int
|
||||
then: ERROR_CALL 'Unresolved reference: <Inapplicable(WRONG_RECEIVER): [kotlin/String.length]>#' type=IrErrorType
|
||||
FUN name:test2 visibility:public modality:FINAL <T> (x:T of <root>.test2) returnType:IrErrorType
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[]
|
||||
VALUE_PARAMETER name:x index:0 type:T of <root>.test2
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun test2 <T> (x: T of <root>.test2): kotlin.Int declared in <root>'
|
||||
WHEN type=kotlin.Int origin=IF
|
||||
RETURN type=kotlin.Nothing from='public final fun test2 <T> (x: T of <root>.test2): IrErrorType declared in <root>'
|
||||
WHEN type=IrErrorType origin=IF
|
||||
BRANCH
|
||||
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
|
||||
arg0: GET_VAR 'x: T of <root>.test2 declared in <root>.test2' type=T of <root>.test2 origin=null
|
||||
@@ -25,7 +25,7 @@ FILE fqName:<root> fileName:/implicitCastToNonNull.kt
|
||||
then: CONST Int type=kotlin.Int value=0
|
||||
BRANCH
|
||||
if: CONST Boolean type=kotlin.Boolean value=true
|
||||
then: ERROR_CALL 'No getter found for R|kotlin/CharSequence.length|' type=kotlin.Int
|
||||
then: ERROR_CALL 'Unresolved reference: <Inapplicable(WRONG_RECEIVER): [kotlin/CharSequence.length]>#' type=IrErrorType
|
||||
FUN name:test3 visibility:public modality:FINAL <T> (x:kotlin.Any) returnType:IrErrorType [inline]
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[]
|
||||
VALUE_PARAMETER name:x index:0 type:kotlin.Any
|
||||
|
||||
Reference in New Issue
Block a user