Fix for 'if' special construct type
If one branch has Nothing type (contains 'return', etc.), return result type of corresponding resolved call (it may depend on smart casts) #KT-6242 Fixed
This commit is contained in:
+7
-6
@@ -133,21 +133,22 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
boolean jumpInThen = thenType != null && KotlinBuiltIns.getInstance().isNothing(thenType);
|
||||
boolean jumpInElse = elseType != null && KotlinBuiltIns.getInstance().isNothing(elseType);
|
||||
|
||||
JetTypeInfo result;
|
||||
DataFlowInfo resultDataFlowInfo;
|
||||
if (thenType == null && elseType == null) {
|
||||
result = JetTypeInfo.create(null, thenDataFlowInfo.or(elseDataFlowInfo));
|
||||
resultDataFlowInfo = thenDataFlowInfo.or(elseDataFlowInfo);
|
||||
}
|
||||
else if (thenType == null || (jumpInThen && !jumpInElse)) {
|
||||
result = elseTypeInfo;
|
||||
resultDataFlowInfo = elseDataFlowInfo;
|
||||
}
|
||||
else if (elseType == null || (jumpInElse && !jumpInThen)) {
|
||||
result = thenTypeInfo;
|
||||
resultDataFlowInfo = thenDataFlowInfo;
|
||||
}
|
||||
else {
|
||||
result = JetTypeInfo.create(resolvedCall.getResultingDescriptor().getReturnType(), thenDataFlowInfo.or(elseDataFlowInfo));
|
||||
resultDataFlowInfo = thenDataFlowInfo.or(elseDataFlowInfo);
|
||||
}
|
||||
|
||||
return DataFlowUtils.checkImplicitCast(result.getType(), ifExpression, contextWithExpectedType, isStatement, result.getDataFlowInfo());
|
||||
JetType resultType = resolvedCall.getResultingDescriptor().getReturnType();
|
||||
return DataFlowUtils.checkImplicitCast(resultType, ifExpression, contextWithExpectedType, isStatement, resultDataFlowInfo);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
inline fun<T> foo(block: () -> T):T = block()
|
||||
|
||||
fun baz() {
|
||||
val x: String = foo {
|
||||
val task: String? = null
|
||||
if (task == null) {
|
||||
return
|
||||
} else <!DEBUG_INFO_SMARTCAST!>task<!>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
DescriptorResolver@0 {
|
||||
<name not found> = NullValue@1
|
||||
}
|
||||
|
||||
LazyAnnotationDescriptor@2 {
|
||||
resolutionResults = OverloadResolutionResultsImpl@3
|
||||
type = JetTypeImpl@4['inline']
|
||||
valueArguments(ValueParameterDescriptorImpl@5['strategy']) = null
|
||||
}
|
||||
|
||||
LazyJavaPackageFragmentProvider@6 {
|
||||
packageFragments('<root>': FqName@7) = LazyJavaPackageFragment@8['<root>']
|
||||
packageFragments('String': FqName@9) = null
|
||||
packageFragments('T': FqName@10) = null
|
||||
packageFragments('inline': FqName@11) = null
|
||||
packageFragments('java': FqName@12) = LazyJavaPackageFragment@13['java']
|
||||
packageFragments('java.lang': FqName@14) = LazyJavaPackageFragment@15['lang']
|
||||
packageFragments('java.lang.String': FqName@16) = null
|
||||
packageFragments('java.lang.T': FqName@17) = null
|
||||
packageFragments('java.lang.inline': FqName@18) = null
|
||||
packageFragments('kotlin': FqName@19) = null
|
||||
packageFragments('kotlin.String': FqName@20) = null
|
||||
packageFragments('kotlin.T': FqName@21) = null
|
||||
packageFragments('kotlin.inline': FqName@22) = null
|
||||
packageFragments('kotlin.io': FqName@23) = null
|
||||
packageFragments('kotlin.jvm': FqName@24) = null
|
||||
}
|
||||
|
||||
LazyJavaPackageFragment@8['<root>'] {
|
||||
classes('String': Name@25) = null // through LazyPackageFragmentScopeForJavaPackage@26
|
||||
classes('block': Name@27) = null // through LazyPackageFragmentScopeForJavaPackage@26
|
||||
classes('equals': Name@28) = null // through LazyPackageFragmentScopeForJavaPackage@26
|
||||
classes('foo': Name@29) = null // through LazyPackageFragmentScopeForJavaPackage@26
|
||||
classes('inline': Name@30) = null // through LazyPackageFragmentScopeForJavaPackage@26
|
||||
classes('invoke': Name@31) = null // through LazyPackageFragmentScopeForJavaPackage@26
|
||||
deserializedPackageScope = Empty@32 // through LazyPackageFragmentScopeForJavaPackage@26
|
||||
functions('block': Name@27) = EmptyList@33[empty] // through LazyPackageFragmentScopeForJavaPackage@26
|
||||
functions('equals': Name@28) = EmptyList@33[empty] // through LazyPackageFragmentScopeForJavaPackage@26
|
||||
functions('foo': Name@29) = EmptyList@33[empty] // through LazyPackageFragmentScopeForJavaPackage@26
|
||||
functions('invoke': Name@31) = EmptyList@33[empty] // through LazyPackageFragmentScopeForJavaPackage@26
|
||||
memberIndex = computeMemberIndex$1@34 // through LazyPackageFragmentScopeForJavaPackage@26
|
||||
}
|
||||
|
||||
LazyJavaPackageFragment@13['java'] {
|
||||
classes('lang': Name@35) = null // through LazyPackageFragmentScopeForJavaPackage@36
|
||||
deserializedPackageScope = Empty@32 // through LazyPackageFragmentScopeForJavaPackage@36
|
||||
functions('lang': Name@37) = EmptyList@33[empty] // through LazyPackageFragmentScopeForJavaPackage@36
|
||||
memberIndex = computeMemberIndex$1@38 // through LazyPackageFragmentScopeForJavaPackage@36
|
||||
}
|
||||
|
||||
LazyJavaPackageFragment@15['lang'] {
|
||||
classes('block': Name@27) = null // through LazyPackageFragmentScopeForJavaPackage@39
|
||||
classes('equals': Name@28) = null // through LazyPackageFragmentScopeForJavaPackage@39
|
||||
classes('foo': Name@29) = null // through LazyPackageFragmentScopeForJavaPackage@39
|
||||
classes('invoke': Name@31) = null // through LazyPackageFragmentScopeForJavaPackage@39
|
||||
deserializedPackageScope = Empty@32 // through LazyPackageFragmentScopeForJavaPackage@39
|
||||
functions('block': Name@27) = EmptyList@33[empty] // through LazyPackageFragmentScopeForJavaPackage@39
|
||||
functions('equals': Name@28) = EmptyList@33[empty] // through LazyPackageFragmentScopeForJavaPackage@39
|
||||
functions('foo': Name@29) = EmptyList@33[empty] // through LazyPackageFragmentScopeForJavaPackage@39
|
||||
functions('invoke': Name@31) = EmptyList@33[empty] // through LazyPackageFragmentScopeForJavaPackage@39
|
||||
memberIndex = computeMemberIndex$1@40 // through LazyPackageFragmentScopeForJavaPackage@39
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package
|
||||
|
||||
internal fun baz(): kotlin.Unit
|
||||
kotlin.inline() internal fun </*0*/ T> foo(/*0*/ block: () -> T): T
|
||||
@@ -9546,6 +9546,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt6242.kt")
|
||||
public void testKt6242() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/inference/kt6242.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("smartCastOnReceiver.kt")
|
||||
public void testSmartCastOnReceiver() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/inference/smartCastOnReceiver.kt");
|
||||
|
||||
Reference in New Issue
Block a user