Do not try computing return type in OverloadChecker

Return type is not needed for checking overloads, but querying it may
involve resolving function bodies, which usually happens after overload
checking (see LazyTopDownAnalyzer.analyzeDeclarations) and at this point
can lead to incorrect BACKING_FIELD_REQUIRED value being computed for
some properties (see KT-27895)

 #KT-27895 Fixed
This commit is contained in:
Alexander Udalov
2018-11-06 15:57:55 +01:00
parent 829bdf6061
commit 17d740a373
6 changed files with 52 additions and 16 deletions
@@ -55,7 +55,9 @@ class OverloadChecker(val specificityComparator: TypeSpecificityComparator) {
// They can be disambiguated by providing explicit type parameters. // They can be disambiguated by providing explicit type parameters.
if (a.typeParameters.isEmpty() != b.typeParameters.isEmpty()) return true if (a.typeParameters.isEmpty() != b.typeParameters.isEmpty()) return true
if (ErrorUtils.containsErrorType(a) || ErrorUtils.containsErrorType(b)) return true if (a is FunctionDescriptor && ErrorUtils.containsErrorTypeInParameters(a) ||
b is FunctionDescriptor && ErrorUtils.containsErrorTypeInParameters(b)
) return true
if (a.varargParameterPosition() != b.varargParameterPosition()) return true if (a.varargParameterPosition() != b.varargParameterPosition()) return true
val aSignature = FlatSignature.createFromCallableDescriptor(a) val aSignature = FlatSignature.createFromCallableDescriptor(a)
@@ -0,0 +1,10 @@
@Target(AnnotationTarget.FIELD)
annotation class Anno
data class C(val x: Int) {
@Anno
val json: String = ""
get() = field
fun copy() = this.also { json }
}
@@ -0,0 +1,21 @@
@kotlin.annotation.Target
@java.lang.annotation.Retention
@java.lang.annotation.Target
@kotlin.Metadata
public annotation class Anno
@kotlin.Metadata
public final class C {
private final @Anno @org.jetbrains.annotations.NotNull field json: java.lang.String
private final field x: int
public method <init>(p0: int): void
public final method component1(): int
public synthetic static @org.jetbrains.annotations.NotNull method copy$default(p0: C, p1: int, p2: int, p3: java.lang.Object): C
public final @org.jetbrains.annotations.NotNull method copy(): C
public final @org.jetbrains.annotations.NotNull method copy(p0: int): C
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public final @org.jetbrains.annotations.NotNull method getJson(): java.lang.String
public final method getX(): int
public method hashCode(): int
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
}
@@ -215,6 +215,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
runTest("compiler/testData/codegen/bytecodeListing/annotations/JvmSynthetic.kt"); runTest("compiler/testData/codegen/bytecodeListing/annotations/JvmSynthetic.kt");
} }
@TestMetadata("kt27895.kt")
public void testKt27895() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/annotations/kt27895.kt");
}
@TestMetadata("kt9320.kt") @TestMetadata("kt9320.kt")
public void testKt9320() throws Exception { public void testKt9320() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/annotations/kt9320.kt"); runTest("compiler/testData/codegen/bytecodeListing/annotations/kt9320.kt");
@@ -142,19 +142,11 @@ public class ErrorUtils {
}; };
} }
public static boolean containsErrorType(@NotNull CallableDescriptor callableDescriptor) { /**
if (callableDescriptor instanceof FunctionDescriptor) { * @return true iff any of the types referenced in parameter types (including type parameters and extension receiver) of the function
return containsErrorType((FunctionDescriptor) callableDescriptor); * is an error type. Does not check the return type of the function.
} */
else { public static boolean containsErrorTypeInParameters(@NotNull FunctionDescriptor function) {
return containsErrorType(callableDescriptor.getReturnType());
}
}
public static boolean containsErrorType(@NotNull FunctionDescriptor function) {
if (containsErrorType(function.getReturnType())) {
return true;
}
ReceiverParameterDescriptor receiverParameter = function.getExtensionReceiverParameter(); ReceiverParameterDescriptor receiverParameter = function.getExtensionReceiverParameter();
if (receiverParameter != null && containsErrorType(receiverParameter.getType())) { if (receiverParameter != null && containsErrorType(receiverParameter.getType())) {
return true; return true;
@@ -16,7 +16,10 @@
package org.jetbrains.kotlin.idea.codeInliner package org.jetbrains.kotlin.idea.codeInliner
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.core.asExpression import org.jetbrains.kotlin.idea.core.asExpression
@@ -90,7 +93,10 @@ class CodeToInlineBuilder(
private fun getParametersForFunctionLiteral(functionLiteralExpression: KtLambdaExpression, context: BindingContext): String? { private fun getParametersForFunctionLiteral(functionLiteralExpression: KtLambdaExpression, context: BindingContext): String? {
val lambdaDescriptor = context.get(BindingContext.FUNCTION, functionLiteralExpression.functionLiteral) val lambdaDescriptor = context.get(BindingContext.FUNCTION, functionLiteralExpression.functionLiteral)
if (lambdaDescriptor == null || ErrorUtils.containsErrorType(lambdaDescriptor)) return null if (lambdaDescriptor == null ||
ErrorUtils.containsErrorTypeInParameters(lambdaDescriptor) ||
ErrorUtils.containsErrorType(lambdaDescriptor.returnType)
) return null
return lambdaDescriptor.valueParameters.joinToString { return lambdaDescriptor.valueParameters.joinToString {
it.name.render() + ": " + IdeDescriptorRenderers.SOURCE_CODE.renderType(it.type) it.name.render() + ": " + IdeDescriptorRenderers.SOURCE_CODE.renderType(it.type)
} }