diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.kt index a84277c27ea..1933848c217 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.kt @@ -304,23 +304,31 @@ class CallExpressionResolver( private fun KtQualifiedExpression.elementChain(context: ExpressionTypingContext) = qualifiedExpressionResolver.resolveQualifierInExpressionAndUnroll(this, context) { nameExpression -> - val resolutionResult = resolveSimpleName(context, nameExpression) + val temporaryTraceAndCache = + TemporaryTraceAndCache.create(context, "trace to resolve as local variable or property", nameExpression) + val resolutionResult = resolveSimpleName(context, nameExpression, temporaryTraceAndCache) if (resolutionResult.isSingleResult && resolutionResult.resultingDescriptor is FakeCallableDescriptorForObject) { false } else when (resolutionResult.resultCode) { NAME_NOT_FOUND, CANDIDATES_WITH_WRONG_RECEIVER -> false - else -> !context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference) || resolutionResult.isSuccess + else -> { + val newInferenceEnabled = context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference) + val success = !newInferenceEnabled || resolutionResult.isSuccess + if (newInferenceEnabled && success) { + temporaryTraceAndCache.commit() + } + success + } } } private fun resolveSimpleName( - context: ExpressionTypingContext, expression: KtSimpleNameExpression + context: ExpressionTypingContext, expression: KtSimpleNameExpression, traceAndCache: TemporaryTraceAndCache ): OverloadResolutionResults { - val temporaryForVariable = TemporaryTraceAndCache.create(context, "trace to resolve as local variable or property", expression) val call = CallMaker.makePropertyCall(null, null, expression) val contextForVariable = BasicCallResolutionContext.create( - context.replaceTraceAndCache(temporaryForVariable), call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS + context.replaceTraceAndCache(traceAndCache), call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS ) return callResolver.resolveSimpleProperty(contextForVariable) } diff --git a/compiler/testData/ir/irText/types/castsInsideCoroutineInference.fir.txt b/compiler/testData/ir/irText/types/castsInsideCoroutineInference.fir.txt index 812f8130137..38dfe588528 100644 --- a/compiler/testData/ir/irText/types/castsInsideCoroutineInference.fir.txt +++ b/compiler/testData/ir/irText/types/castsInsideCoroutineInference.fir.txt @@ -37,6 +37,41 @@ FILE fqName: fileName:/castsInsideCoroutineInference.kt if: CONST Boolean type=kotlin.Boolean value=true then: TYPE_OP type=kotlin.Any origin=IMPLICIT_CAST typeOperand=kotlin.Any GET_VAR 'val tmp_0: kotlin.Any? [val] declared in .asFairChannel..' type=kotlin.Any? origin=null + FUN name:asChannel visibility:private modality:FINAL <> ($receiver:.CoroutineScope, flow:.Flow<*>) returnType:.ReceiveChannel + $receiver: VALUE_PARAMETER name: type:.CoroutineScope + VALUE_PARAMETER name:flow index:0 type:.Flow<*> + BLOCK_BODY + RETURN type=kotlin.Nothing from='private final fun asChannel (flow: .Flow<*>): .ReceiveChannel declared in ' + CALL 'public final fun produce (block: kotlin.Function1<.ProducerScope.produce>, kotlin.Unit>): .ReceiveChannel.produce> declared in ' type=.ReceiveChannel origin=null + : kotlin.Any + $receiver: GET_VAR ': .CoroutineScope declared in .asChannel' type=.CoroutineScope origin=null + block: FUN_EXPR type=kotlin.Function1<.ProducerScope, kotlin.Unit> origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> ($receiver:.ProducerScope) returnType:kotlin.Unit + $receiver: VALUE_PARAMETER name: type:.ProducerScope + BLOCK_BODY + CALL 'public abstract fun collect (collector: .FlowCollector): kotlin.Unit [suspend] declared in .Flow' type=kotlin.Unit origin=null + $this: GET_VAR 'flow: .Flow<*> declared in .asChannel' type=.Flow<*> origin=null + collector: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (value:kotlin.Any?) returnType:kotlin.Unit + VALUE_PARAMETER name:value index:0 type:kotlin.Any? + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (value: kotlin.Any?): kotlin.Unit declared in .asChannel.' + CALL 'public abstract fun send (e: kotlin.Any): kotlin.Unit [suspend] declared in .SendChannel' type=kotlin.Unit origin=null + $this: CALL 'public abstract fun (): .SendChannel declared in .ProducerScope' type=.SendChannel origin=null + $this: GET_VAR ': .ProducerScope declared in special.' type=.ProducerScope origin=null + e: BLOCK type=kotlin.Any origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Any? [val] + GET_VAR 'value: kotlin.Any? declared in .asChannel..' type=kotlin.Any? origin=null + WHEN type=kotlin.Any origin=ELVIS + 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 'val tmp_1: kotlin.Any? [val] declared in .asChannel..' type=kotlin.Any? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' type=kotlin.Any origin=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: TYPE_OP type=kotlin.Any origin=IMPLICIT_CAST typeOperand=kotlin.Any + GET_VAR 'val tmp_1: kotlin.Any? [val] declared in .asChannel..' type=kotlin.Any? origin=null FUN name:collect visibility:public modality:FINAL ($receiver:.Flow.collect>, action:kotlin.Function1.collect, kotlin.Unit>) returnType:kotlin.Unit [inline,suspend] TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] $receiver: VALUE_PARAMETER name: type:.Flow.collect> @@ -162,9 +197,17 @@ FILE fqName: fileName:/castsInsideCoroutineInference.kt overridden: public open fun toString (): kotlin.String declared in kotlin.Any $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:send visibility:public modality:ABSTRACT <> ($this:.SendChannel.SendChannel>, e:E of .ProducerScope) returnType:kotlin.Unit [suspend,fake_override] + overridden: + public abstract fun send (e: E of .SendChannel): kotlin.Unit [suspend] declared in .SendChannel + $this: VALUE_PARAMETER name: type:.SendChannel.SendChannel> + VALUE_PARAMETER name:e index:0 type:E of .ProducerScope CLASS INTERFACE name:SendChannel modality:ABSTRACT visibility:public superTypes:[kotlin.Any] $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.SendChannel.SendChannel> TYPE_PARAMETER name:E index:0 variance:in superTypes:[kotlin.Any?] + FUN name:send visibility:public modality:ABSTRACT <> ($this:.SendChannel.SendChannel>, e:E of .SendChannel) returnType:kotlin.Unit [suspend] + $this: VALUE_PARAMETER name: type:.SendChannel.SendChannel> + VALUE_PARAMETER name:e index:0 type:E of .SendChannel FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/testData/ir/irText/types/castsInsideCoroutineInference.kt b/compiler/testData/ir/irText/types/castsInsideCoroutineInference.kt index 3f42b3acdb2..7a2bf4beb8e 100644 --- a/compiler/testData/ir/irText/types/castsInsideCoroutineInference.kt +++ b/compiler/testData/ir/irText/types/castsInsideCoroutineInference.kt @@ -9,6 +9,12 @@ private fun CoroutineScope.asFairChannel(flow: Flow<*>): ReceiveChannel = p } } +private fun CoroutineScope.asChannel(flow: Flow<*>): ReceiveChannel = produce { + flow.collect { value -> + return@collect channel.send(value ?: Any()) + } +} + suspend inline fun Flow.collect(crossinline action: suspend (value: T) -> Unit) {} open class ChannelCoroutine { @@ -35,4 +41,6 @@ interface ProducerScope : CoroutineScope, SendChannel { val channel: SendChannel } -interface SendChannel \ No newline at end of file +interface SendChannel { + suspend fun send(e: E) +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/types/castsInsideCoroutineInference.txt b/compiler/testData/ir/irText/types/castsInsideCoroutineInference.txt index 4c136265bec..aa3a60422ab 100644 --- a/compiler/testData/ir/irText/types/castsInsideCoroutineInference.txt +++ b/compiler/testData/ir/irText/types/castsInsideCoroutineInference.txt @@ -37,6 +37,41 @@ FILE fqName: fileName:/castsInsideCoroutineInference.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: GET_VAR 'val tmp_0: kotlin.Any? [val] declared in .asFairChannel..' type=kotlin.Any? origin=null + FUN name:asChannel visibility:private modality:FINAL <> ($receiver:.CoroutineScope, flow:.Flow<*>) returnType:.ReceiveChannel + $receiver: VALUE_PARAMETER name: type:.CoroutineScope + VALUE_PARAMETER name:flow index:0 type:.Flow<*> + BLOCK_BODY + RETURN type=kotlin.Nothing from='private final fun asChannel (flow: .Flow<*>): .ReceiveChannel declared in ' + CALL 'public final fun produce (block: @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<.ProducerScope.produce>, kotlin.Unit>): .ReceiveChannel.produce> declared in ' type=.ReceiveChannel origin=null + : kotlin.Any + $receiver: GET_VAR ': .CoroutineScope declared in .asChannel' type=.CoroutineScope origin=null + block: FUN_EXPR type=@[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<.ProducerScope, kotlin.Unit> origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> ($receiver:.ProducerScope) returnType:kotlin.Unit [suspend] + $receiver: VALUE_PARAMETER name: type:.ProducerScope + BLOCK_BODY + CALL 'public final fun collect (action: kotlin.coroutines.SuspendFunction1<@[ParameterName(name = 'value')] T of .collect, kotlin.Unit>): kotlin.Unit [inline,suspend] declared in ' type=kotlin.Unit origin=null + : kotlin.Any? + $receiver: GET_VAR 'flow: .Flow<*> declared in .asChannel' type=.Flow<*> origin=null + action: FUN_EXPR type=kotlin.coroutines.SuspendFunction1<@[ParameterName(name = 'value')] kotlin.Any?, kotlin.Unit> origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (value:kotlin.Any?) returnType:kotlin.Unit [suspend] + VALUE_PARAMETER name:value index:0 type:kotlin.Any? + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (value: kotlin.Any?): kotlin.Unit [suspend] declared in .asChannel.' + CALL 'public abstract fun send (e: E of .SendChannel): kotlin.Unit [suspend] declared in .SendChannel' type=kotlin.Unit origin=null + $this: CALL 'public abstract fun (): .SendChannel.ProducerScope> declared in .ProducerScope' type=.SendChannel origin=GET_PROPERTY + $this: GET_VAR ': .ProducerScope declared in .asChannel.' type=.ProducerScope origin=null + e: BLOCK type=kotlin.Any origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Any? [val] + GET_VAR 'value: kotlin.Any? declared in .asChannel..' type=kotlin.Any? origin=null + WHEN type=kotlin.Any origin=null + 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 'val tmp_1: kotlin.Any? [val] declared in .asChannel..' type=kotlin.Any? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' type=kotlin.Any origin=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_1: kotlin.Any? [val] declared in .asChannel..' type=kotlin.Any? origin=null FUN name:collect visibility:public modality:FINAL ($receiver:.Flow.collect>, action:kotlin.coroutines.SuspendFunction1<@[ParameterName(name = 'value')] T of .collect, kotlin.Unit>) returnType:kotlin.Unit [inline,suspend] TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] $receiver: VALUE_PARAMETER name: type:.Flow.collect> @@ -152,6 +187,11 @@ FILE fqName: fileName:/castsInsideCoroutineInference.kt FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:ABSTRACT <> ($this:.ProducerScope.ProducerScope>) returnType:.SendChannel.ProducerScope> correspondingProperty: PROPERTY name:channel visibility:public modality:ABSTRACT [val] $this: VALUE_PARAMETER name: type:.ProducerScope.ProducerScope> + FUN FAKE_OVERRIDE name:send visibility:public modality:ABSTRACT <> ($this:.SendChannel.ProducerScope>, e:E of .ProducerScope) returnType:kotlin.Unit [suspend,fake_override] + overridden: + public abstract fun send (e: E of .SendChannel): kotlin.Unit [suspend] declared in .SendChannel + $this: VALUE_PARAMETER name: type:.SendChannel.ProducerScope> + VALUE_PARAMETER name:e index:0 type:E of .ProducerScope FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in .CoroutineScope @@ -171,6 +211,9 @@ FILE fqName: fileName:/castsInsideCoroutineInference.kt CLASS INTERFACE name:SendChannel modality:ABSTRACT visibility:public superTypes:[kotlin.Any] $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.SendChannel.SendChannel> TYPE_PARAMETER name:E index:0 variance:in superTypes:[kotlin.Any?] + FUN name:send visibility:public modality:ABSTRACT <> ($this:.SendChannel.SendChannel>, e:E of .SendChannel) returnType:kotlin.Unit [suspend] + $this: VALUE_PARAMETER name: type:.SendChannel.SendChannel> + VALUE_PARAMETER name:e index:0 type:E of .SendChannel FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any