Don't create DONT_CARE type for CR and lambdas within builder inference calls
It leads to leak such type to the back-end. Calls within a builder call should be updated without marking CR and lambdas with DONT_CARE type. ^KT-43845 Fixed ^KT-43956 Fixed ^KT-42622 Fixed
This commit is contained in:
+3
-1
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.resolve.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext;
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.CoroutineInferenceSession;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue;
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.KotlinResolutionCallbacksImpl;
|
||||
@@ -423,7 +424,8 @@ public class ExpressionTypingServices {
|
||||
@NotNull KtExpression statementExpression,
|
||||
@NotNull ExpressionTypingContext context
|
||||
) {
|
||||
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference)) return null;
|
||||
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference) || context.inferenceSession instanceof CoroutineInferenceSession)
|
||||
return null;
|
||||
KtFunctionLiteral functionLiteral = PsiUtilsKt.getNonStrictParentOfType(statementExpression, KtFunctionLiteral.class);
|
||||
if (functionLiteral != null) {
|
||||
KotlinResolutionCallbacksImpl.LambdaInfo info =
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
import kotlin.experimental.ExperimentalTypeInference
|
||||
|
||||
fun <K> FlowCollector<K>.bar(): K = null as K
|
||||
fun <K> FlowCollector<K>.foo(): K = null as K
|
||||
|
||||
fun bar2(): Int = 1
|
||||
fun foo2(): Float = 1f
|
||||
|
||||
fun <T> materialize() = null as T
|
||||
|
||||
interface FlowCollector<in T> {}
|
||||
|
||||
@Suppress("EXPERIMENTAL_API_USAGE_ERROR")
|
||||
fun <L> flow(@BuilderInference block: suspend FlowCollector<L>.() -> Unit) = Flow(block)
|
||||
|
||||
class Flow<out R>(private val block: suspend FlowCollector<R>.() -> Unit)
|
||||
|
||||
fun poll1(flag: Boolean): Flow<String> {
|
||||
return flow {
|
||||
val inv = if (flag) { ::bar2 } else { ::foo2 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll11(flag: Boolean): Flow<String> {
|
||||
return flow {
|
||||
val inv = if (flag) { ::bar2 } else { ::foo2 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll41(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::bar2 } finally { ::foo2 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll51(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::bar2 } catch (e: Exception) { ::foo2 } finally { ::foo2 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
poll1(true)
|
||||
poll11(true)
|
||||
poll41()
|
||||
poll51()
|
||||
return "OK"
|
||||
}
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
// WITH_RUNTIME
|
||||
// SKIP_TXT
|
||||
// !DIAGNOSTICS: -CAST_NEVER_SUCCEEDS -UNCHECKED_CAST -UNUSED_PARAMETER -UNUSED_VARIABLE -EXPERIMENTAL_API_USAGE_ERROR -UNUSED_EXPRESSION
|
||||
|
||||
import kotlin.experimental.ExperimentalTypeInference
|
||||
|
||||
fun <K> FlowCollector<K>.bar(): K = null as K
|
||||
fun <K> FlowCollector<K>.foo(): K = null as K
|
||||
|
||||
fun <K> K.bar3(): K = null as K
|
||||
fun <K> K.foo3(): K = null as K
|
||||
|
||||
fun bar2(): Int = 1
|
||||
fun foo2(): Float = 1f
|
||||
|
||||
val bar4: Int
|
||||
get() = 1
|
||||
|
||||
var foo4: Float
|
||||
get() = 1f
|
||||
set(value) {}
|
||||
|
||||
val <K> FlowCollector<K>.bar5: K get() = null as K
|
||||
val <K> FlowCollector<K>.foo5: K get() = null as K
|
||||
|
||||
class Foo6
|
||||
|
||||
class Foo7<T>
|
||||
fun foo7() = null as Foo7<Int>
|
||||
|
||||
interface FlowCollector<in T> {}
|
||||
|
||||
fun <L> flow(@BuilderInference block: suspend FlowCollector<L>.() -> Unit) = Flow(block)
|
||||
|
||||
class Flow<out R>(private val block: suspend FlowCollector<R>.() -> Unit)
|
||||
|
||||
fun poll1(flag: Boolean): Flow<String> {
|
||||
return flow {
|
||||
val inv = if (flag) { ::bar2 } else { ::foo2 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll11(flag: Boolean): Flow<String> {
|
||||
return flow {
|
||||
val inv = if (flag) { ::bar2 } else { ::foo2 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll12(flag: Boolean): Flow<String> {
|
||||
return flow {
|
||||
val inv = if (flag) { ::bar3 } else { ::foo3 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll13(flag: Boolean): Flow<String> {
|
||||
return flow {
|
||||
val inv = if (flag) { ::bar2 } else { ::foo3 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll14(flag: Boolean): Flow<String> {
|
||||
return flow {
|
||||
val inv = if (flag) { ::bar4 } else { ::foo4 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll15(flag: Boolean): Flow<String> {
|
||||
return flow {
|
||||
val inv = if (flag) { ::bar5 } else { ::foo5 }
|
||||
<!INAPPLICABLE_CANDIDATE!>inv<!>()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll16(flag: Boolean): Flow<String> {
|
||||
return flow {
|
||||
val inv = if (flag) { ::Foo6 } else { ::Foo6 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll17(flag: Boolean): Flow<String> {
|
||||
return flow {
|
||||
val inv = if (flag) { foo7() } else { ::Foo7 }
|
||||
inv
|
||||
}
|
||||
}
|
||||
|
||||
fun poll4(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::bar } finally { ::foo }
|
||||
<!INAPPLICABLE_CANDIDATE!>inv<!>()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll41(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::bar2 } finally { ::foo2 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll42(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::bar3 } finally { ::foo3 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll43(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::bar4 } finally { ::foo4 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll44(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::bar5 } finally { ::foo5 }
|
||||
<!INAPPLICABLE_CANDIDATE!>inv<!>()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll45(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::Foo6 } finally { ::Foo6 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll46(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { foo7() } finally { ::Foo7 }
|
||||
inv
|
||||
}
|
||||
}
|
||||
|
||||
fun poll5(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::bar } catch (e: Exception) { ::foo } finally { ::foo }
|
||||
<!INAPPLICABLE_CANDIDATE!>inv<!>()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll51(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::bar2 } catch (e: Exception) { ::foo2 } finally { ::foo2 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll52(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::bar3 } catch (e: Exception) { ::foo3 } finally { ::foo3 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll53(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::bar4 } catch (e: Exception) { ::foo4 } finally { ::foo4 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll54(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::bar5 } catch (e: Exception) { ::foo5 } finally { ::foo5 }
|
||||
<!INAPPLICABLE_CANDIDATE!>inv<!>()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll55(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::Foo6 } catch (e: Exception) { ::Foo6 } finally { ::Foo6 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll56(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::Foo7 } catch (e: Exception) { foo7() } finally { foo7() }
|
||||
inv
|
||||
}
|
||||
}
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
// WITH_RUNTIME
|
||||
// SKIP_TXT
|
||||
// !DIAGNOSTICS: -CAST_NEVER_SUCCEEDS -UNCHECKED_CAST -UNUSED_PARAMETER -UNUSED_VARIABLE -EXPERIMENTAL_API_USAGE_ERROR -UNUSED_EXPRESSION
|
||||
|
||||
import kotlin.experimental.ExperimentalTypeInference
|
||||
|
||||
fun <K> FlowCollector<K>.bar(): K = null as K
|
||||
fun <K> FlowCollector<K>.foo(): K = null as K
|
||||
|
||||
fun <K> K.bar3(): K = null as K
|
||||
fun <K> K.foo3(): K = null as K
|
||||
|
||||
fun bar2(): Int = 1
|
||||
fun foo2(): Float = 1f
|
||||
|
||||
val bar4: Int
|
||||
get() = 1
|
||||
|
||||
var foo4: Float
|
||||
get() = 1f
|
||||
set(value) {}
|
||||
|
||||
val <K> FlowCollector<K>.bar5: K get() = null as K
|
||||
val <K> FlowCollector<K>.foo5: K get() = null as K
|
||||
|
||||
class Foo6
|
||||
|
||||
class Foo7<T>
|
||||
fun foo7() = null as Foo7<Int>
|
||||
|
||||
interface FlowCollector<in T> {}
|
||||
|
||||
fun <L> flow(@BuilderInference block: suspend FlowCollector<L>.() -> Unit) = Flow(block)
|
||||
|
||||
class Flow<out R>(private val block: suspend FlowCollector<R>.() -> Unit)
|
||||
|
||||
fun poll1(flag: Boolean): Flow<String> {
|
||||
return flow {
|
||||
val inv = if (flag) { ::bar2 } else { ::foo2 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll11(flag: Boolean): Flow<String> {
|
||||
return flow {
|
||||
val inv = if (flag) { ::bar2 } else { ::foo2 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll12(flag: Boolean): Flow<String> {
|
||||
return flow {
|
||||
val inv = if (flag) { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::bar3<!> } else { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::foo3<!> }
|
||||
<!DEBUG_INFO_MISSING_UNRESOLVED!>inv()<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun poll13(flag: Boolean): Flow<String> {
|
||||
return flow {
|
||||
val inv = if (flag) { ::bar2 } else { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::foo3<!> }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll14(flag: Boolean): Flow<String> {
|
||||
return flow {
|
||||
val inv = if (flag) { ::bar4 } else { ::foo4 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll15(flag: Boolean): Flow<String> {
|
||||
return flow {
|
||||
val inv = if (flag) { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::bar5<!> } else { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::foo5<!> }
|
||||
<!DEBUG_INFO_MISSING_UNRESOLVED!>inv()<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun poll16(flag: Boolean): Flow<String> {
|
||||
return flow {
|
||||
val inv = if (flag) { ::Foo6 } else { ::Foo6 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll17(flag: Boolean): Flow<String> {
|
||||
return flow {
|
||||
val inv = if (flag) { <!IMPLICIT_CAST_TO_ANY!>foo7()<!> } else { <!IMPLICIT_CAST_TO_ANY!>::Foo7<!> }
|
||||
inv
|
||||
}
|
||||
}
|
||||
|
||||
fun poll4(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::bar<!> } finally { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::foo<!> }
|
||||
<!DEBUG_INFO_MISSING_UNRESOLVED!>inv()<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun poll41(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::bar2 } finally { ::foo2 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll42(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::bar3<!> } finally { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::foo3<!> }
|
||||
<!DEBUG_INFO_MISSING_UNRESOLVED!>inv()<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun poll43(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::bar4 } finally { ::foo4 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll44(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::bar5<!> } finally { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::foo5<!> }
|
||||
<!DEBUG_INFO_MISSING_UNRESOLVED!>inv()<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun poll45(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::Foo6 } finally { ::Foo6 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll46(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { foo7() } finally { ::<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>Foo7<!> }
|
||||
inv
|
||||
}
|
||||
}
|
||||
|
||||
fun poll5(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::bar<!> } catch (e: Exception) { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::foo<!> } finally { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::foo<!> }
|
||||
<!DEBUG_INFO_MISSING_UNRESOLVED!>inv()<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun poll51(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::bar2 } catch (e: Exception) { ::foo2 } finally { ::foo2 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll52(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::bar3<!> } catch (e: Exception) { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::foo3<!> } finally { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::foo3<!> }
|
||||
<!DEBUG_INFO_MISSING_UNRESOLVED!>inv()<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun poll53(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::bar4 } catch (e: Exception) { ::foo4 } finally { ::foo4 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll54(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::bar5<!> } catch (e: Exception) { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::foo5<!> } finally { <!TYPE_INFERENCE_POSTPONED_VARIABLE_IN_RECEIVER_TYPE!>::foo5<!> }
|
||||
<!DEBUG_INFO_MISSING_UNRESOLVED!>inv()<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun poll55(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::Foo6 } catch (e: Exception) { ::Foo6 } finally { ::Foo6 }
|
||||
inv()
|
||||
}
|
||||
}
|
||||
|
||||
fun poll56(): Flow<String> {
|
||||
return flow {
|
||||
val inv = try { ::Foo7 } catch (e: Exception) { foo7() } finally { foo7() }
|
||||
inv
|
||||
}
|
||||
}
|
||||
+5
@@ -13501,6 +13501,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/lackOfNullCheckOnNullableInsideBuild.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("specialCallsWithCallableReferencesDontCareTypeInBlockExpression.kt")
|
||||
public void testSpecialCallsWithCallableReferencesDontCareTypeInBlockExpression() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/specialCallsWithCallableReferencesDontCareTypeInBlockExpression.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("specialCallsWithCallableReferencesErrorType.kt")
|
||||
public void testSpecialCallsWithCallableReferencesErrorType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/specialCallsWithCallableReferencesErrorType.kt");
|
||||
|
||||
Reference in New Issue
Block a user