Smart cast is performed now inside 'x as? Type ?: return' safe as / elvis combination #KT-10992 Fixed
This commit is contained in:
+24
@@ -1304,6 +1304,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
// left argument is considered not-null if it's not-null also in right part or if we have jump in right part
|
// left argument is considered not-null if it's not-null also in right part or if we have jump in right part
|
||||||
if (jumpInRight || !rightDataFlowInfo.getPredictableNullability(leftValue).canBeNull()) {
|
if (jumpInRight || !rightDataFlowInfo.getPredictableNullability(leftValue).canBeNull()) {
|
||||||
dataFlowInfo = dataFlowInfo.disequate(leftValue, nullValue);
|
dataFlowInfo = dataFlowInfo.disequate(leftValue, nullValue);
|
||||||
|
if (left instanceof KtBinaryExpressionWithTypeRHS) {
|
||||||
|
dataFlowInfo = establishSubtypingForTypeRHS((KtBinaryExpressionWithTypeRHS) left, dataFlowInfo, context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DataFlowValue resultValue = DataFlowValueFactory.createDataFlowValue(expression, type, context);
|
DataFlowValue resultValue = DataFlowValueFactory.createDataFlowValue(expression, type, context);
|
||||||
dataFlowInfo = dataFlowInfo.assign(resultValue, leftValue).disequate(resultValue, nullValue);
|
dataFlowInfo = dataFlowInfo.assign(resultValue, leftValue).disequate(resultValue, nullValue);
|
||||||
@@ -1331,6 +1334,27 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
context.dataFlowInfo);
|
context.dataFlowInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static DataFlowInfo establishSubtypingForTypeRHS(
|
||||||
|
@NotNull KtBinaryExpressionWithTypeRHS left,
|
||||||
|
@NotNull DataFlowInfo dataFlowInfo,
|
||||||
|
@NotNull ExpressionTypingContext context
|
||||||
|
) {
|
||||||
|
IElementType operationType = left.getOperationReference().getReferencedNameElementType();
|
||||||
|
if (operationType == AS_SAFE) {
|
||||||
|
KtExpression underSafeAs = left.getLeft();
|
||||||
|
KotlinType underSafeAsType = context.trace.getType(underSafeAs);
|
||||||
|
if (underSafeAsType != null) {
|
||||||
|
DataFlowValue underSafeAsValue = createDataFlowValue(underSafeAs, underSafeAsType, context);
|
||||||
|
KotlinType targetType = context.trace.get(BindingContext.TYPE, left.getRight());
|
||||||
|
if (targetType != null) {
|
||||||
|
return dataFlowInfo.establishSubtyping(underSafeAsValue, targetType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dataFlowInfo;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public KotlinTypeInfo checkInExpression(
|
public KotlinTypeInfo checkInExpression(
|
||||||
@NotNull KtElement callElement,
|
@NotNull KtElement callElement,
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// See also KT-10992: we should have no errors for all unsafe hashCode() calls
|
||||||
|
|
||||||
|
fun foo(arg: Any?) {
|
||||||
|
val x = arg as? Any ?: return
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>arg<!>.hashCode()
|
||||||
|
x.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(arg: Any?) {
|
||||||
|
arg as? Any ?: return
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>arg<!>.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun gav(arg: Any?) {
|
||||||
|
arg as? String ?: return
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>arg<!>.length
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun bar(/*0*/ arg: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun foo(/*0*/ arg: kotlin.Any?): kotlin.Unit
|
||||||
|
public fun gav(/*0*/ arg: kotlin.Any?): kotlin.Unit
|
||||||
@@ -16455,6 +16455,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("safeAs.kt")
|
||||||
|
public void testSafeAs() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/safeAs.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("shortIfExprNotNull.kt")
|
@TestMetadata("shortIfExprNotNull.kt")
|
||||||
public void testShortIfExprNotNull() throws Exception {
|
public void testShortIfExprNotNull() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/shortIfExprNotNull.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/shortIfExprNotNull.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user