Fix for KT-6863: Internal compiler error folding functions

#KT-6863 Fixed
This commit is contained in:
Michael Bogdanov
2015-04-09 14:21:55 +03:00
parent a24d845bd0
commit 67c2f7105b
17 changed files with 108 additions and 29 deletions
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.CodegenUtil;
import org.jetbrains.kotlin.builtins.InlineStrategy;
import org.jetbrains.kotlin.builtins.InlineUtil;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.codegen.*;
import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
@@ -508,11 +509,11 @@ public class InlineCodegen extends CallGenerator {
}
}
public static boolean isInliningClosure(JetExpression expression, ValueParameterDescriptor valueParameterDescriptora) {
public static boolean isInliningClosure(JetExpression expression, ValueParameterDescriptor valueParameterDescriptor) {
//TODO deparenthisise typed
JetExpression deparenthesize = JetPsiUtil.deparenthesize(expression);
return deparenthesize instanceof JetFunctionLiteralExpression &&
!InlineUtil.hasNoinlineAnnotation(valueParameterDescriptora);
JetExpression deparenthesized = JetPsiUtil.deparenthesize(expression);
return deparenthesized instanceof JetFunctionLiteralExpression &&
InlineUtil.isInlineLambdaParameter(valueParameterDescriptor);
}
public void rememberClosure(JetExpression expression, Type type) {
@@ -76,7 +76,7 @@ public class InlineDescriptorUtils {
ArgumentMapping mapping = resolvedCall.getArgumentMapping(argument);
if (mapping instanceof ArgumentMatch) {
ValueParameterDescriptor parameter = ((ArgumentMatch) mapping).getValueParameter();
if (!InlineUtil.hasNoinlineAnnotation(parameter)) {
if (InlineUtil.isInlineLambdaParameter(parameter)) {
return !checkNonLocalReturn || allowsNonLocalReturns(parameter);
}
}
@@ -222,9 +222,8 @@ class InlineChecker implements CallChecker {
private static boolean isInlinableParameter(@NotNull CallableDescriptor descriptor) {
JetType type = descriptor.getReturnType();
return type != null &&
KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(type) &&
!type.isMarkedNullable() &&
!InlineUtil.hasNoinlineAnnotation(descriptor);
InlineUtil.isInlineLambdaParameter(descriptor) &&
!type.isMarkedNullable();
}
private static boolean isInvokeOrInlineExtension(@NotNull CallableDescriptor descriptor) {
@@ -272,13 +271,4 @@ class InlineChecker implements CallChecker {
context.trace.report(Errors.NON_LOCAL_RETURN_NOT_ALLOWED.on(parameterUsage, parameterUsage, inlinableParameterDescriptor, descriptor));
}
}
@Nullable
public static PsiElement getDeclaration(JetExpression expression) {
do {
expression = PsiTreeUtil.getParentOfType(expression, JetDeclaration.class);
} while (expression instanceof JetMultiDeclaration || expression instanceof JetProperty);
return expression;
}
}
@@ -143,17 +143,15 @@ public class InlineAnalyzerExtension implements FunctionAnalyzerExtension.Analyz
@Nullable BindingTrace trace
) {
JetType type = parameter.getReturnType();
if (type != null && KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(type)) {
if (!InlineUtil.hasNoinlineAnnotation(parameter)) {
if (type.isMarkedNullable()) {
if (trace != null) {
trace.report(Errors.NULLABLE_INLINE_PARAMETER.on(expression, expression, functionDescriptor));
}
}
else {
return true;
if (type != null && InlineUtil.isInlineLambdaParameter(parameter)) {
if (type.isMarkedNullable()) {
if (trace != null) {
trace.report(Errors.NULLABLE_INLINE_PARAMETER.on(expression, expression, functionDescriptor));
}
}
else {
return true;
}
}
return false;
}
@@ -0,0 +1,5 @@
fun box() : String {
test {"123"}
return "OK"
}
@@ -0,0 +1,3 @@
inline fun <T> test(p: T) {
p.toString()
}
@@ -0,0 +1,5 @@
fun box() : String {
test {"123"}
return "OK"
}
@@ -0,0 +1,3 @@
inline fun test(p: Any) {
p.toString()
}
@@ -0,0 +1,11 @@
fun box() : String {
test {
<!RETURN_NOT_ALLOWED!>return@box "123"<!>
}
return "OK"
}
<!NOTHING_TO_INLINE!>inline fun <T> test(p: T)<!> {
p.toString()
}
@@ -0,0 +1,4 @@
package
internal fun box(): kotlin.String
kotlin.inline() internal fun </*0*/ T> test(/*0*/ p: T): kotlin.Unit
@@ -0,0 +1,11 @@
fun box() : String {
test {
<!RETURN_NOT_ALLOWED!>return@box "123"<!>
}
return "OK"
}
<!NOTHING_TO_INLINE!>inline fun test(p: Any)<!> {
p.toString()
}
@@ -0,0 +1,4 @@
package
internal fun box(): kotlin.String
kotlin.inline() internal fun test(/*0*/ p: kotlin.Any): kotlin.Unit
@@ -6739,6 +6739,18 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("lambdaAsGeneric.kt")
public void testLambdaAsGeneric() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaAsGeneric.kt");
doTest(fileName);
}
@TestMetadata("lambdaAsNonFunction.kt")
public void testLambdaAsNonFunction() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaAsNonFunction.kt");
doTest(fileName);
}
@TestMetadata("lambdaWithGlobalReturnsInsideOnlyLocalOne.kt")
public void testLambdaWithGlobalReturnsInsideOnlyLocalOne() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.kt");
@@ -320,6 +320,18 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/noInline"), Pattern.compile("^(.+)\\.1.kt$"), true);
}
@TestMetadata("lambdaAsGeneric.1.kt")
public void testLambdaAsGeneric() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/lambdaAsGeneric.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
@TestMetadata("lambdaAsNonFunction.1.kt")
public void testLambdaAsNonFunction() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/lambdaAsNonFunction.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
@TestMetadata("noInline.1.kt")
public void testNoInline() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/noInline.1.kt");
@@ -320,6 +320,18 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/noInline"), Pattern.compile("^(.+)\\.1.kt$"), true);
}
@TestMetadata("lambdaAsGeneric.1.kt")
public void testLambdaAsGeneric() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/lambdaAsGeneric.1.kt");
doBoxTestWithInlineCheck(fileName);
}
@TestMetadata("lambdaAsNonFunction.1.kt")
public void testLambdaAsNonFunction() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/lambdaAsNonFunction.1.kt");
doBoxTestWithInlineCheck(fileName);
}
@TestMetadata("noInline.1.kt")
public void testNoInline() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/noInline.1.kt");
@@ -29,13 +29,21 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.constants.ArrayValue;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.EnumValue;
import org.jetbrains.kotlin.types.JetType;
import java.util.List;
public class InlineUtil {
public static boolean hasNoinlineAnnotation(@NotNull CallableDescriptor valueParameterDescriptor) {
return KotlinBuiltIns.containsAnnotation(valueParameterDescriptor, KotlinBuiltIns.getNoinlineClassAnnotationFqName());
public static boolean hasNoinlineAnnotation(@NotNull CallableDescriptor valueParameterOrReceiver) {
return KotlinBuiltIns.containsAnnotation(valueParameterOrReceiver, KotlinBuiltIns.getNoinlineClassAnnotationFqName());
}
public static boolean isInlineLambdaParameter(@NotNull CallableDescriptor valueParameterOrReceiver) {
JetType type = valueParameterOrReceiver.getOriginal().getReturnType();
return !hasNoinlineAnnotation(valueParameterOrReceiver) &&
type != null &&
KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(type);
}
@NotNull
@@ -84,7 +84,7 @@ public final class CallExpressionTranslator extends AbstractCallExpressionTransl
if (descriptor instanceof ValueParameterDescriptor) {
DeclarationDescriptor containingDescriptor = descriptor.getContainingDeclaration();
return InlineUtil.getInlineType(containingDescriptor).isInline()
&& !InlineUtil.hasNoinlineAnnotation(descriptor);
&& InlineUtil.isInlineLambdaParameter(descriptor);
}
return false;