dynamic receiver admits nullable values
This commit is contained in:
@@ -597,8 +597,7 @@ public class CandidateResolver {
|
||||
|
||||
BindingContext bindingContext = trace.getBindingContext();
|
||||
if (!safeAccess && !receiverParameter.getType().isNullable() && receiverArgumentType.isNullable()) {
|
||||
if (!SmartCastUtils.isNotNull(receiverArgument, bindingContext, context.dataFlowInfo)) {
|
||||
|
||||
if (!SmartCastUtils.canBeSmartCast(receiverParameter, receiverArgument, bindingContext, context.dataFlowInfo)) {
|
||||
context.tracing.unsafeCall(trace, receiverArgumentType, implicitInvokeCheck);
|
||||
return UNSAFE_CALL_ERROR;
|
||||
}
|
||||
|
||||
+4
-2
@@ -22,6 +22,7 @@ import kotlin.Function1;
|
||||
import kotlin.KotlinPackage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
@@ -183,7 +184,8 @@ public class SmartCastUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isNotNull(
|
||||
public static boolean canBeSmartCast(
|
||||
@NotNull ReceiverParameterDescriptor receiverParameter,
|
||||
@NotNull ReceiverValue receiver,
|
||||
@NotNull BindingContext bindingContext,
|
||||
@NotNull DataFlowInfo dataFlowInfo
|
||||
@@ -192,7 +194,7 @@ public class SmartCastUtils {
|
||||
|
||||
List<JetType> smartCastVariants = getSmartCastVariants(receiver, bindingContext, dataFlowInfo);
|
||||
for (JetType smartCastVariant : smartCastVariants) {
|
||||
if (!smartCastVariant.isNullable()) return true;
|
||||
if (JetTypeChecker.DEFAULT.isSubtypeOf(smartCastVariant, receiverParameter.getType())) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// !MARK_DYNAMIC_CALLS
|
||||
|
||||
// MODULE[js]: m1
|
||||
// FILE: k.kt
|
||||
|
||||
fun foo() {
|
||||
dynamic {
|
||||
<!DEBUG_INFO_DYNAMIC!>foo<!>()
|
||||
<!DEBUG_INFO_DYNAMIC!>bar<!>.<!DEBUG_INFO_DYNAMIC!>baz<!>(0)
|
||||
}
|
||||
}
|
||||
|
||||
fun dynamic<T>(body: dynamic.() -> T): T {
|
||||
val topLevel = null
|
||||
return topLevel.body()
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package
|
||||
|
||||
internal fun </*0*/ T> dynamic(/*0*/ body: dynamic.() -> T): T
|
||||
internal fun foo(): kotlin.Unit
|
||||
@@ -3722,6 +3722,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("block.kt")
|
||||
public void testBlock() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dynamicTypes/block.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("dynamicCalls.kt")
|
||||
public void testDynamicCalls() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dynamicTypes/dynamicCalls.kt");
|
||||
|
||||
Reference in New Issue
Block a user