Fix for KT-6863: Internal compiler error folding functions
#KT-6863 Fixed
This commit is contained in:
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||||
import org.jetbrains.kotlin.builtins.InlineStrategy;
|
import org.jetbrains.kotlin.builtins.InlineStrategy;
|
||||||
import org.jetbrains.kotlin.builtins.InlineUtil;
|
import org.jetbrains.kotlin.builtins.InlineUtil;
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
import org.jetbrains.kotlin.codegen.*;
|
import org.jetbrains.kotlin.codegen.*;
|
||||||
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
|
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
|
//TODO deparenthisise typed
|
||||||
JetExpression deparenthesize = JetPsiUtil.deparenthesize(expression);
|
JetExpression deparenthesized = JetPsiUtil.deparenthesize(expression);
|
||||||
return deparenthesize instanceof JetFunctionLiteralExpression &&
|
return deparenthesized instanceof JetFunctionLiteralExpression &&
|
||||||
!InlineUtil.hasNoinlineAnnotation(valueParameterDescriptora);
|
InlineUtil.isInlineLambdaParameter(valueParameterDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rememberClosure(JetExpression expression, Type type) {
|
public void rememberClosure(JetExpression expression, Type type) {
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public class InlineDescriptorUtils {
|
|||||||
ArgumentMapping mapping = resolvedCall.getArgumentMapping(argument);
|
ArgumentMapping mapping = resolvedCall.getArgumentMapping(argument);
|
||||||
if (mapping instanceof ArgumentMatch) {
|
if (mapping instanceof ArgumentMatch) {
|
||||||
ValueParameterDescriptor parameter = ((ArgumentMatch) mapping).getValueParameter();
|
ValueParameterDescriptor parameter = ((ArgumentMatch) mapping).getValueParameter();
|
||||||
if (!InlineUtil.hasNoinlineAnnotation(parameter)) {
|
if (InlineUtil.isInlineLambdaParameter(parameter)) {
|
||||||
return !checkNonLocalReturn || allowsNonLocalReturns(parameter);
|
return !checkNonLocalReturn || allowsNonLocalReturns(parameter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-12
@@ -222,9 +222,8 @@ class InlineChecker implements CallChecker {
|
|||||||
private static boolean isInlinableParameter(@NotNull CallableDescriptor descriptor) {
|
private static boolean isInlinableParameter(@NotNull CallableDescriptor descriptor) {
|
||||||
JetType type = descriptor.getReturnType();
|
JetType type = descriptor.getReturnType();
|
||||||
return type != null &&
|
return type != null &&
|
||||||
KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(type) &&
|
InlineUtil.isInlineLambdaParameter(descriptor) &&
|
||||||
!type.isMarkedNullable() &&
|
!type.isMarkedNullable();
|
||||||
!InlineUtil.hasNoinlineAnnotation(descriptor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isInvokeOrInlineExtension(@NotNull CallableDescriptor descriptor) {
|
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));
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-9
@@ -143,17 +143,15 @@ public class InlineAnalyzerExtension implements FunctionAnalyzerExtension.Analyz
|
|||||||
@Nullable BindingTrace trace
|
@Nullable BindingTrace trace
|
||||||
) {
|
) {
|
||||||
JetType type = parameter.getReturnType();
|
JetType type = parameter.getReturnType();
|
||||||
if (type != null && KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(type)) {
|
if (type != null && InlineUtil.isInlineLambdaParameter(parameter)) {
|
||||||
if (!InlineUtil.hasNoinlineAnnotation(parameter)) {
|
if (type.isMarkedNullable()) {
|
||||||
if (type.isMarkedNullable()) {
|
if (trace != null) {
|
||||||
if (trace != null) {
|
trace.report(Errors.NULLABLE_INLINE_PARAMETER.on(expression, expression, functionDescriptor));
|
||||||
trace.report(Errors.NULLABLE_INLINE_PARAMETER.on(expression, expression, functionDescriptor));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
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);
|
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")
|
@TestMetadata("lambdaWithGlobalReturnsInsideOnlyLocalOne.kt")
|
||||||
public void testLambdaWithGlobalReturnsInsideOnlyLocalOne() throws Exception {
|
public void testLambdaWithGlobalReturnsInsideOnlyLocalOne() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inline/nonLocalReturns/lambdaWithGlobalReturnsInsideOnlyLocalOne.kt");
|
||||||
|
|||||||
+12
@@ -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);
|
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")
|
@TestMetadata("noInline.1.kt")
|
||||||
public void testNoInline() throws Exception {
|
public void testNoInline() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/noInline.1.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/noInline.1.kt");
|
||||||
|
|||||||
+12
@@ -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);
|
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")
|
@TestMetadata("noInline.1.kt")
|
||||||
public void testNoInline() throws Exception {
|
public void testNoInline() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/noInline.1.kt");
|
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.ArrayValue;
|
||||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||||
import org.jetbrains.kotlin.resolve.constants.EnumValue;
|
import org.jetbrains.kotlin.resolve.constants.EnumValue;
|
||||||
|
import org.jetbrains.kotlin.types.JetType;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class InlineUtil {
|
public class InlineUtil {
|
||||||
|
|
||||||
public static boolean hasNoinlineAnnotation(@NotNull CallableDescriptor valueParameterDescriptor) {
|
public static boolean hasNoinlineAnnotation(@NotNull CallableDescriptor valueParameterOrReceiver) {
|
||||||
return KotlinBuiltIns.containsAnnotation(valueParameterDescriptor, KotlinBuiltIns.getNoinlineClassAnnotationFqName());
|
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
|
@NotNull
|
||||||
|
|||||||
+1
-1
@@ -84,7 +84,7 @@ public final class CallExpressionTranslator extends AbstractCallExpressionTransl
|
|||||||
if (descriptor instanceof ValueParameterDescriptor) {
|
if (descriptor instanceof ValueParameterDescriptor) {
|
||||||
DeclarationDescriptor containingDescriptor = descriptor.getContainingDeclaration();
|
DeclarationDescriptor containingDescriptor = descriptor.getContainingDeclaration();
|
||||||
return InlineUtil.getInlineType(containingDescriptor).isInline()
|
return InlineUtil.getInlineType(containingDescriptor).isInline()
|
||||||
&& !InlineUtil.hasNoinlineAnnotation(descriptor);
|
&& InlineUtil.isInlineLambdaParameter(descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user