K1: add diagnostic BUILDER_INFERENCE_STUB_RECEIVER
It's reported on receivers in extension function calls with stub type, as such calls can shadow members of finalized stub types causing change of resolve when corresponding type argument specified explicitly It works by checking extension receiver during call resolution parts run That way we can easily detect if we found an extension applicable to stub receiver and report call diagnostic for it KT-53739
This commit is contained in:
committed by
teamcity
parent
105358dcf6
commit
154e53c701
+12
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -862,6 +862,7 @@ public interface Errors {
|
||||
DiagnosticFactory3<PsiElement, KotlinType, String, String> STUB_TYPE_IN_ARGUMENT_CAUSES_AMBIGUITY = DiagnosticFactory3.create(ERROR);
|
||||
DiagnosticFactory4<PsiElement, KotlinType, String, String, BuilderLambdaLabelingInfo> STUB_TYPE_IN_RECEIVER_CAUSES_AMBIGUITY = DiagnosticFactory4.create(ERROR);
|
||||
DiagnosticFactory2<PsiElement, Name, Name> BUILDER_INFERENCE_MULTI_LAMBDA_RESTRICTION = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory2<PsiElement, Name, Name> BUILDER_INFERENCE_STUB_RECEIVER = DiagnosticFactory2.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<PsiElement, Collection<? extends ResolvedCall<?>>> NONE_APPLICABLE = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, Collection<? extends ResolvedCall<?>>> CANNOT_COMPLETE_RESOLVE = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
+1
@@ -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);
|
||||
|
||||
+16
@@ -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
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+18
-2
@@ -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,
|
||||
|
||||
+7
@@ -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) {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
""
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ fun main() {
|
||||
|
||||
buildList {
|
||||
add(Bar())
|
||||
this.get(0).test() // resolved to Any?.test
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>this.get(0)<!>.test() // resolved to Any?.test
|
||||
}
|
||||
buildList<Bar> {
|
||||
add(Bar())
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// WITH_STDLIB
|
||||
// SKIP_TXT
|
||||
fun test() {
|
||||
foo(
|
||||
flow { emit(0) }
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
fun test() {
|
||||
foo(
|
||||
flow { emit(0) }
|
||||
) <!BUILDER_INFERENCE_MULTI_LAMBDA_RESTRICTION!>{ it.collect <!TOO_MANY_ARGUMENTS!>{}<!> }<!>
|
||||
) <!BUILDER_INFERENCE_MULTI_LAMBDA_RESTRICTION!>{ <!BUILDER_INFERENCE_STUB_RECEIVER!>it<!>.collect <!TOO_MANY_ARGUMENTS!>{}<!> }<!>
|
||||
|
||||
// 0. Initial
|
||||
// W <: Any / declared upper bound
|
||||
|
||||
+30
-30
@@ -20,9 +20,9 @@ fun test() {
|
||||
val ret1 = build {
|
||||
emit(1)
|
||||
emit(null)
|
||||
get()?.test()
|
||||
get()?.test2()
|
||||
get().test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>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()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>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()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>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<!UNNECESSARY_SAFE_CALL!>?.<!>test2()
|
||||
x.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>x<!>.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>x<!><!UNNECESSARY_SAFE_CALL!>?.<!>test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>x<!>.test2()
|
||||
}
|
||||
|
||||
""
|
||||
@@ -104,7 +104,7 @@ fun test() {
|
||||
emit(null)
|
||||
val x = get()
|
||||
if (x == null) {
|
||||
<!TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER, TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
}
|
||||
|
||||
""
|
||||
@@ -144,7 +144,7 @@ fun test() {
|
||||
emit(null)
|
||||
val x = get()
|
||||
if (x === null) {
|
||||
<!TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER, TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
}
|
||||
|
||||
""
|
||||
@@ -153,16 +153,16 @@ fun test() {
|
||||
emit(1)
|
||||
emit(null)
|
||||
val x = get()
|
||||
<!TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER, TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
|
||||
""
|
||||
}
|
||||
val ret41 = build {
|
||||
emit(1)
|
||||
emit(null)
|
||||
get()?.test()
|
||||
get()?.test2()
|
||||
get().test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>.test2()
|
||||
get()?.hashCode()
|
||||
get()?.equals(1)
|
||||
val x = get()
|
||||
@@ -181,11 +181,11 @@ fun test() {
|
||||
}
|
||||
|
||||
if (x == null) {
|
||||
<!DEBUG_INFO_CONSTANT!>x<!>?.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER, DEBUG_INFO_CONSTANT!>x<!>?.test2()
|
||||
}
|
||||
|
||||
if (x == null) {
|
||||
x.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>x<!>.test2()
|
||||
}
|
||||
|
||||
if (x === null) {
|
||||
@@ -197,11 +197,11 @@ fun test() {
|
||||
}
|
||||
|
||||
if (x === null) {
|
||||
<!DEBUG_INFO_CONSTANT!>x<!>?.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER, DEBUG_INFO_CONSTANT!>x<!>?.test2()
|
||||
}
|
||||
|
||||
if (x === null) {
|
||||
x.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>x<!>.test2()
|
||||
}
|
||||
|
||||
""
|
||||
@@ -239,7 +239,7 @@ fun test() {
|
||||
emit(null)
|
||||
val x = get()
|
||||
if (x == null) {
|
||||
<!TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER, TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
}
|
||||
""
|
||||
}
|
||||
@@ -276,7 +276,7 @@ fun test() {
|
||||
emit(null)
|
||||
val x = get()
|
||||
if (x === null) {
|
||||
<!TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER, TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
}
|
||||
""
|
||||
}
|
||||
@@ -284,15 +284,15 @@ fun test() {
|
||||
emit(1)
|
||||
emit(null)
|
||||
val x = get()
|
||||
<!TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER, TYPE_MISMATCH("Any; Nothing?")!>x<!>.test()
|
||||
""
|
||||
}
|
||||
val ret51 = build {
|
||||
emit(1)
|
||||
emit(null)
|
||||
get()?.test()
|
||||
get()?.test2()
|
||||
get().test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>?.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>get()<!>.test2()
|
||||
get()?.hashCode()
|
||||
get()?.equals(1)
|
||||
val x = get()
|
||||
@@ -305,8 +305,8 @@ fun test() {
|
||||
if (x == null) {
|
||||
<!DEBUG_INFO_CONSTANT!>x<!>?.hashCode()
|
||||
<!DEBUG_INFO_CONSTANT!>x<!>?.equals(1)
|
||||
<!DEBUG_INFO_CONSTANT!>x<!>?.test2()
|
||||
x.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER, DEBUG_INFO_CONSTANT!>x<!>?.test2()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER!>x<!>.test2()
|
||||
}
|
||||
|
||||
""
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
// WITH_STDLIB
|
||||
// SKIP_TXT
|
||||
|
||||
fun <R> a(lambda: List<R>.(R) -> Unit) {}
|
||||
|
||||
fun <T> T.extension() {}
|
||||
|
||||
fun use(p: Any?) {}
|
||||
|
||||
fun test1() {
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>a<!> {
|
||||
this.get(0).extension()
|
||||
use(this.get(0)::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun test2() {
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>a<!> {
|
||||
val v = this.get(0)
|
||||
v.extension()
|
||||
use(v::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun test3() {
|
||||
operator fun <T> T.getValue(thisRef: Any?, prop: Any?): T = this
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>a<!> {
|
||||
val v by this.get(0)
|
||||
v.extension()
|
||||
use(v::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
class Box<TIn>(val t: TIn)
|
||||
|
||||
fun test4() {
|
||||
operator fun <T> T.provideDelegate(thisRef: Any?, prop: Any?): Box<T> = Box(this)
|
||||
operator fun <T> Box<T>.getValue(thisRef: Any?, prop: Any?): T = this.t
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>a<!> {
|
||||
val v by this.get(0)
|
||||
v.extension()
|
||||
use(v::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun <R> b(lambda: R.(List<R>) -> Unit) {}
|
||||
|
||||
fun test5() {
|
||||
|
||||
operator fun <T> T.invoke(): T = this
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>b<!> {
|
||||
extension()
|
||||
this().extension()
|
||||
use(::extension)
|
||||
}
|
||||
}
|
||||
|
||||
val <T> T.genericLambda: T.((T) -> Unit) -> Unit get() = {}
|
||||
|
||||
fun test6() {
|
||||
b {
|
||||
extension()
|
||||
genericLambda { }
|
||||
genericLambda { it.extension() }
|
||||
use(::extension)
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
// WITH_STDLIB
|
||||
// SKIP_TXT
|
||||
|
||||
fun <R> a(lambda: List<R>.(R) -> Unit) {}
|
||||
|
||||
fun <T> T.extension() {}
|
||||
|
||||
fun use(p: Any?) {}
|
||||
|
||||
fun test1() {
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>a<!> {
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>this.get(0)<!>.extension()
|
||||
use(<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>this.get(0)<!>::extension)
|
||||
use(<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>it<!>::extension)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun test2() {
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>a<!> {
|
||||
val v = this.get(0)
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>v<!>.extension()
|
||||
use(<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>v<!>::extension)
|
||||
use(<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>it<!>::extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun test3() {
|
||||
operator fun <T> T.getValue(thisRef: Any?, prop: Any?): T = this
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>a<!> {
|
||||
val v by <!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>this.get(0)<!>
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>v<!>.extension()
|
||||
use(<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>v<!>::extension)
|
||||
use(<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>it<!>::extension)
|
||||
}
|
||||
}
|
||||
|
||||
class Box<TIn>(val t: TIn)
|
||||
|
||||
fun test4() {
|
||||
operator fun <T> T.provideDelegate(thisRef: Any?, prop: Any?): Box<T> = Box(this)
|
||||
operator fun <T> Box<T>.getValue(thisRef: Any?, prop: Any?): T = this.t
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>a<!> {
|
||||
val v by <!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>this.get(0)<!>
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>v<!>.extension()
|
||||
use(<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>v<!>::extension)
|
||||
use(<!BUILDER_INFERENCE_STUB_RECEIVER("R; a")!>it<!>::extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun <R> b(lambda: R.(List<R>) -> Unit) {}
|
||||
|
||||
fun test5() {
|
||||
|
||||
operator fun <T> T.invoke(): T = this
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>b<!> {
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; b")!>extension()<!>
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; b")!><!BUILDER_INFERENCE_STUB_RECEIVER("R; b")!>this<!>()<!>.extension()
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; b")!>use(::extension)<!>
|
||||
}
|
||||
}
|
||||
|
||||
val <T> T.genericLambda: T.((T) -> Unit) -> Unit get() = {}
|
||||
|
||||
fun test6() {
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>b<!> {
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; b")!>extension()<!>
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; b")!>genericLambda<!> { }
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; b")!>genericLambda<!> { <!BUILDER_INFERENCE_STUB_RECEIVER("R; b")!>it<!>.extension() }
|
||||
<!BUILDER_INFERENCE_STUB_RECEIVER("R; b")!>use(::extension)<!>
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
// WITH_STDLIB
|
||||
// LANGUAGE: +NoBuilderInferenceWithoutAnnotationRestriction
|
||||
// SKIP_TXT
|
||||
|
||||
fun <R> a(lambda: List<R>.(R) -> Unit) {}
|
||||
|
||||
fun <T> T.extension() {}
|
||||
|
||||
fun use(p: Any?) {}
|
||||
|
||||
fun test1() {
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>a<!> {
|
||||
this.get(0).extension()
|
||||
use(this.get(0)::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun test2() {
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>a<!> {
|
||||
val v = this.get(0)
|
||||
v.extension()
|
||||
use(v::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun test3() {
|
||||
operator fun <T> T.getValue(thisRef: Any?, prop: Any?): T = this
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>a<!> {
|
||||
val v by this.get(0)
|
||||
v.extension()
|
||||
use(v::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
class Box<TIn>(val t: TIn)
|
||||
|
||||
fun test4() {
|
||||
operator fun <T> T.provideDelegate(thisRef: Any?, prop: Any?): Box<T> = Box(this)
|
||||
operator fun <T> Box<T>.getValue(thisRef: Any?, prop: Any?): T = this.t
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>a<!> {
|
||||
val v by this.get(0)
|
||||
v.extension()
|
||||
use(v::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun <R> b(lambda: R.(List<R>) -> Unit) {}
|
||||
|
||||
fun test5() {
|
||||
|
||||
operator fun <T> T.invoke(): T = this
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>b<!> {
|
||||
extension()
|
||||
this().extension()
|
||||
use(::extension)
|
||||
}
|
||||
}
|
||||
|
||||
val <T> T.genericLambda: T.((T) -> Unit) -> Unit get() = {}
|
||||
|
||||
fun test6() {
|
||||
b {
|
||||
extension()
|
||||
genericLambda { }
|
||||
genericLambda { it.extension() }
|
||||
use(::extension)
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
// WITH_STDLIB
|
||||
// LANGUAGE: +NoBuilderInferenceWithoutAnnotationRestriction
|
||||
// SKIP_TXT
|
||||
|
||||
fun <R> a(lambda: List<R>.(R) -> Unit) {}
|
||||
|
||||
fun <T> T.extension() {}
|
||||
|
||||
fun use(p: Any?) {}
|
||||
|
||||
fun test1() {
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>a<!> {
|
||||
this.get(0).extension()
|
||||
use(this.get(0)::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun test2() {
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>a<!> {
|
||||
val v = this.get(0)
|
||||
v.extension()
|
||||
use(v::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun test3() {
|
||||
operator fun <T> T.getValue(thisRef: Any?, prop: Any?): T = this
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>a<!> {
|
||||
val v by this.get(0)
|
||||
v.extension()
|
||||
use(v::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
class Box<TIn>(val t: TIn)
|
||||
|
||||
fun test4() {
|
||||
operator fun <T> T.provideDelegate(thisRef: Any?, prop: Any?): Box<T> = Box(this)
|
||||
operator fun <T> Box<T>.getValue(thisRef: Any?, prop: Any?): T = this.t
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>a<!> {
|
||||
val v by this.get(0)
|
||||
v.extension()
|
||||
use(v::extension)
|
||||
use(it::extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun <R> b(lambda: R.(List<R>) -> Unit) {}
|
||||
|
||||
fun test5() {
|
||||
|
||||
operator fun <T> T.invoke(): T = this
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>b<!> {
|
||||
extension()
|
||||
this().extension()
|
||||
use(::extension)
|
||||
}
|
||||
}
|
||||
|
||||
val <T> T.genericLambda: T.((T) -> Unit) -> Unit get() = {}
|
||||
|
||||
fun test6() {
|
||||
<!INFERRED_INTO_DECLARED_UPPER_BOUNDS!>b<!> {
|
||||
extension()
|
||||
genericLambda { }
|
||||
genericLambda { it.extension() }
|
||||
use(::extension)
|
||||
}
|
||||
}
|
||||
Generated
+12
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user