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:
Svetlana Isakova
2014-11-13 15:54:02 +03:00
parent 36fd8a1a08
commit 5d0f004292
5 changed files with 91 additions and 6 deletions
@@ -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");