diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 970c5c67d5f..e85e9d33053 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -14625,6 +14625,18 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag public void testRenderingStubTypes() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/renderingStubTypes.kt"); } + + @Test + @TestMetadata("stubTypeReceiverRestriction.kt") + public void testStubTypeReceiverRestriction() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestriction.kt"); + } + + @Test + @TestMetadata("stubTypeReceiverRestrictionDisabled.kt") + public void testStubTypeReceiverRestrictionDisabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestrictionDisabled.kt"); + } } } diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 0004dacaa56..b509f0e061a 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -14625,6 +14625,18 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti public void testRenderingStubTypes() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/renderingStubTypes.kt"); } + + @Test + @TestMetadata("stubTypeReceiverRestriction.kt") + public void testStubTypeReceiverRestriction() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestriction.kt"); + } + + @Test + @TestMetadata("stubTypeReceiverRestrictionDisabled.kt") + public void testStubTypeReceiverRestrictionDisabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestrictionDisabled.kt"); + } } } diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 0a20c57bccd..22ae96e9131 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -14625,6 +14625,18 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac public void testRenderingStubTypes() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/renderingStubTypes.kt"); } + + @Test + @TestMetadata("stubTypeReceiverRestriction.kt") + public void testStubTypeReceiverRestriction() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestriction.kt"); + } + + @Test + @TestMetadata("stubTypeReceiverRestrictionDisabled.kt") + public void testStubTypeReceiverRestrictionDisabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestrictionDisabled.kt"); + } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 7664f6014ca..36e3ddf9b1c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -862,6 +862,7 @@ public interface Errors { DiagnosticFactory3 STUB_TYPE_IN_ARGUMENT_CAUSES_AMBIGUITY = DiagnosticFactory3.create(ERROR); DiagnosticFactory4 STUB_TYPE_IN_RECEIVER_CAUSES_AMBIGUITY = DiagnosticFactory4.create(ERROR); DiagnosticFactory2 BUILDER_INFERENCE_MULTI_LAMBDA_RESTRICTION = DiagnosticFactory2.create(ERROR); + DiagnosticFactory2 BUILDER_INFERENCE_STUB_RECEIVER = DiagnosticFactory2.create(ERROR); DiagnosticFactory1>> NONE_APPLICABLE = DiagnosticFactory1.create(ERROR); DiagnosticFactory1>> CANNOT_COMPLETE_RESOLVE = DiagnosticFactory1.create(ERROR); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 1c9decc2988..329347d605c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -945,6 +945,7 @@ public class DefaultErrorMessages { MAP.put(STUB_TYPE_IN_ARGUMENT_CAUSES_AMBIGUITY, "The type of an argument hasn''t been inferred yet. To disambiguate this call, explicitly cast it to `{0}` if you want the builder''s type parameter(s) `{1}` to be inferred to `{2}`.", RENDER_TYPE, STRING, STRING); MAP.put(STUB_TYPE_IN_RECEIVER_CAUSES_AMBIGUITY, "The type of a receiver hasn''t been inferred yet. To disambiguate this call, explicitly cast it to `{0}` if you want the builder''s type parameter(s) `{1}` to be inferred to `{2}`.", RENDER_TYPE, STRING, STRING, null); MAP.put(BUILDER_INFERENCE_MULTI_LAMBDA_RESTRICTION, "Unstable inference behaviour with multiple lambdas. Please either specify type argument for generic parameter `{0}` of `{1}` explicitly or add @BuilderInference to corresponding parameter declaration", TO_STRING, TO_STRING); + MAP.put(BUILDER_INFERENCE_STUB_RECEIVER, "The type of a receiver hasn''t been inferred yet. Please specify type argument for generic parameter `{0}` of `{1}` explicitly", TO_STRING, TO_STRING); MAP.put(NONE_APPLICABLE, "None of the following functions can be called with the arguments supplied: {0}", AMBIGUOUS_CALLS); MAP.put(CANNOT_COMPLETE_RESOLVE, "Cannot choose among the following candidates without completing type inference: {0}", AMBIGUOUS_CALLS); MAP.put(UNRESOLVED_REFERENCE_WRONG_RECEIVER, "Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: {0}", AMBIGUOUS_CALLS); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt index cd7edadfabf..9b57556c738 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt @@ -39,6 +39,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.StubTypeForBuilderInference import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.checker.intersectWrappedTypes import org.jetbrains.kotlin.types.error.ErrorUtils @@ -199,6 +200,21 @@ class DiagnosticReporterByTrackingStrategy( trace.report(SUPER_CANT_BE_EXTENSION_RECEIVER.on(psiExpression, psiExpression.text)) } } + + StubBuilderInferenceReceiver::class.java -> { + diagnostic as StubBuilderInferenceReceiver + + val stubType = callReceiver.receiver.receiverValue.type as? StubTypeForBuilderInference + val originalTypeParameter = stubType?.originalTypeVariable?.originalTypeParameter + + trace.report( + BUILDER_INFERENCE_STUB_RECEIVER.on( + callReceiver.psiExpression ?: call.callElement, + originalTypeParameter?.name ?: SpecialNames.NO_NAME_PROVIDED, + originalTypeParameter?.containingDeclaration?.name ?: SpecialNames.NO_NAME_PROVIDED + ) + ) + } } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt index 2d172f6b8cf..d45efcd58f6 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt @@ -661,9 +661,25 @@ internal object CheckReceivers : ResolutionPart() { candidateDescriptor.dispatchReceiverParameter, shouldCheckImplicitInvoke = true, ) + 1 -> { - if (resolvedCall.extensionReceiverArgument == null) { - resolvedCall.extensionReceiverArgument = chooseExtensionReceiverCandidate() ?: return + val checkBuilderInferenceRestriction = + !callComponents.languageVersionSettings + .supportsFeature(LanguageFeature.NoBuilderInferenceWithoutAnnotationRestriction) + if (checkBuilderInferenceRestriction) { + var extensionReceiverArgument = resolvedCall.extensionReceiverArgument + if (extensionReceiverArgument == null) { + extensionReceiverArgument = chooseExtensionReceiverCandidate() ?: return + resolvedCall.extensionReceiverArgument = extensionReceiverArgument + } + if (extensionReceiverArgument.receiver.receiverValue.type is StubTypeForBuilderInference) { + addDiagnostic( + StubBuilderInferenceReceiver( + extensionReceiverArgument, + candidateDescriptor.extensionReceiverParameter!! + ) + ) + } } checkReceiver( resolvedCall.extensionReceiverArgument, diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt index 284620868db..11878bb6242 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt @@ -73,6 +73,13 @@ class MultiLambdaBuilderInferenceRestriction( override fun report(reporter: DiagnosticReporter) = reporter.onCallArgument(argument, this) } +class StubBuilderInferenceReceiver( + val receiver: SimpleKotlinCallArgument, + val extensionReceiverParameter: ReceiverParameterDescriptor, +) : KotlinCallDiagnostic(RESOLVED) { + override fun report(reporter: DiagnosticReporter) = reporter.onCallReceiver(receiver, this) +} + class MixingNamedAndPositionArguments(override val argument: KotlinCallArgument) : InapplicableArgumentDiagnostic() class NamedArgumentNotAllowed(val argument: KotlinCallArgument, val descriptor: CallableDescriptor) : KotlinCallDiagnostic(INAPPLICABLE) { diff --git a/compiler/testData/codegen/box/inference/builderInference/memberScope.kt b/compiler/testData/codegen/box/inference/builderInference/memberScope.kt index 42d2b17b909..1c33204c932 100644 --- a/compiler/testData/codegen/box/inference/builderInference/memberScope.kt +++ b/compiler/testData/codegen/box/inference/builderInference/memberScope.kt @@ -20,9 +20,10 @@ fun box(): String { val ret = build { emit(1) emit(null) - get()?.test() - get()?.test2() - get().test2() + // Error, resolved to extension on stub receiver +// get()?.test() +// get()?.test2() +// get().test2() get()?.hashCode() get()?.equals(1) val x = get() @@ -38,9 +39,10 @@ fun box(): String { x.equals("") x.hashCode() x.toString() - x.test() - x?.test2() - x.test2() + // Error, resolved to extension on stub receiver +// x.test() +// x?.test2() +// x.test2() } if (x == null) { @@ -50,8 +52,9 @@ fun box(): String { // x.hashCode() // x.toString() // x.test() - x?.test2() - x.test2() + // Error, resolved to extension on stub receiver +// x?.test2() +// x.test2() } if (x === null) { @@ -61,8 +64,9 @@ fun box(): String { // x.hashCode() // x.toString() // x.test() - x?.test2() - x.test2() + // Error, resolved to extension on stub receiver +// x?.test2() +// x.test2() } "" diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/errorOnStubReceiver.kt b/compiler/testData/diagnostics/tests/inference/builderInference/errorOnStubReceiver.kt index 655a98ec345..38e5002a960 100644 --- a/compiler/testData/diagnostics/tests/inference/builderInference/errorOnStubReceiver.kt +++ b/compiler/testData/diagnostics/tests/inference/builderInference/errorOnStubReceiver.kt @@ -12,7 +12,7 @@ fun main() { buildList { add(Bar()) - this.get(0).test() // resolved to Any?.test + this.get(0).test() // resolved to Any?.test } buildList { add(Bar()) diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/kt53422.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/kt53422.fir.kt index 5ec0bf50632..8a84de782e4 100644 --- a/compiler/testData/diagnostics/tests/inference/builderInference/kt53422.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/builderInference/kt53422.fir.kt @@ -1,4 +1,5 @@ // WITH_STDLIB +// SKIP_TXT fun test() { foo( flow { emit(0) } diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/kt53422.kt b/compiler/testData/diagnostics/tests/inference/builderInference/kt53422.kt index e2c112f8304..24f6b4e7dcf 100644 --- a/compiler/testData/diagnostics/tests/inference/builderInference/kt53422.kt +++ b/compiler/testData/diagnostics/tests/inference/builderInference/kt53422.kt @@ -3,7 +3,7 @@ fun test() { foo( flow { emit(0) } - ) { it.collect {} } + ) { it.collect {} } // 0. Initial // W <: Any / declared upper bound diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/memberScope.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/memberScope.kt index 821f280ae66..c13790a7560 100644 --- a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/memberScope.kt +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/memberScope.kt @@ -20,9 +20,9 @@ fun test() { val ret1 = build { emit(1) emit(null) - get()?.test() - get()?.test2() - get().test2() + get()?.test() + get()?.test2() + get().test2() get()?.hashCode() get()?.equals(1) // there is `String?.equals` extension @@ -31,9 +31,9 @@ fun test() { val ret2 = build { emit(1) emit(null) - get()?.test() - get()?.test2() - get().test2() + get()?.test() + get()?.test2() + get().test2() get()?.hashCode() get()?.equals(1) val x = get() @@ -44,9 +44,9 @@ fun test() { val ret3 = build { emit(1) emit(null) - get()?.test() - get()?.test2() - get().test2() + get()?.test() + get()?.test2() + get().test2() get()?.hashCode() get()?.equals(1) val x = get() @@ -62,9 +62,9 @@ fun test() { x.equals("") x.hashCode() x.toString() - x.test() - x?.test2() - x.test2() + x.test() + x?.test2() + x.test2() } "" @@ -104,7 +104,7 @@ fun test() { emit(null) val x = get() if (x == null) { - x.test() + x.test() } "" @@ -144,7 +144,7 @@ fun test() { emit(null) val x = get() if (x === null) { - x.test() + x.test() } "" @@ -153,16 +153,16 @@ fun test() { emit(1) emit(null) val x = get() - x.test() + x.test() "" } val ret41 = build { emit(1) emit(null) - get()?.test() - get()?.test2() - get().test2() + get()?.test() + get()?.test2() + get().test2() get()?.hashCode() get()?.equals(1) val x = get() @@ -181,11 +181,11 @@ fun test() { } if (x == null) { - x?.test2() + x?.test2() } if (x == null) { - x.test2() + x.test2() } if (x === null) { @@ -197,11 +197,11 @@ fun test() { } if (x === null) { - x?.test2() + x?.test2() } if (x === null) { - x.test2() + x.test2() } "" @@ -239,7 +239,7 @@ fun test() { emit(null) val x = get() if (x == null) { - x.test() + x.test() } "" } @@ -276,7 +276,7 @@ fun test() { emit(null) val x = get() if (x === null) { - x.test() + x.test() } "" } @@ -284,15 +284,15 @@ fun test() { emit(1) emit(null) val x = get() - x.test() + x.test() "" } val ret51 = build { emit(1) emit(null) - get()?.test() - get()?.test2() - get().test2() + get()?.test() + get()?.test2() + get().test2() get()?.hashCode() get()?.equals(1) val x = get() @@ -305,8 +305,8 @@ fun test() { if (x == null) { x?.hashCode() x?.equals(1) - x?.test2() - x.test2() + x?.test2() + x.test2() } "" diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestriction.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestriction.fir.kt new file mode 100644 index 00000000000..0294509b82d --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestriction.fir.kt @@ -0,0 +1,72 @@ +// WITH_STDLIB +// SKIP_TXT + +fun a(lambda: List.(R) -> Unit) {} + +fun T.extension() {} + +fun use(p: Any?) {} + +fun test1() { + a { + this.get(0).extension() + use(this.get(0)::extension) + use(it::extension) + } +} + + +fun test2() { + a { + val v = this.get(0) + v.extension() + use(v::extension) + use(it::extension) + } +} + +fun test3() { + operator fun T.getValue(thisRef: Any?, prop: Any?): T = this + a { + val v by this.get(0) + v.extension() + use(v::extension) + use(it::extension) + } +} + +class Box(val t: TIn) + +fun test4() { + operator fun T.provideDelegate(thisRef: Any?, prop: Any?): Box = Box(this) + operator fun Box.getValue(thisRef: Any?, prop: Any?): T = this.t + a { + val v by this.get(0) + v.extension() + use(v::extension) + use(it::extension) + } +} + +fun b(lambda: R.(List) -> Unit) {} + +fun test5() { + + operator fun T.invoke(): T = this + b { + extension() + this().extension() + use(::extension) + } +} + +val T.genericLambda: T.((T) -> Unit) -> Unit get() = {} + +fun test6() { + b { + extension() + genericLambda { } + genericLambda { it.extension() } + use(::extension) + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestriction.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestriction.kt new file mode 100644 index 00000000000..9444a280bde --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestriction.kt @@ -0,0 +1,72 @@ +// WITH_STDLIB +// SKIP_TXT + +fun a(lambda: List.(R) -> Unit) {} + +fun T.extension() {} + +fun use(p: Any?) {} + +fun test1() { + a { + this.get(0).extension() + use(this.get(0)::extension) + use(it::extension) + } +} + + +fun test2() { + a { + val v = this.get(0) + v.extension() + use(v::extension) + use(it::extension) + } +} + +fun test3() { + operator fun T.getValue(thisRef: Any?, prop: Any?): T = this + a { + val v by this.get(0) + v.extension() + use(v::extension) + use(it::extension) + } +} + +class Box(val t: TIn) + +fun test4() { + operator fun T.provideDelegate(thisRef: Any?, prop: Any?): Box = Box(this) + operator fun Box.getValue(thisRef: Any?, prop: Any?): T = this.t + a { + val v by this.get(0) + v.extension() + use(v::extension) + use(it::extension) + } +} + +fun b(lambda: R.(List) -> Unit) {} + +fun test5() { + + operator fun T.invoke(): T = this + b { + extension() + this().extension() + use(::extension) + } +} + +val T.genericLambda: T.((T) -> Unit) -> Unit get() = {} + +fun test6() { + b { + extension() + genericLambda { } + genericLambda { it.extension() } + use(::extension) + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestrictionDisabled.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestrictionDisabled.fir.kt new file mode 100644 index 00000000000..bd649fb47b2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestrictionDisabled.fir.kt @@ -0,0 +1,73 @@ +// WITH_STDLIB +// LANGUAGE: +NoBuilderInferenceWithoutAnnotationRestriction +// SKIP_TXT + +fun a(lambda: List.(R) -> Unit) {} + +fun T.extension() {} + +fun use(p: Any?) {} + +fun test1() { + a { + this.get(0).extension() + use(this.get(0)::extension) + use(it::extension) + } +} + + +fun test2() { + a { + val v = this.get(0) + v.extension() + use(v::extension) + use(it::extension) + } +} + +fun test3() { + operator fun T.getValue(thisRef: Any?, prop: Any?): T = this + a { + val v by this.get(0) + v.extension() + use(v::extension) + use(it::extension) + } +} + +class Box(val t: TIn) + +fun test4() { + operator fun T.provideDelegate(thisRef: Any?, prop: Any?): Box = Box(this) + operator fun Box.getValue(thisRef: Any?, prop: Any?): T = this.t + a { + val v by this.get(0) + v.extension() + use(v::extension) + use(it::extension) + } +} + +fun b(lambda: R.(List) -> Unit) {} + +fun test5() { + + operator fun T.invoke(): T = this + b { + extension() + this().extension() + use(::extension) + } +} + +val T.genericLambda: T.((T) -> Unit) -> Unit get() = {} + +fun test6() { + b { + extension() + genericLambda { } + genericLambda { it.extension() } + use(::extension) + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestrictionDisabled.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestrictionDisabled.kt new file mode 100644 index 00000000000..38f5c9cbc8d --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestrictionDisabled.kt @@ -0,0 +1,73 @@ +// WITH_STDLIB +// LANGUAGE: +NoBuilderInferenceWithoutAnnotationRestriction +// SKIP_TXT + +fun a(lambda: List.(R) -> Unit) {} + +fun T.extension() {} + +fun use(p: Any?) {} + +fun test1() { + a { + this.get(0).extension() + use(this.get(0)::extension) + use(it::extension) + } +} + + +fun test2() { + a { + val v = this.get(0) + v.extension() + use(v::extension) + use(it::extension) + } +} + +fun test3() { + operator fun T.getValue(thisRef: Any?, prop: Any?): T = this + a { + val v by this.get(0) + v.extension() + use(v::extension) + use(it::extension) + } +} + +class Box(val t: TIn) + +fun test4() { + operator fun T.provideDelegate(thisRef: Any?, prop: Any?): Box = Box(this) + operator fun Box.getValue(thisRef: Any?, prop: Any?): T = this.t + a { + val v by this.get(0) + v.extension() + use(v::extension) + use(it::extension) + } +} + +fun b(lambda: R.(List) -> Unit) {} + +fun test5() { + + operator fun T.invoke(): T = this + b { + extension() + this().extension() + use(::extension) + } +} + +val T.genericLambda: T.((T) -> Unit) -> Unit get() = {} + +fun test6() { + b { + extension() + genericLambda { } + genericLambda { it.extension() } + use(::extension) + } +} \ No newline at end of file diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 77441d80500..2b47bf1aff4 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -14631,6 +14631,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { public void testRenderingStubTypes() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/renderingStubTypes.kt"); } + + @Test + @TestMetadata("stubTypeReceiverRestriction.kt") + public void testStubTypeReceiverRestriction() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestriction.kt"); + } + + @Test + @TestMetadata("stubTypeReceiverRestrictionDisabled.kt") + public void testStubTypeReceiverRestrictionDisabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestrictionDisabled.kt"); + } } }