diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyResolver.java index 0ae7acac342..128fabb3730 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DelegatedPropertyResolver.java @@ -36,7 +36,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.TypeVariableKt; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; -import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfoFactory; import org.jetbrains.kotlin.resolve.scopes.LexicalScope; import org.jetbrains.kotlin.resolve.scopes.ScopeUtils; import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver; @@ -110,19 +109,22 @@ public class DelegatedPropertyResolver { delegateFunctionsScope = initializerScope = propertyHeaderScope; } - KotlinType delegateType = resolveDelegateExpression(delegateExpression, - property, - variableDescriptor, - initializerScope, - trace, - outerDataFlowInfo); + KotlinType delegateType = resolveDelegateExpression( + delegateExpression, property, variableDescriptor, initializerScope, trace, outerDataFlowInfo + ); - resolveDelegatedPropertyGetMethod(variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope); + resolveDelegatedPropertyGetMethod( + variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, outerDataFlowInfo + ); if (property.isVar()) { - resolveDelegatedPropertySetMethod(variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope); + resolveDelegatedPropertySetMethod( + variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, outerDataFlowInfo + ); } - resolveDelegatedPropertyPDMethod(variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope); + resolveDelegatedPropertyPDMethod( + variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, outerDataFlowInfo + ); } @Nullable @@ -131,9 +133,12 @@ public class DelegatedPropertyResolver { @NotNull KtExpression delegateExpression, @NotNull KotlinType delegateType, @NotNull BindingTrace trace, - @NotNull LexicalScope delegateFunctionsScope + @NotNull LexicalScope delegateFunctionsScope, + @NotNull DataFlowInfo dataFlowInfo ) { - resolveDelegatedPropertyConventionMethod(variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, true); + resolveDelegatedPropertyConventionMethod( + variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, dataFlowInfo, true + ); ResolvedCall resolvedCall = trace.getBindingContext().get(DELEGATED_PROPERTY_RESOLVED_CALL, variableDescriptor.getGetter()); return resolvedCall != null ? resolvedCall.getResultingDescriptor().getReturnType() : null; @@ -144,10 +149,12 @@ public class DelegatedPropertyResolver { @NotNull KtExpression delegateExpression, @NotNull KotlinType delegateType, @NotNull BindingTrace trace, - @NotNull LexicalScope delegateFunctionsScope + @NotNull LexicalScope delegateFunctionsScope, + @NotNull DataFlowInfo dataFlowInfo ) { KotlinType returnType = getDelegatedPropertyGetMethodReturnType( - variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope); + variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, dataFlowInfo + ); KotlinType propertyType = variableDescriptor.getType(); /* Do not check return type of get() method of delegate for properties with DeferredType because property type is taken from it */ @@ -164,9 +171,12 @@ public class DelegatedPropertyResolver { @NotNull KtExpression delegateExpression, @NotNull KotlinType delegateType, @NotNull BindingTrace trace, - @NotNull LexicalScope delegateFunctionsScope + @NotNull LexicalScope delegateFunctionsScope, + @NotNull DataFlowInfo dataFlowInfo ) { - resolveDelegatedPropertyConventionMethod(variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, false); + resolveDelegatedPropertyConventionMethod( + variableDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, dataFlowInfo, false + ); } @NotNull @@ -179,12 +189,13 @@ public class DelegatedPropertyResolver { @NotNull KtExpression delegateExpression, @NotNull KotlinType delegateType, @NotNull BindingTrace trace, - @NotNull LexicalScope delegateFunctionsScope + @NotNull LexicalScope delegateFunctionsScope, + @NotNull DataFlowInfo dataFlowInfo ) { TemporaryBindingTrace traceToResolvePDMethod = TemporaryBindingTrace.create(trace, "Trace to resolve propertyDelegated method in delegated property"); ExpressionTypingContext context = ExpressionTypingContext.newContext( - traceToResolvePDMethod, delegateFunctionsScope, - DataFlowInfoFactory.EMPTY, TypeUtils.NO_EXPECTED_TYPE); + traceToResolvePDMethod, delegateFunctionsScope, dataFlowInfo, TypeUtils.NO_EXPECTED_TYPE + ); KtPsiFactory psiFactory = KtPsiFactory(delegateExpression); List arguments = Collections.singletonList(createExpressionForProperty(psiFactory)); @@ -218,6 +229,7 @@ public class DelegatedPropertyResolver { @NotNull KotlinType delegateType, @NotNull BindingTrace trace, @NotNull LexicalScope delegateFunctionsScope, + @NotNull DataFlowInfo dataFlowInfo, boolean isGet ) { VariableAccessorDescriptor accessor = isGet ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter(); @@ -226,7 +238,8 @@ public class DelegatedPropertyResolver { if (trace.getBindingContext().get(DELEGATED_PROPERTY_CALL, accessor) != null) return; OverloadResolutionResults functionResults = getDelegatedPropertyConventionMethod( - propertyDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, isGet, true); + propertyDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, dataFlowInfo, isGet, true + ); Call call = trace.getBindingContext().get(DELEGATED_PROPERTY_CALL, accessor); assert call != null : "'getDelegatedPropertyConventionMethod' didn't record a call"; @@ -276,6 +289,7 @@ public class DelegatedPropertyResolver { @NotNull KotlinType delegateType, @NotNull BindingTrace trace, @NotNull LexicalScope delegateFunctionsScope, + @NotNull DataFlowInfo dataFlowInfo, boolean isGet, boolean isComplete ) { @@ -285,9 +299,7 @@ public class DelegatedPropertyResolver { KotlinType expectedType = isComplete && isGet && !(propertyDescriptor.getType() instanceof DeferredType) ? propertyDescriptor.getType() : TypeUtils.NO_EXPECTED_TYPE; - ExpressionTypingContext context = ExpressionTypingContext.newContext( - trace, delegateFunctionsScope, - DataFlowInfoFactory.EMPTY, expectedType); + ExpressionTypingContext context = ExpressionTypingContext.newContext(trace, delegateFunctionsScope, dataFlowInfo, expectedType); boolean hasThis = propertyDescriptor.getExtensionReceiverParameter() != null || propertyDescriptor.getDispatchReceiverParameter() != null; @@ -349,7 +361,8 @@ public class DelegatedPropertyResolver { TemporaryBindingTrace traceToResolveDelegatedProperty = TemporaryBindingTrace.create(trace, "Trace to resolve delegated property"); KtExpression calleeExpression = CallUtilKt.getCalleeExpressionIfAny(delegateExpression); ConstraintSystemCompleter completer = createConstraintSystemCompleter( - property, variableDescriptor, delegateExpression, scopeForDelegate, trace); + property, variableDescriptor, delegateExpression, scopeForDelegate, trace, dataFlowInfo + ); if (calleeExpression != null) { traceToResolveDelegatedProperty.record(CONSTRAINT_SYSTEM_COMPLETER, calleeExpression, completer); } @@ -370,7 +383,8 @@ public class DelegatedPropertyResolver { @NotNull final VariableDescriptorWithAccessors variableDescriptor, @NotNull final KtExpression delegateExpression, @NotNull LexicalScope scopeForDelegate, - @NotNull final BindingTrace trace + @NotNull final BindingTrace trace, + @NotNull final DataFlowInfo dataFlowInfo ) { final LexicalScope delegateFunctionsScope = ScopeUtils.makeScopeForDelegateConventionFunctions(scopeForDelegate, variableDescriptor); final KotlinType expectedType = property.getTypeReference() != null ? variableDescriptor.getType() : NO_EXPECTED_TYPE; @@ -391,7 +405,7 @@ public class DelegatedPropertyResolver { OverloadResolutionResults getMethodResults = getDelegatedPropertyConventionMethod( variableDescriptor, delegateExpression, returnType, traceToResolveConventionMethods, delegateFunctionsScope, - true, false + dataFlowInfo, true, false ); if (conventionMethodFound(getMethodResults)) { @@ -415,7 +429,7 @@ public class DelegatedPropertyResolver { OverloadResolutionResults setMethodResults = getDelegatedPropertyConventionMethod( variableDescriptor, delegateExpression, returnType, traceToResolveConventionMethods, delegateFunctionsScope, - false, false + dataFlowInfo, false, false ); if (conventionMethodFound(setMethodResults)) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeResolver.kt index 2112ebc599f..cdf1ee75761 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/VariableTypeResolver.kt @@ -141,7 +141,9 @@ class VariableTypeResolver( delegateExpression, property, propertyDescriptor, scopeForInitializer, trace, dataFlowInfo) val delegateFunctionsScope = ScopeUtils.makeScopeForDelegateConventionFunctions(scopeForInitializer, propertyDescriptor) - val getterReturnType = delegatedPropertyResolver.getDelegatedPropertyGetMethodReturnType(propertyDescriptor, delegateExpression, type, trace, delegateFunctionsScope) + val getterReturnType = delegatedPropertyResolver.getDelegatedPropertyGetMethodReturnType( + propertyDescriptor, delegateExpression, type, trace, delegateFunctionsScope, dataFlowInfo + ) if (getterReturnType != null) { return getterReturnType } diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/localWithSmartCast.kt b/compiler/testData/diagnostics/tests/delegatedProperty/localWithSmartCast.kt new file mode 100644 index 00000000000..05fe6a8f92e --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/localWithSmartCast.kt @@ -0,0 +1,15 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE + +interface A { + operator fun getValue(x: Any?, y: Any?): Any? +} + +interface B : A { + override fun getValue(x: Any?, y: Any?): Int +} + +fun test(a: A) { + if (a is B) { + val x: Int by a + } +} diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/localWithSmartCast.txt b/compiler/testData/diagnostics/tests/delegatedProperty/localWithSmartCast.txt new file mode 100644 index 00000000000..19e88adc668 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/localWithSmartCast.txt @@ -0,0 +1,17 @@ +package + +public fun test(/*0*/ a: A): kotlin.Unit + +public interface A { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract operator fun getValue(/*0*/ x: kotlin.Any?, /*1*/ y: kotlin.Any?): kotlin.Any? + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface B : A { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ fun getValue(/*0*/ x: kotlin.Any?, /*1*/ y: kotlin.Any?): kotlin.Int + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 7047a0f0999..99f10cd6516 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -5160,6 +5160,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("localWithSmartCast.kt") + public void testLocalWithSmartCast() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/localWithSmartCast.kt"); + doTest(fileName); + } + @TestMetadata("missedGetter.kt") public void testMissedGetter() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/delegatedProperty/missedGetter.kt");