diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 9a6d7da568f..313ff447e21 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -13507,6 +13507,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT public void testSubstituteTypeVariableIntolambdaParameterDescriptor() throws Exception { runTest("compiler/testData/codegen/box/inference/builderInference/substituteTypeVariableIntolambdaParameterDescriptor.kt"); } + + @TestMetadata("substitutelambdaExtensionReceiverType.kt") + public void testSubstitutelambdaExtensionReceiverType() throws Exception { + runTest("compiler/testData/codegen/box/inference/builderInference/substitutelambdaExtensionReceiverType.kt"); + } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt index 08569c1d1f5..d43f8c8a041 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt @@ -221,6 +221,7 @@ class ResolvedAtomCompleter( } else { resultSubstitutor.safeSubstitute(lambda.returnType) } + val receiverType = lambda.receiver val approximatedValueParameterTypes = lambda.parameters.map { parameterType -> if (parameterType.shouldBeSubstituted()) { @@ -238,7 +239,16 @@ class ResolvedAtomCompleter( local = true, languageVersionSettings = topLevelCallContext.languageVersionSettings ) - updateTraceForLambda(lambda, topLevelTrace, approximatedReturnType, approximatedValueParameterTypes) + + val approximatedReceiverType = if (receiverType != null) { + typeApproximator.approximateDeclarationType( + resultSubstitutor.safeSubstitute(receiverType), + local = true, + languageVersionSettings = topLevelCallContext.languageVersionSettings + ) + } else null + + updateTraceForLambda(lambda, topLevelTrace, approximatedReturnType, approximatedValueParameterTypes, approximatedReceiverType) for (lambdaResult in resultArgumentsInfo.nonErrorArguments) { val resultValueArgument = lambdaResult as? PSIKotlinCallArgument ?: continue @@ -262,7 +272,8 @@ class ResolvedAtomCompleter( lambda: ResolvedLambdaAtom, trace: BindingTrace, returnType: UnwrappedType, - valueParameters: List + valueParameters: List, + receiverType: UnwrappedType? ) { val psiCallArgument = lambda.atom.psiCallArgument @@ -285,6 +296,12 @@ class ResolvedAtomCompleter( functionDescriptor.setReturnType(returnType) + val extensionReceiverParameter = functionDescriptor.extensionReceiverParameter + + if (receiverType != null && extensionReceiverParameter is ReceiverParameterDescriptorImpl && extensionReceiverParameter.type.shouldBeSubstituted()) { + extensionReceiverParameter.setOutType(receiverType) + } + for ((i, valueParameter) in functionDescriptor.valueParameters.withIndex()) { if (valueParameter !is ValueParameterDescriptorImpl || !valueParameter.type.shouldBeSubstituted()) continue valueParameter.setOutType(valueParameters[i]) diff --git a/compiler/testData/codegen/box/inference/builderInference/substitutelambdaExtensionReceiverType.kt b/compiler/testData/codegen/box/inference/builderInference/substitutelambdaExtensionReceiverType.kt new file mode 100644 index 00000000000..6f05546a53b --- /dev/null +++ b/compiler/testData/codegen/box/inference/builderInference/substitutelambdaExtensionReceiverType.kt @@ -0,0 +1,22 @@ +// WITH_RUNTIME +// DONT_TARGET_EXACT_BACKEND: WASM + +import kotlin.experimental.ExperimentalTypeInference + +operator fun SequenceScope.plusAssign(x: SequenceScope) {} + +@OptIn(ExperimentalTypeInference::class) + +fun mySequence(@BuilderInference block: suspend SequenceScope.() -> Unit): Sequence = Sequence { iterator(block) } + +fun main() { + val y: Sequence = mySequence { + yield("result") + this += this + } +} + +fun box(): String { + main() + return "OK" +} diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 8fc5bc4412c..84d19bdf9fa 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -13507,6 +13507,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testSubstituteTypeVariableIntolambdaParameterDescriptor() throws Exception { runTest("compiler/testData/codegen/box/inference/builderInference/substituteTypeVariableIntolambdaParameterDescriptor.kt"); } + + @TestMetadata("substitutelambdaExtensionReceiverType.kt") + public void testSubstitutelambdaExtensionReceiverType() throws Exception { + runTest("compiler/testData/codegen/box/inference/builderInference/substitutelambdaExtensionReceiverType.kt"); + } } } diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 5d60c37dcac..fcca375efda 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -13507,6 +13507,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes public void testSubstituteTypeVariableIntolambdaParameterDescriptor() throws Exception { runTest("compiler/testData/codegen/box/inference/builderInference/substituteTypeVariableIntolambdaParameterDescriptor.kt"); } + + @TestMetadata("substitutelambdaExtensionReceiverType.kt") + public void testSubstitutelambdaExtensionReceiverType() throws Exception { + runTest("compiler/testData/codegen/box/inference/builderInference/substitutelambdaExtensionReceiverType.kt"); + } } } diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index ff9198733fd..d211a6110df 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -13507,6 +13507,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes public void testSubstituteTypeVariableIntolambdaParameterDescriptor() throws Exception { runTest("compiler/testData/codegen/box/inference/builderInference/substituteTypeVariableIntolambdaParameterDescriptor.kt"); } + + @TestMetadata("substitutelambdaExtensionReceiverType.kt") + public void testSubstitutelambdaExtensionReceiverType() throws Exception { + runTest("compiler/testData/codegen/box/inference/builderInference/substitutelambdaExtensionReceiverType.kt"); + } } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ReceiverParameterDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ReceiverParameterDescriptorImpl.java index df56e1e7249..a2a04279f70 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ReceiverParameterDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ReceiverParameterDescriptorImpl.java @@ -21,10 +21,12 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor; import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; +import org.jetbrains.kotlin.types.KotlinType; +import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt; public class ReceiverParameterDescriptorImpl extends AbstractReceiverParameterDescriptor { private final DeclarationDescriptor containingDeclaration; - private final ReceiverValue value; + private ReceiverValue value; public ReceiverParameterDescriptorImpl( @NotNull DeclarationDescriptor containingDeclaration, @@ -53,4 +55,9 @@ public class ReceiverParameterDescriptorImpl extends AbstractReceiverParameterDe public ReceiverParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner) { return new ReceiverParameterDescriptorImpl(newOwner, value, getAnnotations()); } + + public void setOutType(@NotNull KotlinType outType) { + assert TypeUtilsKt.shouldBeSubstituted(this.value.getType()); + this.value = value.replaceType(outType); + } } diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 762fcead901..4572d5c426a 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -11557,6 +11557,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception { runTest("compiler/testData/codegen/box/inference/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt"); } + + @TestMetadata("substitutelambdaExtensionReceiverType.kt") + public void testSubstitutelambdaExtensionReceiverType() throws Exception { + runTest("compiler/testData/codegen/box/inference/builderInference/substitutelambdaExtensionReceiverType.kt"); + } } } diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 703ba087a41..191cc4fa79b 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -11557,6 +11557,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception { runTest("compiler/testData/codegen/box/inference/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt"); } + + @TestMetadata("substitutelambdaExtensionReceiverType.kt") + public void testSubstitutelambdaExtensionReceiverType() throws Exception { + runTest("compiler/testData/codegen/box/inference/builderInference/substitutelambdaExtensionReceiverType.kt"); + } } } diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 76dbeb1e489..269a94c3140 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -11622,6 +11622,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception { runTest("compiler/testData/codegen/box/inference/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt"); } + + @TestMetadata("substitutelambdaExtensionReceiverType.kt") + public void testSubstitutelambdaExtensionReceiverType() throws Exception { + runTest("compiler/testData/codegen/box/inference/builderInference/substitutelambdaExtensionReceiverType.kt"); + } } }